From 919b01cce1afcf1489c4e2e55923da35e82348f6 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Wed, 22 Sep 2010 01:21:58 -1000 Subject: [PATCH] Import OpenSSL-1.0.0a. --- crypto/openssl/CHANGES | 873 +++ crypto/openssl/FAQ | 29 +- crypto/openssl/NEWS | 46 + crypto/openssl/README | 4 +- crypto/openssl/README.DELETED | 50 +- crypto/openssl/apps/apps.c | 874 ++- crypto/openssl/apps/apps.h | 91 +- crypto/openssl/apps/asn1pars.c | 16 +- crypto/openssl/apps/ca.c | 148 +- crypto/openssl/apps/ciphers.c | 37 +- crypto/openssl/apps/cms.c | 113 +- crypto/openssl/apps/crl2p7.c | 20 +- crypto/openssl/apps/dgst.c | 346 +- crypto/openssl/apps/dh.c | 6 + crypto/openssl/apps/dhparam.c | 6 + crypto/openssl/apps/dsa.c | 59 +- crypto/openssl/apps/ec.c | 6 + crypto/openssl/apps/ecparam.c | 6 + crypto/openssl/apps/enc.c | 49 +- crypto/openssl/apps/engine.c | 57 +- crypto/openssl/apps/errstr.c | 10 +- crypto/openssl/apps/gendh.c | 6 + crypto/openssl/apps/genpkey.c | 440 ++ crypto/openssl/apps/genrsa.c | 20 +- crypto/openssl/apps/ocsp.c | 149 +- crypto/openssl/apps/openssl.c | 214 +- crypto/openssl/apps/openssl.cnf | 57 +- crypto/openssl/apps/pkcs12.c | 102 +- crypto/openssl/apps/pkcs7.c | 7 +- crypto/openssl/apps/pkcs8.c | 79 +- crypto/openssl/apps/pkey.c | 284 + .../x509/x509cset.c => apps/pkeyparam.c} | 205 +- crypto/openssl/apps/pkeyutl.c | 570 ++ crypto/openssl/apps/prime.c | 46 +- crypto/openssl/apps/progs.h | 19 + crypto/openssl/apps/req.c | 497 +- crypto/openssl/apps/rsa.c | 63 +- crypto/openssl/apps/rsautl.c | 6 + crypto/openssl/apps/s_apps.h | 4 +- crypto/openssl/apps/s_cb.c | 195 +- crypto/openssl/apps/s_client.c | 307 +- crypto/openssl/apps/s_server.c | 319 +- crypto/openssl/apps/s_socket.c | 8 +- crypto/openssl/apps/s_time.c | 109 +- crypto/openssl/apps/smime.c | 412 +- crypto/openssl/apps/speed.c | 331 +- crypto/openssl/apps/ts.c | 1147 ++++ crypto/openssl/apps/verify.c | 165 +- crypto/openssl/apps/x509.c | 92 +- crypto/openssl/crypto/aes/aes.h | 28 +- crypto/openssl/crypto/aes/aes_cbc.c | 82 +- crypto/openssl/crypto/aes/aes_cfb.c | 159 +- crypto/openssl/crypto/aes/aes_core.c | 209 +- crypto/openssl/crypto/aes/aes_ctr.c | 90 +- crypto/openssl/crypto/aes/aes_ige.c | 12 +- crypto/openssl/crypto/aes/aes_ofb.c | 94 +- crypto/openssl/crypto/asn1/a_bitstr.c | 23 + crypto/openssl/crypto/asn1/a_dup.c | 2 +- crypto/openssl/crypto/asn1/a_gentm.c | 23 +- crypto/openssl/crypto/asn1/a_hdr.c | 119 - crypto/openssl/crypto/asn1/a_int.c | 10 +- crypto/openssl/crypto/asn1/a_meth.c | 84 - crypto/openssl/crypto/asn1/a_object.c | 30 +- crypto/openssl/crypto/asn1/a_octet.c | 4 +- crypto/openssl/crypto/asn1/a_set.c | 45 +- crypto/openssl/crypto/asn1/a_sign.c | 78 +- crypto/openssl/crypto/asn1/a_strnid.c | 18 +- crypto/openssl/crypto/asn1/a_time.c | 40 +- crypto/openssl/crypto/asn1/a_type.c | 53 +- crypto/openssl/crypto/asn1/a_utctm.c | 21 +- crypto/openssl/crypto/asn1/a_verify.c | 31 +- crypto/openssl/crypto/asn1/ameth_lib.c | 450 ++ crypto/openssl/crypto/asn1/asn1.h | 254 +- crypto/openssl/crypto/asn1/asn1_err.c | 21 +- crypto/openssl/crypto/asn1/asn1_gen.c | 35 +- crypto/openssl/crypto/asn1/asn1_lib.c | 36 +- .../{x509v3/pcy_node.c => asn1/asn1_locl.h} | 164 +- crypto/openssl/crypto/asn1/asn1_mac.h | 7 + crypto/openssl/crypto/asn1/asn1_par.c | 15 +- crypto/openssl/crypto/asn1/asn1t.h | 71 +- crypto/openssl/crypto/asn1/asn_mime.c | 88 +- crypto/openssl/crypto/asn1/asn_pack.c | 8 +- crypto/openssl/crypto/asn1/bio_asn1.c | 495 ++ crypto/openssl/crypto/asn1/bio_ndef.c | 246 + crypto/openssl/crypto/asn1/charmap.h | 2 +- crypto/openssl/crypto/asn1/d2i_pr.c | 97 +- crypto/openssl/crypto/asn1/d2i_pu.c | 10 +- crypto/openssl/crypto/asn1/i2d_pr.c | 39 +- crypto/openssl/crypto/asn1/nsseq.c | 5 +- crypto/openssl/crypto/asn1/p5_pbe.c | 105 +- crypto/openssl/crypto/asn1/p5_pbev2.c | 54 +- crypto/openssl/crypto/asn1/p8_pkey.c | 75 +- crypto/openssl/crypto/asn1/t_pkey.c | 729 +-- crypto/openssl/crypto/asn1/t_req.c | 28 +- crypto/openssl/crypto/asn1/t_spki.c | 31 +- crypto/openssl/crypto/asn1/t_x509.c | 47 +- crypto/openssl/crypto/asn1/tasn_dec.c | 24 +- crypto/openssl/crypto/asn1/tasn_enc.c | 11 +- crypto/openssl/crypto/asn1/tasn_fre.c | 8 +- crypto/openssl/crypto/asn1/tasn_new.c | 23 +- crypto/openssl/crypto/asn1/tasn_prn.c | 627 ++ crypto/openssl/crypto/asn1/tasn_typ.c | 11 + crypto/openssl/crypto/asn1/x_crl.c | 391 +- crypto/openssl/crypto/asn1/x_long.c | 10 +- crypto/openssl/crypto/asn1/x_name.c | 298 +- .../crypto/{pem/pem_x509.c => asn1/x_nx509.c} | 25 +- crypto/openssl/crypto/asn1/x_pubkey.c | 304 +- crypto/openssl/crypto/asn1/x_req.c | 3 +- crypto/openssl/crypto/asn1/x_x509.c | 20 +- crypto/openssl/crypto/bf/bf_skey.c | 7 +- crypto/openssl/crypto/bf/blowfish.h | 6 +- crypto/openssl/crypto/bio/b_print.c | 4 +- crypto/openssl/crypto/bio/b_sock.c | 242 +- crypto/openssl/crypto/bio/bio.h | 55 +- crypto/openssl/crypto/bio/bio_cb.c | 24 +- crypto/openssl/crypto/bio/bio_err.c | 2 +- crypto/openssl/crypto/bio/bio_lcl.h | 10 +- crypto/openssl/crypto/bio/bio_lib.c | 4 +- crypto/openssl/crypto/bio/bss_acpt.c | 8 +- crypto/openssl/crypto/bio/bss_dgram.c | 171 +- crypto/openssl/crypto/bio/bss_fd.c | 27 +- crypto/openssl/crypto/bio/bss_file.c | 54 +- crypto/openssl/crypto/bio/bss_log.c | 55 +- crypto/openssl/crypto/bio/bss_mem.c | 18 +- crypto/openssl/crypto/bio/bss_sock.c | 13 - crypto/openssl/crypto/bn/bn.h | 181 +- crypto/openssl/crypto/bn/bn_asm.c | 322 +- crypto/openssl/crypto/bn/bn_blind.c | 17 +- crypto/openssl/crypto/bn/bn_ctx.c | 6 +- crypto/openssl/crypto/bn/bn_div.c | 10 +- crypto/openssl/crypto/bn/bn_gf2m.c | 142 +- crypto/openssl/crypto/bn/bn_lcl.h | 3 +- crypto/openssl/crypto/bn/bn_lib.c | 29 +- crypto/openssl/crypto/bn/bn_mont.c | 269 +- crypto/openssl/crypto/bn/bn_opt.c | 87 - crypto/openssl/crypto/bn/bn_print.c | 21 + crypto/openssl/crypto/bn/bn_x931p.c | 272 - crypto/openssl/crypto/buffer/buf_err.c | 2 +- crypto/openssl/crypto/buffer/buffer.c | 89 +- crypto/openssl/crypto/buffer/buffer.h | 9 +- crypto/openssl/crypto/camellia/camellia.c | 2024 ++----- crypto/openssl/crypto/camellia/camellia.h | 36 +- crypto/openssl/crypto/camellia/cmll_cbc.c | 227 +- crypto/openssl/crypto/camellia/cmll_cfb.c | 110 +- crypto/openssl/crypto/camellia/cmll_ctr.c | 85 +- crypto/openssl/crypto/camellia/cmll_locl.h | 102 +- crypto/openssl/crypto/camellia/cmll_misc.c | 60 +- crypto/openssl/crypto/camellia/cmll_ofb.c | 28 +- crypto/openssl/crypto/cast/c_skey.c | 7 +- crypto/openssl/crypto/cast/cast.h | 6 +- crypto/openssl/crypto/cms/cms.h | 10 +- crypto/openssl/crypto/cms/cms_asn1.c | 46 +- crypto/openssl/crypto/cms/cms_env.c | 85 +- crypto/openssl/crypto/cms/cms_err.c | 4 +- crypto/openssl/crypto/cms/cms_ess.c | 2 +- crypto/openssl/crypto/cms/cms_io.c | 79 +- crypto/openssl/crypto/cms/cms_lcl.h | 1 + crypto/openssl/crypto/cms/cms_lib.c | 26 +- crypto/openssl/crypto/cms/cms_sd.c | 126 +- crypto/openssl/crypto/cms/cms_smime.c | 22 +- crypto/openssl/crypto/comp/c_zlib.c | 1 + crypto/openssl/crypto/comp/comp_err.c | 2 +- crypto/openssl/crypto/conf/README | 47 +- crypto/openssl/crypto/conf/conf.h | 35 +- crypto/openssl/crypto/conf/conf_api.c | 134 +- crypto/openssl/crypto/conf/conf_def.c | 11 +- crypto/openssl/crypto/conf/conf_err.c | 4 +- crypto/openssl/crypto/conf/conf_lib.c | 30 +- crypto/openssl/crypto/conf/conf_mall.c | 2 - crypto/openssl/crypto/conf/conf_mod.c | 8 +- crypto/openssl/crypto/cpt_err.c | 2 +- crypto/openssl/crypto/cryptlib.c | 506 +- crypto/openssl/crypto/crypto.h | 104 +- crypto/openssl/crypto/des/des_enc.c | 21 +- crypto/openssl/crypto/des/des_lib.c | 106 - crypto/openssl/crypto/des/des_locl.h | 6 +- crypto/openssl/crypto/des/ecb_enc.c | 48 +- crypto/openssl/crypto/des/enc_read.c | 12 +- crypto/openssl/crypto/des/enc_writ.c | 4 + crypto/openssl/crypto/des/fcrypt_b.c | 4 +- crypto/openssl/crypto/des/rpc_des.h | 4 +- crypto/openssl/crypto/des/set_key.c | 13 +- crypto/openssl/crypto/des/xcbc_enc.c | 2 +- crypto/openssl/crypto/dh/dh.h | 41 +- crypto/openssl/crypto/dh/dh_ameth.c | 500 ++ crypto/openssl/crypto/dh/dh_asn1.c | 10 +- crypto/openssl/crypto/dh/dh_check.c | 8 +- crypto/openssl/crypto/dh/dh_err.c | 21 +- crypto/openssl/crypto/dh/dh_gen.c | 4 - crypto/openssl/crypto/dh/dh_key.c | 4 - crypto/openssl/crypto/dh/dh_pmeth.c | 254 + .../crypto/{err/err_bio.c => dh/dh_prn.c} | 31 +- crypto/openssl/crypto/dsa/dsa.h | 69 +- crypto/openssl/crypto/dsa/dsa_ameth.c | 657 +++ crypto/openssl/crypto/dsa/dsa_asn1.c | 98 +- crypto/openssl/crypto/dsa/dsa_err.c | 26 +- crypto/openssl/crypto/dsa/dsa_gen.c | 124 +- crypto/openssl/crypto/dsa/dsa_key.c | 4 - crypto/openssl/crypto/dsa/dsa_lib.c | 51 +- .../crypto/{o_time.h => dsa/dsa_locl.h} | 23 +- crypto/openssl/crypto/dsa/dsa_ossl.c | 48 +- crypto/openssl/crypto/dsa/dsa_pmeth.c | 315 + .../crypto/{pem/pem_x509.c => dsa/dsa_prn.c} | 70 +- crypto/openssl/crypto/dsa/dsa_sign.c | 35 +- crypto/openssl/crypto/dsa/dsa_utl.c | 95 - crypto/openssl/crypto/dsa/dsa_vrf.c | 37 +- crypto/openssl/crypto/dso/dso.h | 43 +- crypto/openssl/crypto/dso/dso_dl.c | 42 +- crypto/openssl/crypto/dso/dso_dlfcn.c | 129 +- crypto/openssl/crypto/dso/dso_err.c | 14 +- crypto/openssl/crypto/dso/dso_lib.c | 35 +- crypto/openssl/crypto/dso/dso_null.c | 4 +- crypto/openssl/crypto/dso/dso_openssl.c | 2 + crypto/openssl/crypto/dyn_lck.c | 428 -- crypto/openssl/crypto/ec/ec.h | 814 ++- crypto/openssl/crypto/ec/ec2_mult.c | 33 +- crypto/openssl/crypto/ec/ec2_smpl.c | 112 +- crypto/openssl/crypto/ec/ec2_smpt.c | 141 - crypto/openssl/crypto/ec/ec_ameth.c | 659 +++ crypto/openssl/crypto/ec/ec_curve.c | 2593 +++++--- crypto/openssl/crypto/ec/ec_err.c | 21 +- crypto/openssl/crypto/ec/ec_lcl.h | 13 +- crypto/openssl/crypto/ec/ec_lib.c | 4 +- crypto/openssl/crypto/ec/ec_mult.c | 22 +- crypto/openssl/crypto/ec/ec_pmeth.c | 340 ++ crypto/openssl/crypto/ec/eck_prn.c | 391 ++ crypto/openssl/crypto/ec/ecp_nist.c | 26 - crypto/openssl/crypto/ecdh/ech_err.c | 4 +- crypto/openssl/crypto/ecdsa/ecdsa.h | 193 +- crypto/openssl/crypto/ecdsa/ecs_err.c | 2 +- crypto/openssl/crypto/engine/eng_all.c | 19 +- crypto/openssl/crypto/engine/eng_cryptodev.c | 448 +- crypto/openssl/crypto/engine/eng_dyn.c | 14 +- crypto/openssl/crypto/engine/eng_err.c | 3 + crypto/openssl/crypto/engine/eng_fat.c | 14 + crypto/openssl/crypto/engine/eng_int.h | 12 +- crypto/openssl/crypto/engine/eng_lib.c | 3 + crypto/openssl/crypto/engine/eng_list.c | 2 + crypto/openssl/crypto/engine/eng_openssl.c | 2 +- crypto/openssl/crypto/engine/eng_table.c | 69 +- crypto/openssl/crypto/engine/engine.h | 56 +- crypto/openssl/crypto/engine/tb_asnmth.c | 246 + .../{x509/x509cset.c => engine/tb_pkmeth.c} | 159 +- crypto/openssl/crypto/err/err.c | 789 ++- crypto/openssl/crypto/err/err.h | 77 +- crypto/openssl/crypto/err/err_all.c | 11 +- crypto/openssl/crypto/err/err_def.c | 665 --- crypto/openssl/crypto/err/err_prn.c | 77 +- crypto/openssl/crypto/err/err_str.c | 295 - crypto/openssl/crypto/evp/bio_b64.c | 77 +- crypto/openssl/crypto/evp/bio_enc.c | 6 +- crypto/openssl/crypto/evp/bio_md.c | 16 +- crypto/openssl/crypto/evp/c_all.c | 2 +- crypto/openssl/crypto/evp/c_allc.c | 3 - crypto/openssl/crypto/evp/c_alld.c | 5 +- crypto/openssl/crypto/evp/digest.c | 194 +- crypto/openssl/crypto/evp/e_aes.c | 35 +- crypto/openssl/crypto/evp/e_camellia.c | 2 +- crypto/openssl/crypto/evp/e_des.c | 91 +- crypto/openssl/crypto/evp/e_des3.c | 95 +- crypto/openssl/crypto/evp/e_idea.c | 2 +- crypto/openssl/crypto/evp/e_null.c | 8 +- crypto/openssl/crypto/evp/e_rc2.c | 5 + crypto/openssl/crypto/evp/e_rc4.c | 5 +- .../openssl/crypto/{o_init.c => evp/e_seed.c} | 54 +- crypto/openssl/crypto/evp/e_xcbc_d.c | 19 +- crypto/openssl/crypto/evp/enc_min.c | 390 -- crypto/openssl/crypto/evp/encode.c | 4 +- crypto/openssl/crypto/evp/evp.h | 535 +- crypto/openssl/crypto/evp/evp_enc.c | 267 +- crypto/openssl/crypto/evp/evp_err.c | 60 +- crypto/openssl/crypto/evp/evp_key.c | 9 +- crypto/openssl/crypto/evp/evp_lib.c | 38 +- crypto/openssl/crypto/evp/evp_locl.h | 155 +- crypto/openssl/crypto/evp/evp_pbe.c | 266 +- crypto/openssl/crypto/evp/evp_pkey.c | 646 +- crypto/openssl/crypto/evp/m_dss.c | 2 +- crypto/openssl/crypto/evp/m_dss1.c | 5 +- crypto/openssl/crypto/evp/m_ecdsa.c | 2 +- crypto/openssl/crypto/evp/m_md2.c | 1 - crypto/openssl/crypto/evp/m_md4.c | 1 - crypto/openssl/crypto/evp/m_md5.c | 1 - crypto/openssl/crypto/evp/m_mdc2.c | 3 +- crypto/openssl/crypto/evp/m_sha.c | 1 - crypto/openssl/crypto/evp/m_sha1.c | 17 +- crypto/openssl/crypto/evp/m_sigver.c | 200 + crypto/openssl/crypto/evp/m_wp.c | 42 + crypto/openssl/crypto/evp/names.c | 87 +- crypto/openssl/crypto/evp/p5_crpt.c | 39 +- crypto/openssl/crypto/evp/p5_crpt2.c | 86 +- crypto/openssl/crypto/evp/p_dec.c | 4 +- crypto/openssl/crypto/evp/p_enc.c | 4 +- crypto/openssl/crypto/evp/p_lib.c | 394 +- crypto/openssl/crypto/evp/p_open.c | 2 +- crypto/openssl/crypto/evp/p_seal.c | 2 +- crypto/openssl/crypto/evp/p_sign.c | 47 +- crypto/openssl/crypto/evp/p_verify.c | 44 +- crypto/openssl/crypto/evp/pmeth_fn.c | 368 ++ crypto/openssl/crypto/evp/pmeth_gn.c | 220 + crypto/openssl/crypto/evp/pmeth_lib.c | 538 ++ crypto/openssl/crypto/ex_data.c | 42 +- crypto/openssl/crypto/fips_err.c | 7 - crypto/openssl/crypto/fips_err.h | 137 - .../crypto/{evp/evp_cnf.c => hmac/hm_ameth.c} | 150 +- crypto/openssl/crypto/hmac/hm_pmeth.c | 265 + crypto/openssl/crypto/hmac/hmac.c | 90 +- crypto/openssl/crypto/hmac/hmac.h | 9 +- crypto/openssl/crypto/idea/i_skey.c | 22 +- crypto/openssl/crypto/idea/idea.h | 5 +- crypto/openssl/crypto/krb5/krb5_asn.c | 167 - crypto/openssl/crypto/krb5/krb5_asn.h | 256 - crypto/openssl/crypto/lhash/lh_stats.c | 12 +- crypto/openssl/crypto/lhash/lhash.c | 99 +- crypto/openssl/crypto/lhash/lhash.h | 131 +- crypto/openssl/crypto/md2/md2.h | 95 - crypto/openssl/crypto/md2/md2_dgst.c | 232 - crypto/openssl/crypto/md2/md2_one.c | 94 - crypto/openssl/crypto/md32_common.h | 12 +- crypto/openssl/crypto/md4/md4.h | 5 +- crypto/openssl/crypto/md4/md4_dgst.c | 11 +- crypto/openssl/crypto/md5/md5.h | 5 +- crypto/openssl/crypto/md5/md5_dgst.c | 11 +- crypto/openssl/crypto/md5/md5_locl.h | 2 + crypto/openssl/crypto/mdc2/mdc2.h | 4 +- crypto/openssl/crypto/mdc2/mdc2dgst.c | 7 +- crypto/openssl/crypto/mem.c | 64 +- crypto/openssl/crypto/mem_dbg.c | 257 +- crypto/openssl/crypto/modes/cbc128.c | 206 + crypto/openssl/crypto/modes/cfb128.c | 249 + .../{camellia/cmll_ctr.c => modes/ctr128.c} | 163 +- crypto/openssl/crypto/modes/cts128.c | 259 + crypto/openssl/crypto/modes/modes.h | 59 + .../crypto/{o_init.c => modes/ofb128.c} | 105 +- crypto/openssl/crypto/o_time.c | 153 +- crypto/openssl/crypto/o_time.h | 1 + crypto/openssl/crypto/objects/o_names.c | 47 +- crypto/openssl/crypto/objects/obj_dat.c | 169 +- crypto/openssl/crypto/objects/obj_dat.h | 5234 ++++++++--------- crypto/openssl/crypto/objects/obj_err.c | 2 +- crypto/openssl/crypto/objects/obj_lib.c | 35 +- crypto/openssl/crypto/objects/obj_xref.c | 231 + crypto/openssl/crypto/objects/obj_xref.h | 75 + crypto/openssl/crypto/objects/objects.h | 97 +- crypto/openssl/crypto/ocsp/ocsp.h | 22 +- crypto/openssl/crypto/ocsp/ocsp_cl.c | 1 - crypto/openssl/crypto/ocsp/ocsp_err.c | 3 +- crypto/openssl/crypto/ocsp/ocsp_ext.c | 47 +- crypto/openssl/crypto/ocsp/ocsp_ht.c | 56 +- crypto/openssl/crypto/ocsp/ocsp_lib.c | 3 + crypto/openssl/crypto/ocsp/ocsp_prn.c | 19 +- crypto/openssl/crypto/ocsp/ocsp_vfy.c | 4 +- crypto/openssl/crypto/opensslv.h | 10 +- crypto/openssl/crypto/ossl_typ.h | 21 +- crypto/openssl/crypto/pem/pem.h | 255 +- crypto/openssl/crypto/pem/pem_all.c | 194 +- crypto/openssl/crypto/pem/pem_err.c | 28 +- crypto/openssl/crypto/pem/pem_info.c | 40 +- crypto/openssl/crypto/pem/pem_lib.c | 100 +- crypto/openssl/crypto/pem/pem_pkey.c | 109 +- crypto/openssl/crypto/pem/pem_x509.c | 1 - crypto/openssl/crypto/pem/pem_xaux.c | 1 - crypto/openssl/crypto/pem/pvkfmt.c | 942 +++ crypto/openssl/crypto/pkcs12/p12_add.c | 20 +- crypto/openssl/crypto/pkcs12/p12_attr.c | 8 +- crypto/openssl/crypto/pkcs12/p12_crpt.c | 20 +- crypto/openssl/crypto/pkcs12/p12_crt.c | 11 - crypto/openssl/crypto/pkcs12/p12_key.c | 13 +- crypto/openssl/crypto/pkcs12/p12_kiss.c | 163 +- crypto/openssl/crypto/pkcs12/p12_mutl.c | 8 +- crypto/openssl/crypto/pkcs12/p12_npas.c | 17 +- crypto/openssl/crypto/pkcs12/p12_utl.c | 10 +- crypto/openssl/crypto/pkcs12/pk12err.c | 2 +- crypto/openssl/crypto/pkcs12/pkcs12.h | 9 +- .../{rc4/rc4_fblk.c => pkcs7/bio_pk7.c} | 28 +- crypto/openssl/crypto/pkcs7/pk7_asn1.c | 43 +- crypto/openssl/crypto/pkcs7/pk7_attr.c | 66 +- crypto/openssl/crypto/pkcs7/pk7_doit.c | 486 +- crypto/openssl/crypto/pkcs7/pk7_lib.c | 192 +- crypto/openssl/crypto/pkcs7/pk7_mime.c | 65 +- crypto/openssl/crypto/pkcs7/pk7_smime.c | 263 +- crypto/openssl/crypto/pkcs7/pkcs7.h | 59 +- crypto/openssl/crypto/pkcs7/pkcs7err.c | 22 +- crypto/openssl/crypto/pqueue/pq_compat.h | 152 - crypto/openssl/crypto/pqueue/pqueue.c | 29 +- crypto/openssl/crypto/pqueue/pqueue.h | 8 +- crypto/openssl/crypto/rand/md_rand.c | 46 +- crypto/openssl/crypto/rand/rand.h | 29 +- crypto/openssl/crypto/rand/rand_egd.c | 2 +- crypto/openssl/crypto/rand/rand_eng.c | 152 - crypto/openssl/crypto/rand/rand_err.c | 20 +- crypto/openssl/crypto/rand/rand_lcl.h | 11 - crypto/openssl/crypto/rand/rand_lib.c | 71 +- crypto/openssl/crypto/rand/rand_unix.c | 71 +- crypto/openssl/crypto/rand/randfile.c | 24 +- crypto/openssl/crypto/rc2/rc2.h | 4 +- crypto/openssl/crypto/rc2/rc2_skey.c | 19 +- crypto/openssl/crypto/rc4/rc4.h | 7 +- crypto/openssl/crypto/rc4/rc4_enc.c | 16 +- crypto/openssl/crypto/rc4/rc4_skey.c | 21 +- crypto/openssl/crypto/rc5/rc5.h | 121 - crypto/openssl/crypto/rc5/rc5_ecb.c | 80 - crypto/openssl/crypto/rc5/rc5_enc.c | 215 - crypto/openssl/crypto/rc5/rc5_locl.h | 207 - crypto/openssl/crypto/rc5/rc5_skey.c | 130 - crypto/openssl/crypto/rc5/rc5cfb64.c | 122 - crypto/openssl/crypto/rc5/rc5ofb64.c | 111 - crypto/openssl/crypto/ripemd/ripemd.h | 6 +- crypto/openssl/crypto/ripemd/rmd_dgst.c | 11 +- crypto/openssl/crypto/ripemd/rmd_locl.h | 2 +- crypto/openssl/crypto/rsa/rsa.h | 89 +- crypto/openssl/crypto/rsa/rsa_ameth.c | 349 ++ crypto/openssl/crypto/rsa/rsa_asn1.c | 16 +- crypto/openssl/crypto/rsa/rsa_eay.c | 6 +- crypto/openssl/crypto/rsa/rsa_eng.c | 357 -- crypto/openssl/crypto/rsa/rsa_err.c | 29 +- crypto/openssl/crypto/rsa/rsa_gen.c | 3 - crypto/openssl/crypto/rsa/rsa_lib.c | 283 +- crypto/openssl/crypto/rsa/rsa_locl.h | 4 + crypto/openssl/crypto/rsa/rsa_oaep.c | 21 +- crypto/openssl/crypto/rsa/rsa_pmeth.c | 587 ++ .../crypto/{pem/pem_x509.c => rsa/rsa_prn.c} | 42 +- crypto/openssl/crypto/rsa/rsa_pss.c | 14 +- crypto/openssl/crypto/rsa/rsa_sign.c | 96 +- crypto/openssl/crypto/rsa/rsa_x931g.c | 255 - crypto/openssl/crypto/seed/seed.c | 325 + .../crypto/{evp/m_ecdsa.c => seed/seed.h} | 177 +- .../crypto/{o_time.h => seed/seed_cbc.c} | 35 +- .../crypto/{evp/dig_eng.c => seed/seed_cfb.c} | 176 +- .../crypto/{o_time.h => seed/seed_ecb.c} | 32 +- crypto/openssl/crypto/seed/seed_locl.h | 116 + .../crypto/{aes/aes_ofb.c => seed/seed_ofb.c} | 44 +- crypto/openssl/crypto/sha/sha.h | 5 +- crypto/openssl/crypto/sha/sha1_one.c | 2 +- crypto/openssl/crypto/sha/sha1dgst.c | 4 - crypto/openssl/crypto/sha/sha256.c | 32 +- crypto/openssl/crypto/sha/sha512.c | 189 +- crypto/openssl/crypto/sha/sha_dgst.c | 6 - crypto/openssl/crypto/sha/sha_locl.h | 11 +- crypto/openssl/crypto/stack/safestack.h | 964 ++- crypto/openssl/crypto/stack/stack.c | 85 +- crypto/openssl/crypto/stack/stack.h | 49 +- crypto/openssl/crypto/store/README | 95 - crypto/openssl/crypto/store/store.h | 554 -- crypto/openssl/crypto/store/str_err.c | 211 - crypto/openssl/crypto/store/str_lib.c | 1824 ------ crypto/openssl/crypto/store/str_locl.h | 124 - crypto/openssl/crypto/store/str_mem.c | 357 -- crypto/openssl/crypto/store/str_meth.c | 250 - crypto/openssl/crypto/symhacks.h | 86 +- crypto/openssl/crypto/tmdiff.c | 260 - crypto/openssl/crypto/tmdiff.h | 93 - crypto/openssl/crypto/ts/ts.h | 861 +++ crypto/openssl/crypto/ts/ts_asn1.c | 322 + crypto/openssl/crypto/ts/ts_conf.c | 507 ++ crypto/openssl/crypto/ts/ts_err.c | 179 + .../crypto/{evp/evp_cnf.c => ts/ts_lib.c} | 126 +- .../{dh/dh_asn1.c => ts/ts_req_print.c} | 69 +- crypto/openssl/crypto/ts/ts_req_utils.c | 234 + crypto/openssl/crypto/ts/ts_rsp_print.c | 287 + crypto/openssl/crypto/ts/ts_rsp_sign.c | 1020 ++++ crypto/openssl/crypto/ts/ts_rsp_utils.c | 409 ++ crypto/openssl/crypto/ts/ts_rsp_verify.c | 725 +++ .../{buffer/buf_str.c => ts/ts_verify_ctx.c} | 130 +- crypto/openssl/crypto/txt_db/txt_db.c | 76 +- crypto/openssl/crypto/txt_db/txt_db.h | 19 +- crypto/openssl/crypto/ui/ui.h | 4 +- crypto/openssl/crypto/ui/ui_err.c | 2 +- crypto/openssl/crypto/ui/ui_lib.c | 19 + crypto/openssl/crypto/ui/ui_openssl.c | 6 +- crypto/openssl/crypto/whrlpool/whrlpool.h | 38 + crypto/openssl/crypto/whrlpool/wp_block.c | 655 +++ crypto/openssl/crypto/whrlpool/wp_dgst.c | 264 + crypto/openssl/crypto/whrlpool/wp_locl.h | 3 + crypto/openssl/crypto/x509/by_dir.c | 221 +- crypto/openssl/crypto/x509/by_file.c | 2 +- crypto/openssl/crypto/x509/x509.h | 257 +- crypto/openssl/crypto/x509/x509_cmp.c | 237 +- crypto/openssl/crypto/x509/x509_err.c | 5 +- crypto/openssl/crypto/x509/x509_lu.c | 149 +- crypto/openssl/crypto/x509/x509_obj.c | 2 +- crypto/openssl/crypto/x509/x509_req.c | 24 +- crypto/openssl/crypto/x509/x509_set.c | 4 +- crypto/openssl/crypto/x509/x509_trs.c | 3 +- crypto/openssl/crypto/x509/x509_txt.c | 24 +- crypto/openssl/crypto/x509/x509_vfy.c | 937 ++- crypto/openssl/crypto/x509/x509_vfy.h | 37 +- crypto/openssl/crypto/x509/x509_vpm.c | 22 +- crypto/openssl/crypto/x509/x509cset.c | 4 +- crypto/openssl/crypto/x509/x509name.c | 2 +- crypto/openssl/crypto/x509/x509type.c | 4 + crypto/openssl/crypto/x509/x_all.c | 7 - crypto/openssl/crypto/x509v3/ext_dat.h | 13 +- crypto/openssl/crypto/x509v3/pcy_cache.c | 1 - crypto/openssl/crypto/x509v3/pcy_data.c | 12 +- crypto/openssl/crypto/x509v3/pcy_int.h | 25 +- crypto/openssl/crypto/x509v3/pcy_map.c | 56 +- crypto/openssl/crypto/x509v3/pcy_node.c | 43 +- crypto/openssl/crypto/x509v3/pcy_tree.c | 233 +- crypto/openssl/crypto/x509v3/v3_addr.c | 25 +- crypto/openssl/crypto/x509v3/v3_alt.c | 135 +- crypto/openssl/crypto/x509v3/v3_asid.c | 10 +- crypto/openssl/crypto/x509v3/v3_conf.c | 51 +- crypto/openssl/crypto/x509v3/v3_cpols.c | 5 +- crypto/openssl/crypto/x509v3/v3_crld.c | 552 +- crypto/openssl/crypto/x509v3/v3_enum.c | 19 +- crypto/openssl/crypto/x509v3/v3_extku.c | 16 +- crypto/openssl/crypto/x509v3/v3_genn.c | 153 +- crypto/openssl/crypto/x509v3/v3_lib.c | 24 +- crypto/openssl/crypto/x509v3/v3_ncons.c | 312 +- crypto/openssl/crypto/x509v3/v3_ocsp.c | 42 +- crypto/openssl/crypto/x509v3/v3_pci.c | 32 +- crypto/openssl/crypto/x509v3/v3_pcons.c | 20 +- crypto/openssl/crypto/x509v3/v3_pmaps.c | 18 +- crypto/openssl/crypto/x509v3/v3_prn.c | 2 +- crypto/openssl/crypto/x509v3/v3_purp.c | 194 +- crypto/openssl/crypto/x509v3/v3_utl.c | 45 +- crypto/openssl/crypto/x509v3/v3err.c | 13 +- crypto/openssl/crypto/x509v3/x509v3.h | 173 +- crypto/openssl/doc/apps/asn1parse.pod | 14 +- crypto/openssl/doc/apps/ca.pod | 12 +- crypto/openssl/doc/apps/ciphers.pod | 58 +- crypto/openssl/doc/apps/cms.pod | 602 ++ crypto/openssl/doc/apps/dgst.pod | 47 + crypto/openssl/doc/apps/dhparam.pod | 2 +- crypto/openssl/doc/apps/dsa.pod | 2 +- crypto/openssl/doc/apps/dsaparam.pod | 2 +- crypto/openssl/doc/apps/ec.pod | 2 +- crypto/openssl/doc/apps/ecparam.pod | 2 +- crypto/openssl/doc/apps/enc.pod | 60 +- crypto/openssl/doc/apps/gendsa.pod | 2 +- crypto/openssl/doc/apps/genpkey.pod | 213 + crypto/openssl/doc/apps/genrsa.pod | 2 +- crypto/openssl/doc/apps/ocsp.pod | 6 + crypto/openssl/doc/apps/openssl.pod | 93 +- crypto/openssl/doc/apps/pkcs12.pod | 85 +- crypto/openssl/doc/apps/pkcs7.pod | 2 +- crypto/openssl/doc/apps/pkcs8.pod | 2 +- crypto/openssl/doc/apps/pkey.pod | 135 + crypto/openssl/doc/apps/pkeyparam.pod | 69 + crypto/openssl/doc/apps/pkeyutl.pod | 222 + crypto/openssl/doc/apps/req.pod | 91 +- crypto/openssl/doc/apps/rsa.pod | 2 +- crypto/openssl/doc/apps/s_client.pod | 27 +- crypto/openssl/doc/apps/s_server.pod | 15 +- crypto/openssl/doc/apps/smime.pod | 118 +- crypto/openssl/doc/apps/speed.pod | 2 +- crypto/openssl/doc/apps/spkac.pod | 2 +- crypto/openssl/doc/apps/ts.pod | 594 ++ crypto/openssl/doc/apps/tsget.pod | 194 + crypto/openssl/doc/apps/verify.pod | 83 +- crypto/openssl/doc/apps/x509.pod | 30 +- crypto/openssl/doc/apps/x509v3_config.pod | 97 +- crypto/openssl/doc/crypto/ASN1_OBJECT_new.pod | 2 + .../openssl/doc/crypto/ASN1_STRING_length.pod | 2 + crypto/openssl/doc/crypto/ASN1_STRING_new.pod | 2 + .../doc/crypto/ASN1_generate_nconf.pod | 5 +- crypto/openssl/doc/crypto/BIO_f_buffer.pod | 9 +- crypto/openssl/doc/crypto/BIO_f_md.pod | 6 + crypto/openssl/doc/crypto/BIO_f_ssl.pod | 9 + crypto/openssl/doc/crypto/BIO_new_CMS.pod | 66 + crypto/openssl/doc/crypto/BIO_s_file.pod | 4 + crypto/openssl/doc/crypto/BIO_s_mem.pod | 2 +- .../openssl/doc/crypto/BIO_should_retry.pod | 2 +- crypto/openssl/doc/crypto/BN_BLINDING_new.pod | 20 +- crypto/openssl/doc/crypto/CMS_add0_cert.pod | 66 + .../doc/crypto/CMS_add1_recipient_cert.pod | 62 + crypto/openssl/doc/crypto/CMS_compress.pod | 73 + crypto/openssl/doc/crypto/CMS_decrypt.pod | 65 + crypto/openssl/doc/crypto/CMS_encrypt.pod | 96 + crypto/openssl/doc/crypto/CMS_final.pod | 41 + .../doc/crypto/CMS_get0_RecipientInfos.pod | 106 + .../doc/crypto/CMS_get0_SignerInfos.pod | 75 + crypto/openssl/doc/crypto/CMS_get0_type.pod | 63 + .../doc/crypto/CMS_get1_ReceiptRequest.pod | 69 + crypto/openssl/doc/crypto/CMS_sign.pod | 121 + .../doc/crypto/CMS_sign_add1_signer.pod | 101 + .../openssl/doc/crypto/CMS_sign_receipt.pod | 45 + crypto/openssl/doc/crypto/CMS_uncompress.pod | 54 + crypto/openssl/doc/crypto/CMS_verify.pod | 126 + .../openssl/doc/crypto/CMS_verify_receipt.pod | 47 + .../openssl/doc/crypto/CRYPTO_set_ex_data.pod | 2 + .../doc/crypto/DSA_get_ex_new_index.pod | 2 +- crypto/openssl/doc/crypto/EVP_DigestInit.pod | 17 +- .../openssl/doc/crypto/EVP_DigestSignInit.pod | 87 + .../doc/crypto/EVP_DigestVerifyInit.pod | 82 + .../openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod | 128 + .../openssl/doc/crypto/EVP_PKEY_CTX_new.pod | 52 + crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod | 61 + .../openssl/doc/crypto/EVP_PKEY_decrypt.pod | 93 + crypto/openssl/doc/crypto/EVP_PKEY_derive.pod | 93 + .../openssl/doc/crypto/EVP_PKEY_encrypt.pod | 93 + .../crypto/EVP_PKEY_get_default_digest.pod | 41 + crypto/openssl/doc/crypto/EVP_PKEY_keygen.pod | 161 + .../doc/crypto/EVP_PKEY_print_private.pod | 53 + crypto/openssl/doc/crypto/EVP_PKEY_sign.pod | 96 + crypto/openssl/doc/crypto/EVP_PKEY_verify.pod | 91 + .../doc/crypto/EVP_PKEY_verifyrecover.pod | 103 + crypto/openssl/doc/crypto/EVP_SignInit.pod | 9 + crypto/openssl/doc/crypto/EVP_VerifyInit.pod | 9 + crypto/openssl/doc/crypto/OBJ_nid2obj.pod | 2 + .../doc/crypto/PEM_write_bio_CMS_stream.pod | 41 + .../doc/crypto/PEM_write_bio_PKCS7_stream.pod | 41 + crypto/openssl/doc/crypto/PKCS7_decrypt.pod | 4 +- crypto/openssl/doc/crypto/PKCS7_encrypt.pod | 61 +- crypto/openssl/doc/crypto/PKCS7_sign.pod | 115 +- .../doc/crypto/PKCS7_sign_add_signer.pod | 87 + crypto/openssl/doc/crypto/PKCS7_verify.pod | 6 +- crypto/openssl/doc/crypto/SMIME_read_CMS.pod | 70 + .../openssl/doc/crypto/SMIME_read_PKCS7.pod | 4 +- crypto/openssl/doc/crypto/SMIME_write_CMS.pod | 64 + .../openssl/doc/crypto/SMIME_write_PKCS7.pod | 24 +- .../doc/crypto/X509_NAME_ENTRY_get_object.pod | 16 +- .../doc/crypto/X509_NAME_add_entry_by_txt.pod | 12 +- .../doc/crypto/X509_NAME_get_index_by_NID.pod | 14 +- .../doc/crypto/X509_STORE_CTX_get_error.pod | 303 + .../X509_STORE_CTX_get_ex_new_index.pod | 41 + .../openssl/doc/crypto/X509_STORE_CTX_new.pod | 122 + .../crypto/X509_STORE_CTX_set_verify_cb.pod | 161 + .../crypto/X509_STORE_set_verify_cb_func.pod | 54 + .../crypto/X509_VERIFY_PARAM_set_flags.pod | 171 + crypto/openssl/doc/crypto/X509_new.pod | 2 + .../openssl/doc/crypto/X509_verify_cert.pod | 53 + crypto/openssl/doc/crypto/bn_internal.pod | 2 + .../openssl/doc/crypto/d2i_RSAPublicKey.pod | 8 +- crypto/openssl/doc/crypto/evp.pod | 22 +- crypto/openssl/doc/crypto/hmac.pod | 20 +- .../openssl/doc/crypto/i2d_CMS_bio_stream.pod | 44 + .../doc/crypto/i2d_PKCS7_bio_stream.pod | 44 + crypto/openssl/doc/crypto/lhash.pod | 244 +- crypto/openssl/doc/crypto/threads.pod | 91 +- crypto/openssl/doc/crypto/ui_compat.pod | 2 + crypto/openssl/doc/ssl/SSL_CTX_new.pod | 2 +- crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod | 10 + .../openssl/doc/ssl/SSL_CTX_set_options.pod | 3 +- .../ssl/SSL_CTX_set_psk_client_callback.pod | 81 + .../doc/ssl/SSL_CTX_set_ssl_version.pod | 6 +- .../doc/ssl/SSL_CTX_use_psk_identity_hint.pod | 102 + .../openssl/doc/ssl/SSL_get_psk_identity.pod | 63 + crypto/openssl/doc/ssl/SSL_library_init.pod | 17 +- crypto/openssl/doc/ssl/ssl.pod | 50 +- crypto/openssl/e_os.h | 105 +- crypto/openssl/e_os2.h | 24 +- crypto/openssl/engines/ccgost/README.gost | 300 + crypto/openssl/engines/ccgost/e_gost_err.c | 212 + crypto/openssl/engines/ccgost/e_gost_err.h | 156 + crypto/openssl/engines/ccgost/gost2001.c | 343 ++ crypto/openssl/engines/ccgost/gost2001_keyx.c | 304 + crypto/openssl/engines/ccgost/gost2001_keyx.h | 10 + crypto/openssl/engines/ccgost/gost89.c | 409 ++ crypto/openssl/engines/ccgost/gost89.h | 96 + crypto/openssl/engines/ccgost/gost94_keyx.c | 287 + crypto/openssl/engines/ccgost/gost_ameth.c | 910 +++ crypto/openssl/engines/ccgost/gost_asn1.c | 55 + crypto/openssl/engines/ccgost/gost_crypt.c | 616 ++ crypto/openssl/engines/ccgost/gost_ctl.c | 89 + crypto/openssl/engines/ccgost/gost_eng.c | 273 + crypto/openssl/engines/ccgost/gost_keywrap.c | 109 + crypto/openssl/engines/ccgost/gost_keywrap.h | 56 + crypto/openssl/engines/ccgost/gost_lcl.h | 218 + crypto/openssl/engines/ccgost/gost_md.c | 75 + crypto/openssl/engines/ccgost/gost_params.c | 198 + crypto/openssl/engines/ccgost/gost_params.h | 34 + crypto/openssl/engines/ccgost/gost_pmeth.c | 621 ++ crypto/openssl/engines/ccgost/gost_sign.c | 321 + crypto/openssl/engines/ccgost/gosthash.c | 255 + crypto/openssl/engines/ccgost/gosthash.h | 48 + crypto/openssl/engines/ccgost/gostsum.c | 210 + crypto/openssl/engines/e_4758cca.c | 17 +- crypto/openssl/engines/e_aep.c | 2 +- crypto/openssl/engines/e_capi.c | 1816 ++++++ crypto/openssl/engines/e_capi_err.c | 184 + crypto/openssl/engines/e_capi_err.h | 124 + crypto/openssl/engines/e_chil.c | 70 +- crypto/openssl/engines/e_gmp.c | 4 +- .../eng_padlock.c => engines/e_padlock.c} | 24 +- crypto/openssl/engines/e_sureware.c | 2 - crypto/openssl/engines/e_ubsec.c | 15 +- crypto/openssl/ssl/bio_ssl.c | 21 +- crypto/openssl/ssl/d1_both.c | 412 +- crypto/openssl/ssl/d1_clnt.c | 347 +- crypto/openssl/ssl/d1_enc.c | 29 +- crypto/openssl/ssl/d1_lib.c | 42 +- crypto/openssl/ssl/d1_meth.c | 4 +- crypto/openssl/ssl/d1_pkt.c | 348 +- crypto/openssl/ssl/d1_srvr.c | 312 +- crypto/openssl/ssl/dtls1.h | 11 +- crypto/openssl/ssl/kssl.c | 23 +- crypto/openssl/ssl/kssl_lcl.h | 2 +- crypto/openssl/ssl/s23_clnt.c | 216 +- crypto/openssl/ssl/s23_lib.c | 12 +- crypto/openssl/ssl/s23_meth.c | 4 +- crypto/openssl/ssl/s23_srvr.c | 32 +- crypto/openssl/ssl/s2_clnt.c | 12 +- crypto/openssl/ssl/s2_enc.c | 9 +- crypto/openssl/ssl/s2_lib.c | 178 +- crypto/openssl/ssl/s2_meth.c | 10 +- crypto/openssl/ssl/s2_pkt.c | 23 +- crypto/openssl/ssl/s2_srvr.c | 8 +- crypto/openssl/ssl/s3_both.c | 220 +- crypto/openssl/ssl/s3_clnt.c | 565 +- crypto/openssl/ssl/s3_enc.c | 193 +- crypto/openssl/ssl/s3_lib.c | 2227 ++++--- crypto/openssl/ssl/s3_meth.c | 10 +- crypto/openssl/ssl/s3_pkt.c | 233 +- crypto/openssl/ssl/s3_srvr.c | 771 ++- crypto/openssl/ssl/ssl.h | 522 +- crypto/openssl/ssl/ssl3.h | 115 +- crypto/openssl/ssl/ssl_algs.c | 15 +- crypto/openssl/ssl/ssl_asn1.c | 104 +- crypto/openssl/ssl/ssl_cert.c | 10 +- crypto/openssl/ssl/ssl_ciph.c | 1016 ++-- crypto/openssl/ssl/ssl_err.c | 41 +- crypto/openssl/ssl/ssl_lib.c | 556 +- crypto/openssl/ssl/ssl_locl.h | 275 +- crypto/openssl/ssl/ssl_sess.c | 246 +- crypto/openssl/ssl/ssl_stat.c | 50 + crypto/openssl/ssl/ssl_txt.c | 35 +- crypto/openssl/ssl/t1_clnt.c | 4 +- crypto/openssl/ssl/t1_enc.c | 511 +- crypto/openssl/ssl/t1_lib.c | 773 ++- crypto/openssl/ssl/t1_meth.c | 4 +- crypto/openssl/ssl/t1_srvr.c | 4 +- crypto/openssl/ssl/tls1.h | 140 +- 723 files changed, 67276 insertions(+), 30314 deletions(-) create mode 100644 crypto/openssl/apps/genpkey.c create mode 100644 crypto/openssl/apps/pkey.c copy crypto/openssl/{crypto/x509/x509cset.c => apps/pkeyparam.c} (51%) create mode 100644 crypto/openssl/apps/pkeyutl.c create mode 100644 crypto/openssl/apps/ts.c delete mode 100644 crypto/openssl/crypto/asn1/a_hdr.c delete mode 100644 crypto/openssl/crypto/asn1/a_meth.c create mode 100644 crypto/openssl/crypto/asn1/ameth_lib.c copy crypto/openssl/crypto/{x509v3/pcy_node.c => asn1/asn1_locl.h} (52%) create mode 100644 crypto/openssl/crypto/asn1/bio_asn1.c create mode 100644 crypto/openssl/crypto/asn1/bio_ndef.c create mode 100644 crypto/openssl/crypto/asn1/tasn_prn.c copy crypto/openssl/crypto/{pem/pem_x509.c => asn1/x_nx509.c} (86%) delete mode 100644 crypto/openssl/crypto/bn/bn_opt.c delete mode 100644 crypto/openssl/crypto/bn/bn_x931p.c delete mode 100644 crypto/openssl/crypto/des/des_lib.c create mode 100644 crypto/openssl/crypto/dh/dh_ameth.c create mode 100644 crypto/openssl/crypto/dh/dh_pmeth.c rename crypto/openssl/crypto/{err/err_bio.c => dh/dh_prn.c} (89%) create mode 100644 crypto/openssl/crypto/dsa/dsa_ameth.c copy crypto/openssl/crypto/{o_time.h => dsa/dsa_locl.h} (82%) create mode 100644 crypto/openssl/crypto/dsa/dsa_pmeth.c copy crypto/openssl/crypto/{pem/pem_x509.c => dsa/dsa_prn.c} (69%) delete mode 100644 crypto/openssl/crypto/dsa/dsa_utl.c delete mode 100644 crypto/openssl/crypto/dyn_lck.c delete mode 100644 crypto/openssl/crypto/ec/ec2_smpt.c create mode 100644 crypto/openssl/crypto/ec/ec_ameth.c create mode 100644 crypto/openssl/crypto/ec/ec_pmeth.c create mode 100644 crypto/openssl/crypto/ec/eck_prn.c create mode 100644 crypto/openssl/crypto/engine/tb_asnmth.c copy crypto/openssl/crypto/{x509/x509cset.c => engine/tb_pkmeth.c} (50%) delete mode 100644 crypto/openssl/crypto/err/err_def.c delete mode 100644 crypto/openssl/crypto/err/err_str.c copy crypto/openssl/crypto/{o_init.c => evp/e_seed.c} (76%) delete mode 100644 crypto/openssl/crypto/evp/enc_min.c create mode 100644 crypto/openssl/crypto/evp/m_sigver.c create mode 100644 crypto/openssl/crypto/evp/m_wp.c create mode 100644 crypto/openssl/crypto/evp/pmeth_fn.c create mode 100644 crypto/openssl/crypto/evp/pmeth_gn.c create mode 100644 crypto/openssl/crypto/evp/pmeth_lib.c delete mode 100644 crypto/openssl/crypto/fips_err.c delete mode 100644 crypto/openssl/crypto/fips_err.h copy crypto/openssl/crypto/{evp/evp_cnf.c => hmac/hm_ameth.c} (59%) create mode 100644 crypto/openssl/crypto/hmac/hm_pmeth.c delete mode 100644 crypto/openssl/crypto/krb5/krb5_asn.c delete mode 100644 crypto/openssl/crypto/krb5/krb5_asn.h delete mode 100644 crypto/openssl/crypto/md2/md2.h delete mode 100644 crypto/openssl/crypto/md2/md2_dgst.c delete mode 100644 crypto/openssl/crypto/md2/md2_one.c create mode 100644 crypto/openssl/crypto/modes/cbc128.c create mode 100644 crypto/openssl/crypto/modes/cfb128.c copy crypto/openssl/crypto/{camellia/cmll_ctr.c => modes/ctr128.c} (58%) create mode 100644 crypto/openssl/crypto/modes/cts128.c create mode 100644 crypto/openssl/crypto/modes/modes.h rename crypto/openssl/crypto/{o_init.c => modes/ofb128.c} (58%) create mode 100644 crypto/openssl/crypto/objects/obj_xref.c create mode 100644 crypto/openssl/crypto/objects/obj_xref.h create mode 100644 crypto/openssl/crypto/pem/pvkfmt.c rename crypto/openssl/crypto/{rc4/rc4_fblk.c => pkcs7/bio_pk7.c} (84%) delete mode 100644 crypto/openssl/crypto/pqueue/pq_compat.h delete mode 100644 crypto/openssl/crypto/rand/rand_eng.c delete mode 100644 crypto/openssl/crypto/rc5/rc5.h delete mode 100644 crypto/openssl/crypto/rc5/rc5_ecb.c delete mode 100644 crypto/openssl/crypto/rc5/rc5_enc.c delete mode 100644 crypto/openssl/crypto/rc5/rc5_locl.h delete mode 100644 crypto/openssl/crypto/rc5/rc5_skey.c delete mode 100644 crypto/openssl/crypto/rc5/rc5cfb64.c delete mode 100644 crypto/openssl/crypto/rc5/rc5ofb64.c create mode 100644 crypto/openssl/crypto/rsa/rsa_ameth.c delete mode 100644 crypto/openssl/crypto/rsa/rsa_eng.c create mode 100644 crypto/openssl/crypto/rsa/rsa_locl.h create mode 100644 crypto/openssl/crypto/rsa/rsa_pmeth.c copy crypto/openssl/crypto/{pem/pem_x509.c => rsa/rsa_prn.c} (80%) delete mode 100644 crypto/openssl/crypto/rsa/rsa_x931g.c create mode 100644 crypto/openssl/crypto/seed/seed.c copy crypto/openssl/crypto/{evp/m_ecdsa.c => seed/seed.h} (52%) copy crypto/openssl/crypto/{o_time.h => seed/seed_cbc.c} (75%) rename crypto/openssl/crypto/{evp/dig_eng.c => seed/seed_cfb.c} (74%) copy crypto/openssl/crypto/{o_time.h => seed/seed_ecb.c} (76%) create mode 100644 crypto/openssl/crypto/seed/seed_locl.h copy crypto/openssl/crypto/{aes/aes_ofb.c => seed/seed_ofb.c} (86%) delete mode 100644 crypto/openssl/crypto/store/README delete mode 100644 crypto/openssl/crypto/store/store.h delete mode 100644 crypto/openssl/crypto/store/str_err.c delete mode 100644 crypto/openssl/crypto/store/str_lib.c delete mode 100644 crypto/openssl/crypto/store/str_locl.h delete mode 100644 crypto/openssl/crypto/store/str_mem.c delete mode 100644 crypto/openssl/crypto/store/str_meth.c delete mode 100644 crypto/openssl/crypto/tmdiff.c delete mode 100644 crypto/openssl/crypto/tmdiff.h create mode 100644 crypto/openssl/crypto/ts/ts.h create mode 100644 crypto/openssl/crypto/ts/ts_asn1.c create mode 100644 crypto/openssl/crypto/ts/ts_conf.c create mode 100644 crypto/openssl/crypto/ts/ts_err.c rename crypto/openssl/crypto/{evp/evp_cnf.c => ts/ts_lib.c} (57%) copy crypto/openssl/crypto/{dh/dh_asn1.c => ts/ts_req_print.c} (72%) create mode 100644 crypto/openssl/crypto/ts/ts_req_utils.c create mode 100644 crypto/openssl/crypto/ts/ts_rsp_print.c create mode 100644 crypto/openssl/crypto/ts/ts_rsp_sign.c create mode 100644 crypto/openssl/crypto/ts/ts_rsp_utils.c create mode 100644 crypto/openssl/crypto/ts/ts_rsp_verify.c rename crypto/openssl/crypto/{buffer/buf_str.c => ts/ts_verify_ctx.c} (52%) create mode 100644 crypto/openssl/crypto/whrlpool/whrlpool.h create mode 100644 crypto/openssl/crypto/whrlpool/wp_block.c create mode 100644 crypto/openssl/crypto/whrlpool/wp_dgst.c create mode 100644 crypto/openssl/crypto/whrlpool/wp_locl.h create mode 100644 crypto/openssl/doc/apps/cms.pod create mode 100644 crypto/openssl/doc/apps/genpkey.pod create mode 100644 crypto/openssl/doc/apps/pkey.pod create mode 100644 crypto/openssl/doc/apps/pkeyparam.pod create mode 100644 crypto/openssl/doc/apps/pkeyutl.pod create mode 100644 crypto/openssl/doc/apps/ts.pod create mode 100644 crypto/openssl/doc/apps/tsget.pod create mode 100644 crypto/openssl/doc/crypto/BIO_new_CMS.pod create mode 100644 crypto/openssl/doc/crypto/CMS_add0_cert.pod create mode 100644 crypto/openssl/doc/crypto/CMS_add1_recipient_cert.pod create mode 100644 crypto/openssl/doc/crypto/CMS_compress.pod create mode 100644 crypto/openssl/doc/crypto/CMS_decrypt.pod create mode 100644 crypto/openssl/doc/crypto/CMS_encrypt.pod create mode 100644 crypto/openssl/doc/crypto/CMS_final.pod create mode 100644 crypto/openssl/doc/crypto/CMS_get0_RecipientInfos.pod create mode 100644 crypto/openssl/doc/crypto/CMS_get0_SignerInfos.pod create mode 100644 crypto/openssl/doc/crypto/CMS_get0_type.pod create mode 100644 crypto/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod create mode 100644 crypto/openssl/doc/crypto/CMS_sign.pod create mode 100644 crypto/openssl/doc/crypto/CMS_sign_add1_signer.pod create mode 100644 crypto/openssl/doc/crypto/CMS_sign_receipt.pod create mode 100644 crypto/openssl/doc/crypto/CMS_uncompress.pod create mode 100644 crypto/openssl/doc/crypto/CMS_verify.pod create mode 100644 crypto/openssl/doc/crypto/CMS_verify_receipt.pod create mode 100644 crypto/openssl/doc/crypto/EVP_DigestSignInit.pod create mode 100644 crypto/openssl/doc/crypto/EVP_DigestVerifyInit.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_CTX_new.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_decrypt.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_derive.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_encrypt.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_keygen.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_print_private.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_sign.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_verify.pod create mode 100644 crypto/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod create mode 100644 crypto/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod create mode 100644 crypto/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod create mode 100644 crypto/openssl/doc/crypto/PKCS7_sign_add_signer.pod create mode 100644 crypto/openssl/doc/crypto/SMIME_read_CMS.pod create mode 100644 crypto/openssl/doc/crypto/SMIME_write_CMS.pod create mode 100644 crypto/openssl/doc/crypto/X509_STORE_CTX_get_error.pod create mode 100644 crypto/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod create mode 100644 crypto/openssl/doc/crypto/X509_STORE_CTX_new.pod create mode 100644 crypto/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod create mode 100644 crypto/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod create mode 100644 crypto/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod create mode 100644 crypto/openssl/doc/crypto/X509_verify_cert.pod create mode 100644 crypto/openssl/doc/crypto/i2d_CMS_bio_stream.pod create mode 100644 crypto/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod create mode 100644 crypto/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod create mode 100644 crypto/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod create mode 100644 crypto/openssl/doc/ssl/SSL_get_psk_identity.pod create mode 100644 crypto/openssl/engines/ccgost/README.gost create mode 100644 crypto/openssl/engines/ccgost/e_gost_err.c create mode 100644 crypto/openssl/engines/ccgost/e_gost_err.h create mode 100644 crypto/openssl/engines/ccgost/gost2001.c create mode 100644 crypto/openssl/engines/ccgost/gost2001_keyx.c create mode 100644 crypto/openssl/engines/ccgost/gost2001_keyx.h create mode 100644 crypto/openssl/engines/ccgost/gost89.c create mode 100644 crypto/openssl/engines/ccgost/gost89.h create mode 100644 crypto/openssl/engines/ccgost/gost94_keyx.c create mode 100644 crypto/openssl/engines/ccgost/gost_ameth.c create mode 100644 crypto/openssl/engines/ccgost/gost_asn1.c create mode 100644 crypto/openssl/engines/ccgost/gost_crypt.c create mode 100644 crypto/openssl/engines/ccgost/gost_ctl.c create mode 100644 crypto/openssl/engines/ccgost/gost_eng.c create mode 100644 crypto/openssl/engines/ccgost/gost_keywrap.c create mode 100644 crypto/openssl/engines/ccgost/gost_keywrap.h create mode 100644 crypto/openssl/engines/ccgost/gost_lcl.h create mode 100644 crypto/openssl/engines/ccgost/gost_md.c create mode 100644 crypto/openssl/engines/ccgost/gost_params.c create mode 100644 crypto/openssl/engines/ccgost/gost_params.h create mode 100644 crypto/openssl/engines/ccgost/gost_pmeth.c create mode 100644 crypto/openssl/engines/ccgost/gost_sign.c create mode 100644 crypto/openssl/engines/ccgost/gosthash.c create mode 100644 crypto/openssl/engines/ccgost/gosthash.h create mode 100644 crypto/openssl/engines/ccgost/gostsum.c create mode 100644 crypto/openssl/engines/e_capi.c create mode 100644 crypto/openssl/engines/e_capi_err.c create mode 100644 crypto/openssl/engines/e_capi_err.h rename crypto/openssl/{crypto/engine/eng_padlock.c => engines/e_padlock.c} (98%) diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES index 97b3810f40..b139cf6244 100644 --- a/crypto/openssl/CHANGES +++ b/crypto/openssl/CHANGES @@ -2,6 +2,879 @@ OpenSSL CHANGES _______________ + Changes between 1.0.0 and 1.0.0a [01 Jun 2010] + + *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover + (CVE-2010-1633) + [Steve Henson, Peter-Michael Hager ] + + Changes between 0.9.8n and 1.0.0 [29 Mar 2010] + + *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher + context. The operation can be customised via the ctrl mechanism in + case ENGINEs want to include additional functionality. + [Steve Henson] + + *) Tolerate yet another broken PKCS#8 key format: private key value negative. + [Steve Henson] + + *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to + output hashes compatible with older versions of OpenSSL. + [Willy Weisz ] + + *) Fix compression algorithm handling: if resuming a session use the + compression algorithm of the resumed session instead of determining + it from client hello again. Don't allow server to change algorithm. + [Steve Henson] + + *) Add load_crls() function to apps tidying load_certs() too. Add option + to verify utility to allow additional CRLs to be included. + [Steve Henson] + + *) Update OCSP request code to permit adding custom headers to the request: + some responders need this. + [Steve Henson] + + *) The function EVP_PKEY_sign() returns <=0 on error: check return code + correctly. + [Julia Lawall ] + + *) Update verify callback code in apps/s_cb.c and apps/verify.c, it + needlessly dereferenced structures, used obsolete functions and + didn't handle all updated verify codes correctly. + [Steve Henson] + + *) Disable MD2 in the default configuration. + [Steve Henson] + + *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to + indicate the initial BIO being pushed or popped. This makes it possible + to determine whether the BIO is the one explicitly called or as a result + of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so + it handles reference counts correctly and doesn't zero out the I/O bio + when it is not being explicitly popped. WARNING: applications which + included workarounds for the old buggy behaviour will need to be modified + or they could free up already freed BIOs. + [Steve Henson] + + *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni + renaming to all platforms (within the 0.9.8 branch, this was + done conditionally on Netware platforms to avoid a name clash). + [Guenter ] + + *) Add ECDHE and PSK support to DTLS. + [Michael Tuexen ] + + *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't + be used on C++. + [Steve Henson] + + *) Add "missing" function EVP_MD_flags() (without this the only way to + retrieve a digest flags is by accessing the structure directly. Update + EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest + or cipher is registered as in the "from" argument. Print out all + registered digests in the dgst usage message instead of manually + attempting to work them out. + [Steve Henson] + + *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello: + this allows the use of compression and extensions. Change default cipher + string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2 + by default unless an application cipher string requests it. + [Steve Henson] + + *) Alter match criteria in PKCS12_parse(). It used to try to use local + key ids to find matching certificates and keys but some PKCS#12 files + don't follow the (somewhat unwritten) rules and this strategy fails. + Now just gather all certificates together and the first private key + then look for the first certificate that matches the key. + [Steve Henson] + + *) Support use of registered digest and cipher names for dgst and cipher + commands instead of having to add each one as a special case. So now + you can do: + + openssl sha256 foo + + as well as: + + openssl dgst -sha256 foo + + and this works for ENGINE based algorithms too. + + [Steve Henson] + + *) Update Gost ENGINE to support parameter files. + [Victor B. Wagner ] + + *) Support GeneralizedTime in ca utility. + [Oliver Martin , Steve Henson] + + *) Enhance the hash format used for certificate directory links. The new + form uses the canonical encoding (meaning equivalent names will work + even if they aren't identical) and uses SHA1 instead of MD5. This form + is incompatible with the older format and as a result c_rehash should + be used to rebuild symbolic links. + [Steve Henson] + + *) Make PKCS#8 the default write format for private keys, replacing the + traditional format. This form is standardised, more secure and doesn't + include an implicit MD5 dependency. + [Steve Henson] + + *) Add a $gcc_devteam_warn option to Configure. The idea is that any code + committed to OpenSSL should pass this lot as a minimum. + [Steve Henson] + + *) Add session ticket override functionality for use by EAP-FAST. + [Jouni Malinen ] + + *) Modify HMAC functions to return a value. Since these can be implemented + in an ENGINE errors can occur. + [Steve Henson] + + *) Type-checked OBJ_bsearch_ex. + [Ben Laurie] + + *) Type-checked OBJ_bsearch. Also some constification necessitated + by type-checking. Still to come: TXT_DB, bsearch(?), + OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING, + CONF_VALUE. + [Ben Laurie] + + *) New function OPENSSL_gmtime_adj() to add a specific number of days and + seconds to a tm structure directly, instead of going through OS + specific date routines. This avoids any issues with OS routines such + as the year 2038 bug. New *_adj() functions for ASN1 time structures + and X509_time_adj_ex() to cover the extended range. The existing + X509_time_adj() is still usable and will no longer have any date issues. + [Steve Henson] + + *) Delta CRL support. New use deltas option which will attempt to locate + and search any appropriate delta CRLs available. + + This work was sponsored by Google. + [Steve Henson] + + *) Support for CRLs partitioned by reason code. Reorganise CRL processing + code and add additional score elements. Validate alternate CRL paths + as part of the CRL checking and indicate a new error "CRL path validation + error" in this case. Applications wanting additional details can use + the verify callback and check the new "parent" field. If this is not + NULL CRL path validation is taking place. Existing applications wont + see this because it requires extended CRL support which is off by + default. + + This work was sponsored by Google. + [Steve Henson] + + *) Support for freshest CRL extension. + + This work was sponsored by Google. + [Steve Henson] + + *) Initial indirect CRL support. Currently only supported in the CRLs + passed directly and not via lookup. Process certificate issuer + CRL entry extension and lookup CRL entries by bother issuer name + and serial number. Check and process CRL issuer entry in IDP extension. + + This work was sponsored by Google. + [Steve Henson] + + *) Add support for distinct certificate and CRL paths. The CRL issuer + certificate is validated separately in this case. Only enabled if + an extended CRL support flag is set: this flag will enable additional + CRL functionality in future. + + This work was sponsored by Google. + [Steve Henson] + + *) Add support for policy mappings extension. + + This work was sponsored by Google. + [Steve Henson] + + *) Fixes to pathlength constraint, self issued certificate handling, + policy processing to align with RFC3280 and PKITS tests. + + This work was sponsored by Google. + [Steve Henson] + + *) Support for name constraints certificate extension. DN, email, DNS + and URI types are currently supported. + + This work was sponsored by Google. + [Steve Henson] + + *) To cater for systems that provide a pointer-based thread ID rather + than numeric, deprecate the current numeric thread ID mechanism and + replace it with a structure and associated callback type. This + mechanism allows a numeric "hash" to be extracted from a thread ID in + either case, and on platforms where pointers are larger than 'long', + mixing is done to help ensure the numeric 'hash' is usable even if it + can't be guaranteed unique. The default mechanism is to use "&errno" + as a pointer-based thread ID to distinguish between threads. + + Applications that want to provide their own thread IDs should now use + CRYPTO_THREADID_set_callback() to register a callback that will call + either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer(). + + Note that ERR_remove_state() is now deprecated, because it is tied + to the assumption that thread IDs are numeric. ERR_remove_state(0) + to free the current thread's error state should be replaced by + ERR_remove_thread_state(NULL). + + (This new approach replaces the functions CRYPTO_set_idptr_callback(), + CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in + OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an + application was previously providing a numeric thread callback that + was inappropriate for distinguishing threads, then uniqueness might + have been obtained with &errno that happened immediately in the + intermediate development versions of OpenSSL; this is no longer the + case, the numeric thread callback will now override the automatic use + of &errno.) + [Geoff Thorpe, with help from Bodo Moeller] + + *) Initial support for different CRL issuing certificates. This covers a + simple case where the self issued certificates in the chain exist and + the real CRL issuer is higher in the existing chain. + + This work was sponsored by Google. + [Steve Henson] + + *) Removed effectively defunct crypto/store from the build. + [Ben Laurie] + + *) Revamp of STACK to provide stronger type-checking. Still to come: + TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE, + ASN1_STRING, CONF_VALUE. + [Ben Laurie] + + *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer + RAM on SSL connections. This option can save about 34k per idle SSL. + [Nick Mathewson] + + *) Revamp of LHASH to provide stronger type-checking. Still to come: + STACK, TXT_DB, bsearch, qsort. + [Ben Laurie] + + *) Initial support for Cryptographic Message Syntax (aka CMS) based + on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility, + support for data, signedData, compressedData, digestedData and + encryptedData, envelopedData types included. Scripts to check against + RFC4134 examples draft and interop and consistency checks of many + content types and variants. + [Steve Henson] + + *) Add options to enc utility to support use of zlib compression BIO. + [Steve Henson] + + *) Extend mk1mf to support importing of options and assembly language + files from Configure script, currently only included in VC-WIN32. + The assembly language rules can now optionally generate the source + files from the associated perl scripts. + [Steve Henson] + + *) Implement remaining functionality needed to support GOST ciphersuites. + Interop testing has been performed using CryptoPro implementations. + [Victor B. Wagner ] + + *) s390x assembler pack. + [Andy Polyakov] + + *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU + "family." + [Andy Polyakov] + + *) Implement Opaque PRF Input TLS extension as specified in + draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an + official specification yet and no extension type assignment by + IANA exists, this extension (for now) will have to be explicitly + enabled when building OpenSSL by providing the extension number + to use. For example, specify an option + + -DTLSEXT_TYPE_opaque_prf_input=0x9527 + + to the "config" or "Configure" script to enable the extension, + assuming extension number 0x9527 (which is a completely arbitrary + and unofficial assignment based on the MD5 hash of the Internet + Draft). Note that by doing so, you potentially lose + interoperability with other TLS implementations since these might + be using the same extension number for other purposes. + + SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the + opaque PRF input value to use in the handshake. This will create + an interal copy of the length-'len' string at 'src', and will + return non-zero for success. + + To get more control and flexibility, provide a callback function + by using + + SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) + + where + + int (*cb)(SSL *, void *peerinput, size_t len, void *arg); + void *arg; + + Callback function 'cb' will be called in handshakes, and is + expected to use SSL_set_tlsext_opaque_prf_input() as appropriate. + Argument 'arg' is for application purposes (the value as given to + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly + be provided to the callback function). The callback function + has to return non-zero to report success: usually 1 to use opaque + PRF input just if possible, or 2 to enforce use of the opaque PRF + input. In the latter case, the library will abort the handshake + if opaque PRF input is not successfully negotiated. + + Arguments 'peerinput' and 'len' given to the callback function + will always be NULL and 0 in the case of a client. A server will + see the client's opaque PRF input through these variables if + available (NULL and 0 otherwise). Note that if the server + provides an opaque PRF input, the length must be the same as the + length of the client's opaque PRF input. + + Note that the callback function will only be called when creating + a new session (session resumption can resume whatever was + previously negotiated), and will not be called in SSL 2.0 + handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or + SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended + for applications that need to enforce opaque PRF input. + + [Bodo Moeller] + + *) Update ssl code to support digests other than SHA1+MD5 for handshake + MAC. + + [Victor B. Wagner ] + + *) Add RFC4507 support to OpenSSL. This includes the corrections in + RFC4507bis. The encrypted ticket format is an encrypted encoded + SSL_SESSION structure, that way new session features are automatically + supported. + + If a client application caches session in an SSL_SESSION structure + support is transparent because tickets are now stored in the encoded + SSL_SESSION. + + The SSL_CTX structure automatically generates keys for ticket + protection in servers so again support should be possible + with no application modification. + + If a client or server wishes to disable RFC4507 support then the option + SSL_OP_NO_TICKET can be set. + + Add a TLS extension debugging callback to allow the contents of any client + or server extensions to be examined. + + This work was sponsored by Google. + [Steve Henson] + + *) Final changes to avoid use of pointer pointer casts in OpenSSL. + OpenSSL should now compile cleanly on gcc 4.2 + [Peter Hartley , Steve Henson] + + *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC + support including streaming MAC support: this is required for GOST + ciphersuite support. + [Victor B. Wagner , Steve Henson] + + *) Add option -stream to use PKCS#7 streaming in smime utility. New + function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream() + to output in BER and PEM format. + [Steve Henson] + + *) Experimental support for use of HMAC via EVP_PKEY interface. This + allows HMAC to be handled via the EVP_DigestSign*() interface. The + EVP_PKEY "key" in this case is the HMAC key, potentially allowing + ENGINE support for HMAC keys which are unextractable. New -mac and + -macopt options to dgst utility. + [Steve Henson] + + *) New option -sigopt to dgst utility. Update dgst to use + EVP_Digest{Sign,Verify}*. These two changes make it possible to use + alternative signing paramaters such as X9.31 or PSS in the dgst + utility. + [Steve Henson] + + *) Change ssl_cipher_apply_rule(), the internal function that does + the work each time a ciphersuite string requests enabling + ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or + removing ("!foo+bar") a class of ciphersuites: Now it maintains + the order of disabled ciphersuites such that those ciphersuites + that most recently went from enabled to disabled not only stay + in order with respect to each other, but also have higher priority + than other disabled ciphersuites the next time ciphersuites are + enabled again. + + This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable + the same ciphersuites as with "HIGH" alone, but in a specific + order where the PSK ciphersuites come first (since they are the + most recently disabled ciphersuites when "HIGH" is parsed). + + Also, change ssl_create_cipher_list() (using this new + funcionality) such that between otherwise identical + cihpersuites, ephemeral ECDH is preferred over ephemeral DH in + the default order. + [Bodo Moeller] + + *) Change ssl_create_cipher_list() so that it automatically + arranges the ciphersuites in reasonable order before starting + to process the rule string. Thus, the definition for "DEFAULT" + (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but + remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH". + This makes it much easier to arrive at a reasonable default order + in applications for which anonymous ciphers are OK (meaning + that you can't actually use DEFAULT). + [Bodo Moeller; suggested by Victor Duchovni] + + *) Split the SSL/TLS algorithm mask (as used for ciphersuite string + processing) into multiple integers instead of setting + "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK", + "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer. + (These masks as well as the individual bit definitions are hidden + away into the non-exported interface ssl/ssl_locl.h, so this + change to the definition of the SSL_CIPHER structure shouldn't + affect applications.) This give us more bits for each of these + categories, so there is no longer a need to coagulate AES128 and + AES256 into a single algorithm bit, and to coagulate Camellia128 + and Camellia256 into a single algorithm bit, which has led to all + kinds of kludges. + + Thus, among other things, the kludge introduced in 0.9.7m and + 0.9.8e for masking out AES256 independently of AES128 or masking + out Camellia256 independently of AES256 is not needed here in 0.9.9. + + With the change, we also introduce new ciphersuite aliases that + so far were missing: "AES128", "AES256", "CAMELLIA128", and + "CAMELLIA256". + [Bodo Moeller] + + *) Add support for dsa-with-SHA224 and dsa-with-SHA256. + Use the leftmost N bytes of the signature input if the input is + larger than the prime q (with N being the size in bytes of q). + [Nils Larsch] + + *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses + it yet and it is largely untested. + [Steve Henson] + + *) Add support for the ecdsa-with-SHA224/256/384/512 signature types. + [Nils Larsch] + + *) Initial incomplete changes to avoid need for function casts in OpenSSL + some compilers (gcc 4.2 and later) reject their use. Safestack is + reimplemented. Update ASN1 to avoid use of legacy functions. + [Steve Henson] + + *) Win32/64 targets are linked with Winsock2. + [Andy Polyakov] + + *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected + to external functions. This can be used to increase CRL handling + efficiency especially when CRLs are very large by (for example) storing + the CRL revoked certificates in a database. + [Steve Henson] + + *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so + new CRLs added to a directory can be used. New command line option + -verify_return_error to s_client and s_server. This causes real errors + to be returned by the verify callback instead of carrying on no matter + what. This reflects the way a "real world" verify callback would behave. + [Steve Henson] + + *) GOST engine, supporting several GOST algorithms and public key formats. + Kindly donated by Cryptocom. + [Cryptocom] + + *) Partial support for Issuing Distribution Point CRL extension. CRLs + partitioned by DP are handled but no indirect CRL or reason partitioning + (yet). Complete overhaul of CRL handling: now the most suitable CRL is + selected via a scoring technique which handles IDP and AKID in CRLs. + [Steve Henson] + + *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which + will ultimately be used for all verify operations: this will remove the + X509_STORE dependency on certificate verification and allow alternative + lookup methods. X509_STORE based implementations of these two callbacks. + [Steve Henson] + + *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names. + Modify get_crl() to find a valid (unexpired) CRL if possible. + [Steve Henson] + + *) New function X509_CRL_match() to check if two CRLs are identical. Normally + this would be called X509_CRL_cmp() but that name is already used by + a function that just compares CRL issuer names. Cache several CRL + extensions in X509_CRL structure and cache CRLDP in X509. + [Steve Henson] + + *) Store a "canonical" representation of X509_NAME structure (ASN1 Name) + this maps equivalent X509_NAME structures into a consistent structure. + Name comparison can then be performed rapidly using memcmp(). + [Steve Henson] + + *) Non-blocking OCSP request processing. Add -timeout option to ocsp + utility. + [Steve Henson] + + *) Allow digests to supply their own micalg string for S/MIME type using + the ctrl EVP_MD_CTRL_MICALG. + [Steve Henson] + + *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the + EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN + ctrl. It can then customise the structure before and/or after signing + if necessary. + [Steve Henson] + + *) New function OBJ_add_sigid() to allow application defined signature OIDs + to be added to OpenSSLs internal tables. New function OBJ_sigid_free() + to free up any added signature OIDs. + [Steve Henson] + + *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(), + EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal + digest and cipher tables. New options added to openssl utility: + list-message-digest-algorithms and list-cipher-algorithms. + [Steve Henson] + + *) Change the array representation of binary polynomials: the list + of degrees of non-zero coefficients is now terminated with -1. + Previously it was terminated with 0, which was also part of the + value; thus, the array representation was not applicable to + polynomials where t^0 has coefficient zero. This change makes + the array representation useful in a more general context. + [Douglas Stebila] + + *) Various modifications and fixes to SSL/TLS cipher string + handling. For ECC, the code now distinguishes between fixed ECDH + with RSA certificates on the one hand and with ECDSA certificates + on the other hand, since these are separate ciphersuites. The + unused code for Fortezza ciphersuites has been removed. + + For consistency with EDH, ephemeral ECDH is now called "EECDH" + (not "ECDHE"). For consistency with the code for DH + certificates, use of ECDH certificates is now considered ECDH + authentication, not RSA or ECDSA authentication (the latter is + merely the CA's signing algorithm and not actively used in the + protocol). + + The temporary ciphersuite alias "ECCdraft" is no longer + available, and ECC ciphersuites are no longer excluded from "ALL" + and "DEFAULT". The following aliases now exist for RFC 4492 + ciphersuites, most of these by analogy with the DH case: + + kECDHr - ECDH cert, signed with RSA + kECDHe - ECDH cert, signed with ECDSA + kECDH - ECDH cert (signed with either RSA or ECDSA) + kEECDH - ephemeral ECDH + ECDH - ECDH cert or ephemeral ECDH + + aECDH - ECDH cert + aECDSA - ECDSA cert + ECDSA - ECDSA cert + + AECDH - anonymous ECDH + EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH") + + [Bodo Moeller] + + *) Add additional S/MIME capabilities for AES and GOST ciphers if supported. + Use correct micalg parameters depending on digest(s) in signed message. + [Steve Henson] + + *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process + an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code. + [Steve Henson] + + *) Initial engine support for EVP_PKEY_METHOD. New functions to permit + an engine to register a method. Add ENGINE lookups for methods and + functional reference processing. + [Steve Henson] + + *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of + EVP_{Sign,Verify}* which allow an application to customise the signature + process. + [Steve Henson] + + *) New -resign option to smime utility. This adds one or more signers + to an existing PKCS#7 signedData structure. Also -md option to use an + alternative message digest algorithm for signing. + [Steve Henson] + + *) Tidy up PKCS#7 routines and add new functions to make it easier to + create PKCS7 structures containing multiple signers. Update smime + application to support multiple signers. + [Steve Henson] + + *) New -macalg option to pkcs12 utility to allow setting of an alternative + digest MAC. + [Steve Henson] + + *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC. + Reorganize PBE internals to lookup from a static table using NIDs, + add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl: + EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative + PRF which will be automatically used with PBES2. + [Steve Henson] + + *) Replace the algorithm specific calls to generate keys in "req" with the + new API. + [Steve Henson] + + *) Update PKCS#7 enveloped data routines to use new API. This is now + supported by any public key method supporting the encrypt operation. A + ctrl is added to allow the public key algorithm to examine or modify + the PKCS#7 RecipientInfo structure if it needs to: for RSA this is + a no op. + [Steve Henson] + + *) Add a ctrl to asn1 method to allow a public key algorithm to express + a default digest type to use. In most cases this will be SHA1 but some + algorithms (such as GOST) need to specify an alternative digest. The + return value indicates how strong the prefernce is 1 means optional and + 2 is mandatory (that is it is the only supported type). Modify + ASN1_item_sign() to accept a NULL digest argument to indicate it should + use the default md. Update openssl utilities to use the default digest + type for signing if it is not explicitly indicated. + [Steve Henson] + + *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New + EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant + signing method from the key type. This effectively removes the link + between digests and public key types. + [Steve Henson] + + *) Add an OID cross reference table and utility functions. Its purpose is to + translate between signature OIDs such as SHA1WithrsaEncryption and SHA1, + rsaEncryption. This will allow some of the algorithm specific hackery + needed to use the correct OID to be removed. + [Steve Henson] + + *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO + structures for PKCS7_sign(). They are now set up by the relevant public + key ASN1 method. + [Steve Henson] + + *) Add provisional EC pkey method with support for ECDSA and ECDH. + [Steve Henson] + + *) Add support for key derivation (agreement) in the API, DH method and + pkeyutl. + [Steve Henson] + + *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support + public and private key formats. As a side effect these add additional + command line functionality not previously available: DSA signatures can be + generated and verified using pkeyutl and DH key support and generation in + pkey, genpkey. + [Steve Henson] + + *) BeOS support. + [Oliver Tappe ] + + *) New make target "install_html_docs" installs HTML renditions of the + manual pages. + [Oliver Tappe ] + + *) New utility "genpkey" this is analagous to "genrsa" etc except it can + generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to + support key and parameter generation and add initial key generation + functionality for RSA. + [Steve Henson] + + *) Add functions for main EVP_PKEY_method operations. The undocumented + functions EVP_PKEY_{encrypt,decrypt} have been renamed to + EVP_PKEY_{encrypt,decrypt}_old. + [Steve Henson] + + *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public + key API, doesn't do much yet. + [Steve Henson] + + *) New function EVP_PKEY_asn1_get0_info() to retrieve information about + public key algorithms. New option to openssl utility: + "list-public-key-algorithms" to print out info. + [Steve Henson] + + *) Implement the Supported Elliptic Curves Extension for + ECC ciphersuites from draft-ietf-tls-ecc-12.txt. + [Douglas Stebila] + + *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or + EVP_CIPHER structures to avoid later problems in EVP_cleanup(). + [Steve Henson] + + *) New utilities pkey and pkeyparam. These are similar to algorithm specific + utilities such as rsa, dsa, dsaparam etc except they process any key + type. + [Steve Henson] + + *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New + functions EVP_PKEY_print_public(), EVP_PKEY_print_private(), + EVP_PKEY_print_param() to print public key data from an EVP_PKEY + structure. + [Steve Henson] + + *) Initial support for pluggable public key ASN1. + De-spaghettify the public key ASN1 handling. Move public and private + key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate + algorithm specific handling to a single module within the relevant + algorithm directory. Add functions to allow (near) opaque processing + of public and private key structures. + [Steve Henson] + + *) Implement the Supported Point Formats Extension for + ECC ciphersuites from draft-ietf-tls-ecc-12.txt. + [Douglas Stebila] + + *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members + for the psk identity [hint] and the psk callback functions to the + SSL_SESSION, SSL and SSL_CTX structure. + + New ciphersuites: + PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA, + PSK-AES256-CBC-SHA + + New functions: + SSL_CTX_use_psk_identity_hint + SSL_get_psk_identity_hint + SSL_get_psk_identity + SSL_use_psk_identity_hint + + [Mika Kousa and Pasi Eronen of Nokia Corporation] + + *) Add RFC 3161 compliant time stamp request creation, response generation + and response verification functionality. + [Zoltán Glózik , The OpenTSA Project] + + *) Add initial support for TLS extensions, specifically for the server_name + extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now + have new members for a host name. The SSL data structure has an + additional member SSL_CTX *initial_ctx so that new sessions can be + stored in that context to allow for session resumption, even after the + SSL has been switched to a new SSL_CTX in reaction to a client's + server_name extension. + + New functions (subject to change): + + SSL_get_servername() + SSL_get_servername_type() + SSL_set_SSL_CTX() + + New CTRL codes and macros (subject to change): + + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + - SSL_CTX_set_tlsext_servername_callback() + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG + - SSL_CTX_set_tlsext_servername_arg() + SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() + + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecogninzed_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. + + [Peter Sylvester, Remy Allais, Christophe Renou] + + *) Whirlpool hash implementation is added. + [Andy Polyakov] + + *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to + bn(64,32). Because of instruction set limitations it doesn't have + any negative impact on performance. This was done mostly in order + to make it possible to share assembler modules, such as bn_mul_mont + implementations, between 32- and 64-bit builds without hassle. + [Andy Polyakov] + + *) Move code previously exiled into file crypto/ec/ec2_smpt.c + to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP + macro. + [Bodo Moeller] + + *) New candidate for BIGNUM assembler implementation, bn_mul_mont, + dedicated Montgomery multiplication procedure, is introduced. + BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher + "64-bit" performance on certain 32-bit targets. + [Andy Polyakov] + + *) New option SSL_OP_NO_COMP to disable use of compression selectively + in SSL structures. New SSL ctrl to set maximum send fragment size. + Save memory by seeting the I/O buffer sizes dynamically instead of + using the maximum available value. + [Steve Henson] + + *) New option -V for 'openssl ciphers'. This prints the ciphersuite code + in addition to the text details. + [Bodo Moeller] + + *) Very, very preliminary EXPERIMENTAL support for printing of general + ASN1 structures. This currently produces rather ugly output and doesn't + handle several customised structures at all. + [Steve Henson] + + *) Integrated support for PVK file format and some related formats such + as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support + these in the 'rsa' and 'dsa' utilities. + [Steve Henson] + + *) Support for PKCS#1 RSAPublicKey format on rsa utility command line. + [Steve Henson] + + *) Remove the ancient ASN1_METHOD code. This was only ever used in one + place for the (very old) "NETSCAPE" format certificates which are now + handled using new ASN1 code equivalents. + [Steve Henson] + + *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD + pointer and make the SSL_METHOD parameter in SSL_CTX_new, + SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'. + [Nils Larsch] + + *) Modify CRL distribution points extension code to print out previously + unsupported fields. Enhance extension setting code to allow setting of + all fields. + [Steve Henson] + + *) Add print and set support for Issuing Distribution Point CRL extension. + [Steve Henson] + + *) Change 'Configure' script to enable Camellia by default. + [NTT] + + Changes between 0.9.8n and 0.9.8o [xx XXX xxxx] + + *) Correct a typo in the CMS ASN1 module which can result in invalid memory + access or freeing data twice (CVE-2010-0742) + [Steve Henson, Ronald Moesbergen ] + + *) Add SHA2 algorithms to SSL_library_init(). SHA2 is becoming far more + common in certificates and some applications which only call + SSL_library_init and not OpenSSL_add_all_algorithms() will fail. + [Steve Henson] + + Changes between 0.9.8m and 0.9.8n [24 Mar 2010] + + *) When rejecting SSL/TLS records due to an incorrect version number, never + update s->server with a new major version number. As of + - OpenSSL 0.9.8m if 'short' is a 16-bit type, + - OpenSSL 0.9.8f if 'short' is longer than 16 bits, + the previous behavior could result in a read attempt at NULL when + receiving specific incorrect SSL/TLS records once record payload + protection is active. (CVE-2010-####) + [Bodo Moeller, Adam Langley] + + *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL + could be crashed if the relevant tables were not present (e.g. chrooted). + [Tomas Hoger ] + Changes between 0.9.8l and 0.9.8m [25 Feb 2010] *) Always check bn_wexpend() return values for failure. (CVE-2009-3245) diff --git a/crypto/openssl/FAQ b/crypto/openssl/FAQ index 8041479c7e..becee6663f 100644 --- a/crypto/openssl/FAQ +++ b/crypto/openssl/FAQ @@ -70,6 +70,7 @@ OpenSSL - Frequently Asked Questions * I think I've detected a memory leak, is this a bug? * Why does Valgrind complain about the use of uninitialized data? * Why doesn't a memory BIO work when a file does? +* Where are the declarations and implementations of d2i_X509() etc? =============================================================================== @@ -78,7 +79,7 @@ OpenSSL - Frequently Asked Questions * Which is the current version of OpenSSL? The current version is available from . -OpenSSL 0.9.8m was released on Feb 25th, 2010. +OpenSSL 1.0.0a was released on Jun 1st, 2010. In addition to the current stable release, you can also access daily snapshots of the OpenSSL development version at . +. Note that the online documents refer +to the very latest development versions of OpenSSL and may include features +not present in released versions. If in doubt refer to the documentation +that came with the version of OpenSSL you are using. For information on parts of libcrypto that are not yet documented, you might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's @@ -717,8 +721,10 @@ file. Multi-threaded applications must provide two callback functions to OpenSSL by calling CRYPTO_set_locking_callback() and -CRYPTO_set_id_callback(). This is described in the threads(3) -manpage. +CRYPTO_set_id_callback(), for all versions of OpenSSL up to and +including 0.9.8[abc...]. As of version 1.0.0, CRYPTO_set_id_callback() +and associated APIs are deprecated by CRYPTO_THREADID_set_callback() +and friends. This is described in the threads(3) manpage. * I've compiled a program under Windows and it crashes: why? @@ -962,4 +968,15 @@ is needed. This must be done by calling: See the manual pages for more details. +* Where are the declarations and implementations of d2i_X509() etc? + +These are defined and implemented by macros of the form: + + + DECLARE_ASN1_FUNCTIONS(X509) and IMPLEMENT_ASN1_FUNCTIONS(X509) + +The implementation passes an ASN1 "template" defining the structure into an +ASN1 interpreter using generalised functions such as ASN1_item_d2i(). + + =============================================================================== diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS index 7bff9591d4..3a787ea06c 100644 --- a/crypto/openssl/NEWS +++ b/crypto/openssl/NEWS @@ -5,6 +5,47 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a: + + o Fix for security issue CVE-2010-1633. + o GOST MAC and CFB fixes. + + Major changes between OpenSSL 0.9.8n and OpenSSL 1.0: + + o RFC3280 path validation: sufficient to process PKITS tests. + o Integrated support for PVK files and keyblobs. + o Change default private key format to PKCS#8. + o CMS support: able to process all examples in RFC4134 + o Streaming ASN1 encode support for PKCS#7 and CMS. + o Multiple signer and signer add support for PKCS#7 and CMS. + o ASN1 printing support. + o Whirlpool hash algorithm added. + o RFC3161 time stamp support. + o New generalised public key API supporting ENGINE based algorithms. + o New generalised public key API utilities. + o New ENGINE supporting GOST algorithms. + o SSL/TLS GOST ciphersuite support. + o PKCS#7 and CMS GOST support. + o RFC4279 PSK ciphersuite support. + o Supported points format extension for ECC ciphersuites. + o ecdsa-with-SHA224/256/384/512 signature types. + o dsa-with-SHA224 and dsa-with-SHA256 signature types. + o Opaque PRF Input TLS extension support. + o Updated time routines to avoid OS limitations. + + Major changes between OpenSSL 0.9.8n and OpenSSL 0.9.8o: + + o Fix for security issue CVE-2010-0742. + o Various DTLS fixes. + o Recognise SHA2 certificates if only SSL algorithms added. + o Fix for no-rc4 compilation. + o Chil ENGINE unload workaround. + + Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n: + + o CFB cipher definition fixes. + o Fix security issues CVE-2010-0740 and CVE-2010-0433. + Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m: o Cipher definition fixes. @@ -159,6 +200,11 @@ o Added initial support for Win64. o Added alternate pkg-config files. + Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m: + + o FIPS 1.1.1 module linking. + o Various ciphersuite selection fixes. + Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l: o Introduce limits to prevent malicious key DoS (CVE-2006-2940) diff --git a/crypto/openssl/README b/crypto/openssl/README index 0cfba9c6c3..c1d0a5fd52 100644 --- a/crypto/openssl/README +++ b/crypto/openssl/README @@ -1,7 +1,7 @@ - OpenSSL 0.9.8m + OpenSSL 1.0.0a 1 Jun 2010 - Copyright (c) 1998-2009 The OpenSSL Project + Copyright (c) 1998-2010 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson All rights reserved. diff --git a/crypto/openssl/README.DELETED b/crypto/openssl/README.DELETED index abb49044b5..195de41ce9 100644 --- a/crypto/openssl/README.DELETED +++ b/crypto/openssl/README.DELETED @@ -54,6 +54,7 @@ apps/server.srl apps/server2.pem apps/set/ apps/testCA.pem +apps/tsget apps/winrand.c bugs/ certs/ @@ -65,11 +66,10 @@ crypto/LPdir_win32.c crypto/LPdir_wince.c crypto/Makefile crypto/aes/Makefile +crypto/aes/aes_x86core.c crypto/aes/asm/ crypto/asn1/Makefile crypto/asn1/charmap.pl -crypto/asn1/p8_key.c -crypto/asn1/tasn_prn.c crypto/bf/INSTALL crypto/bf/Makefile crypto/bf/asm/ @@ -93,6 +93,7 @@ crypto/bn/exptest.c crypto/bn/vms-helper.c crypto/buffer/Makefile crypto/camellia/Makefile +crypto/camellia/asm/ crypto/cast/Makefile crypto/cast/asm/ crypto/cast/cast_spd.c @@ -146,6 +147,7 @@ crypto/dsa/Makefile crypto/dsa/dsagen.c crypto/dsa/dsatest.c crypto/dso/Makefile +crypto/dso/dso_beos.c crypto/dso/dso_vms.c crypto/dso/dso_win32.c crypto/ec/Makefile @@ -161,7 +163,6 @@ crypto/err/openssl.ec crypto/evp/Makefile crypto/evp/e_dsa.c crypto/evp/e_old.c -crypto/evp/e_seed.c crypto/evp/evp_test.c crypto/evp/evptests.txt crypto/hmac/Makefile @@ -172,13 +173,11 @@ crypto/idea/idea_spd.c crypto/idea/ideatest.c crypto/install.com crypto/jpake/ -crypto/krb5/Makefile +crypto/krb5/ crypto/lhash/Makefile crypto/lhash/lh_test.c crypto/lhash/num.pl -crypto/md2/Makefile -crypto/md2/md2.c -crypto/md2/md2test.c +crypto/md2/ crypto/md4/Makefile crypto/md4/md4.c crypto/md4/md4s.cpp @@ -190,14 +189,17 @@ crypto/md5/md5s.cpp crypto/md5/md5test.c crypto/mdc2/Makefile crypto/mdc2/mdc2test.c +crypto/modes/Makefile crypto/o_dir_test.c crypto/o_str.c crypto/o_str.h crypto/objects/Makefile crypto/objects/obj_dat.pl crypto/objects/obj_mac.num +crypto/objects/obj_xref.txt crypto/objects/objects.pl crypto/objects/objects.txt +crypto/objects/objxref.pl crypto/ocsp/Makefile crypto/opensslconf.h crypto/opensslconf.h.in @@ -220,6 +222,7 @@ crypto/pkcs7/server.pem crypto/pkcs7/sign.c crypto/pkcs7/t/ crypto/pkcs7/verify.c +crypto/ppccpuid.pl crypto/pqueue/Makefile crypto/rand/Makefile crypto/rand/rand_os2.c @@ -238,30 +241,28 @@ crypto/rc4/rc4s.cpp crypto/rc4/rc4speed.c crypto/rc4/rc4test.c crypto/rc4/rrc4.doc -crypto/rc5/Makefile -crypto/rc5/asm/ -crypto/rc5/rc5s.cpp -crypto/rc5/rc5speed.c -crypto/rc5/rc5test.c +crypto/rc5/ crypto/ripemd/Makefile crypto/ripemd/asm/ crypto/ripemd/rmd160.c crypto/ripemd/rmdtest.c crypto/rsa/Makefile crypto/rsa/rsa_test.c -crypto/seed/ +crypto/s390xcap.c +crypto/s390xcpuid.S +crypto/seed/Makefile crypto/sha/Makefile crypto/sha/asm/ crypto/sha/sha.c crypto/sha/sha1.c -crypto/sha/sha1s.cpp crypto/sha/sha1test.c crypto/sha/sha256t.c crypto/sha/sha512t.c crypto/sha/shatest.c crypto/sparccpuid.S +crypto/sparcv9cap.c crypto/stack/Makefile -crypto/store/Makefile +crypto/store/ crypto/threads/mttest.c crypto/threads/netware.bat crypto/threads/profile.sh @@ -272,8 +273,12 @@ crypto/threads/pthreads-vms.com crypto/threads/purify.sh crypto/threads/solaris.sh crypto/threads/win32.bat +crypto/ts/Makefile crypto/txt_db/Makefile crypto/ui/Makefile +crypto/whrlpool/Makefile +crypto/whrlpool/asm/ +crypto/whrlpool/wp_test.c crypto/x509/Makefile crypto/x509v3/Makefile crypto/x509v3/tabtest.c @@ -294,24 +299,26 @@ doc/ssleay.txt doc/standards.txt engines/Makefile engines/alpha.opt +engines/axp.opt +engines/capierr.bat +engines/ccgost/Makefile +engines/ccgost/e_gost_err.proto +engines/ccgost/gost.ec engines/e_4758cca.ec engines/e_aep.ec engines/e_atalla.ec -engines/e_capi.c engines/e_capi.ec -engines/e_capi_err.c -engines/e_capi_err.h engines/e_chil.ec engines/e_cswift.ec engines/e_gmp.ec engines/e_nuron.ec +engines/e_padlock.ec engines/e_sureware.ec engines/e_ubsec.ec engines/engine_vector.mar engines/ia64.opt engines/makeengines.com engines/vax.opt -fips/ include/ install.com makevms.com @@ -331,19 +338,18 @@ times/ tools/ util/FreeBSD.sh util/add_cr.pl -util/arx.pl util/bat.sh util/ck_errf.pl util/clean-depend.pl util/copy.pl util/cygwin.sh util/deleof.pl +util/deltree.com util/dirname.pl util/do_ms.sh util/domd util/err-ins.pl util/files.pl -util/fipslink.pl util/fixNT.sh util/install.sh util/libeay.num @@ -354,7 +360,7 @@ util/mkdir-p.pl util/mkerr.pl util/mkfiles.pl util/mklink.pl -util/mksdef.pl +util/mkrc.pl util/mkstack.pl util/opensslwrap.sh util/perlpath.pl diff --git a/crypto/openssl/apps/apps.c b/crypto/openssl/apps/apps.c index 35b62b8b09..acc50df04e 100644 --- a/crypto/openssl/apps/apps.c +++ b/crypto/openssl/apps/apps.c @@ -109,12 +109,21 @@ * */ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 2 /* On VMS, you need to define this to get + the declaration of fileno(). The value + 2 is to make sure no function defined + in POSIX-2 is left undefined. */ +#endif #include #include #include +#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB) +#include +#endif #include -#include #include +#include #include #include #include @@ -138,6 +147,11 @@ #include "apps.h" #undef NON_MAIN +#ifdef _WIN32 +static int WIN32_rename(const char *from, const char *to); +#define rename(from,to) WIN32_rename((from),(to)) +#endif + typedef struct { const char *name; unsigned long flag; @@ -166,18 +180,23 @@ int args_from_file(char *file, int *argc, char **argv[]) static char *buf=NULL; static char **arg=NULL; char *p; - struct stat stbuf; - - if (stat(file,&stbuf) < 0) return(0); fp=fopen(file,"r"); if (fp == NULL) return(0); + if (fseek(fp,0,SEEK_END)==0) + len=ftell(fp), rewind(fp); + else len=-1; + if (len<=0) + { + fclose(fp); + return(0); + } + *argc=0; *argv=NULL; - len=(unsigned int)stbuf.st_size; if (buf != NULL) OPENSSL_free(buf); buf=(char *)OPENSSL_malloc(len+1); if (buf == NULL) return(0); @@ -242,18 +261,25 @@ int str2fmt(char *s) return(FORMAT_ASN1); else if ((*s == 'T') || (*s == 't')) return(FORMAT_TEXT); - else if ((*s == 'P') || (*s == 'p')) - return(FORMAT_PEM); - else if ((*s == 'N') || (*s == 'n')) - return(FORMAT_NETSCAPE); - else if ((*s == 'S') || (*s == 's')) - return(FORMAT_SMIME); + else if ((*s == 'N') || (*s == 'n')) + return(FORMAT_NETSCAPE); + else if ((*s == 'S') || (*s == 's')) + return(FORMAT_SMIME); + else if ((*s == 'M') || (*s == 'm')) + return(FORMAT_MSBLOB); else if ((*s == '1') || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0) || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0)) return(FORMAT_PKCS12); else if ((*s == 'E') || (*s == 'e')) return(FORMAT_ENGINE); + else if ((*s == 'P') || (*s == 'p')) + { + if (s[1] == 'V' || s[1] == 'v') + return FORMAT_PVK; + else + return(FORMAT_PEM); + } else return(FORMAT_UNDEF); } @@ -639,6 +665,15 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) BIO_printf(err, "Can't open file %s\n", arg + 5); return NULL; } +#if !defined(_WIN32) + /* + * Under _WIN32, which covers even Win64 and CE, file + * descriptors referenced by BIO_s_fd are not inherited + * by child process and therefore below is not an option. + * It could have been an option if bss_fd.c was operating + * on real Windows descriptors, such as those obtained + * with CreateFile. + */ } else if(!strncmp(arg, "fd:", 3)) { BIO *btmp; i = atoi(arg + 3); @@ -650,6 +685,7 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) /* Can't do BIO_gets on an fd BIO so add a buffering BIO */ btmp = BIO_new(BIO_f_buffer()); pwdbio = BIO_push(btmp, pwdbio); +#endif } else if(!strcmp(arg, "stdin")) { pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); if(!pwdbio) { @@ -749,8 +785,6 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc, X509 *load_cert(BIO *err, const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip) { - ASN1_HEADER *ah=NULL; - BUF_MEM *buf=NULL; X509 *x=NULL; BIO *cert; @@ -762,7 +796,9 @@ X509 *load_cert(BIO *err, const char *file, int format, if (file == NULL) { +#ifdef _IONBF setvbuf(stdin, NULL, _IONBF, 0); +#endif BIO_set_fp(cert,stdin,BIO_NOCLOSE); } else @@ -780,46 +816,21 @@ X509 *load_cert(BIO *err, const char *file, int format, x=d2i_X509_bio(cert,NULL); else if (format == FORMAT_NETSCAPE) { - const unsigned char *p,*op; - int size=0,i; - - /* We sort of have to do it this way because it is sort of nice - * to read the header first and check it, then - * try to read the certificate */ - buf=BUF_MEM_new(); - for (;;) - { - if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10))) - goto end; - i=BIO_read(cert,&(buf->data[size]),1024*10); - size+=i; - if (i == 0) break; - if (i < 0) - { - perror("reading certificate"); + NETSCAPE_X509 *nx; + nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL); + if (nx == NULL) goto end; - } - } - p=(unsigned char *)buf->data; - op=p; - /* First load the header */ - if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL) - goto end; - if ((ah->header == NULL) || (ah->header->data == NULL) || - (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data, - ah->header->length) != 0)) + if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data, + nx->header->length) != 0)) { + NETSCAPE_X509_free(nx); BIO_printf(err,"Error reading header on certificate\n"); goto end; } - /* header is ok, so now read the object */ - p=op; - ah->meth=X509_asn1_meth(); - if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL) - goto end; - x=(X509 *)ah->data; - ah->data=NULL; + x=nx->cert; + nx->cert = NULL; + NETSCAPE_X509_free(nx); } else if (format == FORMAT_PEM) x=PEM_read_bio_X509_AUX(cert,NULL, @@ -841,9 +852,7 @@ end: BIO_printf(err,"unable to load certificate\n"); ERR_print_errors(err); } - if (ah != NULL) ASN1_HEADER_free(ah); if (cert != NULL) BIO_free(cert); - if (buf != NULL) BUF_MEM_free(buf); return(x); } @@ -866,10 +875,17 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, if (format == FORMAT_ENGINE) { if (!e) - BIO_printf(bio_err,"no engine specified\n"); + BIO_printf(err,"no engine specified\n"); else + { pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data); + if (!pkey) + { + BIO_printf(err,"cannot load %s from engine\n",key_descrip); + ERR_print_errors(err); + } + } goto end; } #endif @@ -881,7 +897,9 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, } if (file == NULL && maybe_stdin) { +#ifdef _IONBF setvbuf(stdin, NULL, _IONBF, 0); +#endif BIO_set_fp(key,stdin,BIO_NOCLOSE); } else @@ -912,6 +930,13 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, &pkey, NULL, NULL)) goto end; } +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) + else if (format == FORMAT_MSBLOB) + pkey = b2i_PrivateKey_bio(key); + else if (format == FORMAT_PVK) + pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, + &cb_data); +#endif else { BIO_printf(err,"bad input format specified for key file\n"); @@ -919,8 +944,11 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, } end: if (key != NULL) BIO_free(key); - if (pkey == NULL) + if (pkey == NULL) + { BIO_printf(err,"unable to load %s\n", key_descrip); + ERR_print_errors(err); + } return(pkey); } @@ -958,7 +986,9 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, } if (file == NULL && maybe_stdin) { +#ifdef _IONBF setvbuf(stdin, NULL, _IONBF, 0); +#endif BIO_set_fp(key,stdin,BIO_NOCLOSE); } else @@ -973,6 +1003,37 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, { pkey=d2i_PUBKEY_bio(key, NULL); } +#ifndef OPENSSL_NO_RSA + else if (format == FORMAT_ASN1RSA) + { + RSA *rsa; + rsa = d2i_RSAPublicKey_bio(key, NULL); + if (rsa) + { + pkey = EVP_PKEY_new(); + if (pkey) + EVP_PKEY_set1_RSA(pkey, rsa); + RSA_free(rsa); + } + else + pkey = NULL; + } + else if (format == FORMAT_PEMRSA) + { + RSA *rsa; + rsa = PEM_read_bio_RSAPublicKey(key, NULL, + (pem_password_cb *)password_callback, &cb_data); + if (rsa) + { + pkey = EVP_PKEY_new(); + if (pkey) + EVP_PKEY_set1_RSA(pkey, rsa); + RSA_free(rsa); + } + else + pkey = NULL; + } +#endif else if (format == FORMAT_PEM) { pkey=PEM_read_bio_PUBKEY(key,NULL, @@ -981,6 +1042,10 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) pkey = load_netscape_key(err, key, file, key_descrip, format); +#endif +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) + else if (format == FORMAT_MSBLOB) + pkey = b2i_PublicKey_bio(key); #endif else { @@ -1040,76 +1105,120 @@ error: } #endif /* ndef OPENSSL_NO_RC4 */ -STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, - const char *pass, ENGINE *e, const char *cert_descrip) +static int load_certs_crls(BIO *err, const char *file, int format, + const char *pass, ENGINE *e, const char *desc, + STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls) { - BIO *certs; int i; - STACK_OF(X509) *othercerts = NULL; - STACK_OF(X509_INFO) *allcerts = NULL; + BIO *bio; + STACK_OF(X509_INFO) *xis = NULL; X509_INFO *xi; PW_CB_DATA cb_data; + int rv = 0; cb_data.password = pass; cb_data.prompt_info = file; - if((certs = BIO_new(BIO_s_file())) == NULL) + if (format != FORMAT_PEM) { - ERR_print_errors(err); - goto end; + BIO_printf(err,"bad input format specified for %s\n", desc); + return 0; } if (file == NULL) - BIO_set_fp(certs,stdin,BIO_NOCLOSE); + bio = BIO_new_fp(stdin,BIO_NOCLOSE); else + bio = BIO_new_file(file, "r"); + + if (bio == NULL) { - if (BIO_read_filename(certs,file) <= 0) - { - BIO_printf(err, "Error opening %s %s\n", - cert_descrip, file); - ERR_print_errors(err); + BIO_printf(err, "Error opening %s %s\n", + desc, file ? file : "stdin"); + ERR_print_errors(err); + return 0; + } + + xis = PEM_X509_INFO_read_bio(bio, NULL, + (pem_password_cb *)password_callback, &cb_data); + + BIO_free(bio); + + if (pcerts) + { + *pcerts = sk_X509_new_null(); + if (!*pcerts) goto end; - } } - if (format == FORMAT_PEM) + if (pcrls) { - othercerts = sk_X509_new_null(); - if(!othercerts) - { - sk_X509_free(othercerts); - othercerts = NULL; + *pcrls = sk_X509_CRL_new_null(); + if (!*pcrls) goto end; + } + + for(i = 0; i < sk_X509_INFO_num(xis); i++) + { + xi = sk_X509_INFO_value (xis, i); + if (xi->x509 && pcerts) + { + if (!sk_X509_push(*pcerts, xi->x509)) + goto end; + xi->x509 = NULL; } - allcerts = PEM_X509_INFO_read_bio(certs, NULL, - (pem_password_cb *)password_callback, &cb_data); - for(i = 0; i < sk_X509_INFO_num(allcerts); i++) + if (xi->crl && pcrls) { - xi = sk_X509_INFO_value (allcerts, i); - if (xi->x509) - { - sk_X509_push(othercerts, xi->x509); - xi->x509 = NULL; - } + if (!sk_X509_CRL_push(*pcrls, xi->crl)) + goto end; + xi->crl = NULL; } - goto end; } - else { - BIO_printf(err,"bad input format specified for %s\n", - cert_descrip); - goto end; - } -end: - if (othercerts == NULL) + + if (pcerts && sk_X509_num(*pcerts) > 0) + rv = 1; + + if (pcrls && sk_X509_CRL_num(*pcrls) > 0) + rv = 1; + + end: + + if (xis) + sk_X509_INFO_pop_free(xis, X509_INFO_free); + + if (rv == 0) { - BIO_printf(err,"unable to load certificates\n"); + if (pcerts) + { + sk_X509_pop_free(*pcerts, X509_free); + *pcerts = NULL; + } + if (pcrls) + { + sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); + *pcrls = NULL; + } + BIO_printf(err,"unable to load %s\n", + pcerts ? "certificates" : "CRLs"); ERR_print_errors(err); } - if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free); - if (certs != NULL) BIO_free(certs); - return(othercerts); + return rv; } +STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, + const char *pass, ENGINE *e, const char *desc) + { + STACK_OF(X509) *certs; + load_certs_crls(err, file, format, pass, e, desc, &certs, NULL); + return certs; + } + +STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, + const char *pass, ENGINE *e, const char *desc) + { + STACK_OF(X509_CRL) *crls; + load_certs_crls(err, file, format, pass, e, desc, NULL, &crls); + return crls; + } #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) /* Return error for unknown extensions */ @@ -1396,6 +1505,10 @@ ENGINE *setup_engine(BIO *err, const char *engine, int debug) int load_config(BIO *err, CONF *cnf) { + static int load_config_called = 0; + if (load_config_called) + return 1; + load_config_called = 1; if (!cnf) cnf = config; if (!cnf) @@ -1429,7 +1542,7 @@ char *make_config_name() return p; } -static unsigned long index_serial_hash(const char **a) +static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) { const char *n; @@ -1438,7 +1551,7 @@ static unsigned long index_serial_hash(const char **a) return(lh_strhash(n)); } -static int index_serial_cmp(const char **a, const char **b) +static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) { const char *aa,*bb; @@ -1450,17 +1563,16 @@ static int index_serial_cmp(const char **a, const char **b) static int index_name_qual(char **a) { return(a[0][0] == 'V'); } -static unsigned long index_name_hash(const char **a) +static unsigned long index_name_hash(const OPENSSL_CSTRING *a) { return(lh_strhash(a[DB_name])); } -int index_name_cmp(const char **a, const char **b) - { return(strcmp(a[DB_name], - b[DB_name])); } +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) + { return(strcmp(a[DB_name], b[DB_name])); } -static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **) -static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **) -static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **) -static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **) +static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) #undef BSIZE #define BSIZE 256 @@ -1588,7 +1700,6 @@ int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) { char buf[5][BSIZE]; int i,j; - struct stat sb; i = strlen(serialfile) + strlen(old_suffix); j = strlen(serialfile) + strlen(new_suffix); @@ -1613,30 +1724,21 @@ int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix); #endif - if (stat(serialfile,&sb) < 0) - { - if (errno != ENOENT +#ifdef RL_DEBUG + BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", + serialfile, buf[1]); +#endif + if (rename(serialfile,buf[1]) < 0 && errno != ENOENT #ifdef ENOTDIR && errno != ENOTDIR #endif - ) - goto err; - } - else - { -#ifdef RL_DEBUG - BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", - serialfile, buf[1]); -#endif - if (rename(serialfile,buf[1]) < 0) - { + ) { BIO_printf(bio_err, "unable to rename %s to %s\n", serialfile, buf[1]); perror("reason"); goto err; } - } #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[0],serialfile); @@ -1703,10 +1805,7 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) goto err; } if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL) - { - if (tmpdb != NULL) TXT_DB_free(tmpdb); goto err; - } #ifndef OPENSSL_SYS_VMS BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); @@ -1767,8 +1866,8 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) int index_index(CA_DB *db) { if (!TXT_DB_create_index(db->db, DB_serial, NULL, - LHASH_HASH_FN(index_serial_hash), - LHASH_COMP_FN(index_serial_cmp))) + LHASH_HASH_FN(index_serial), + LHASH_COMP_FN(index_serial))) { BIO_printf(bio_err, "error creating serial number index:(%ld,%ld,%ld)\n", @@ -1778,8 +1877,8 @@ int index_index(CA_DB *db) if (db->attributes.unique_subject && !TXT_DB_create_index(db->db, DB_name, index_name_qual, - LHASH_HASH_FN(index_name_hash), - LHASH_COMP_FN(index_name_cmp))) + LHASH_HASH_FN(index_name), + LHASH_COMP_FN(index_name))) { BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n", db->db->error,db->db->arg1,db->db->arg2); @@ -1859,7 +1958,6 @@ int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suf { char buf[5][BSIZE]; int i,j; - struct stat sb; i = strlen(dbfile) + strlen(old_suffix); j = strlen(dbfile) + strlen(new_suffix); @@ -1903,30 +2001,21 @@ int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suf j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix); #endif - if (stat(dbfile,&sb) < 0) - { - if (errno != ENOENT -#ifdef ENOTDIR - && errno != ENOTDIR -#endif - ) - goto err; - } - else - { #ifdef RL_DEBUG - BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", - dbfile, buf[1]); + BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", + dbfile, buf[1]); #endif - if (rename(dbfile,buf[1]) < 0) - { + if (rename(dbfile,buf[1]) < 0 && errno != ENOENT +#ifdef ENOTDIR + && errno != ENOTDIR +#endif + ) { BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]); perror("reason"); goto err; } - } #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[0],dbfile); @@ -1940,23 +2029,15 @@ int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suf rename(buf[1],dbfile); goto err; } - if (stat(buf[4],&sb) < 0) - { - if (errno != ENOENT -#ifdef ENOTDIR - && errno != ENOTDIR -#endif - ) - goto err; - } - else - { #ifdef RL_DEBUG - BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", - buf[4],buf[3]); + BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", + buf[4],buf[3]); #endif - if (rename(buf[4],buf[3]) < 0) - { + if (rename(buf[4],buf[3]) < 0 && errno != ENOENT +#ifdef ENOTDIR + && errno != ENOTDIR +#endif + ) { BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]); @@ -1965,7 +2046,6 @@ int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suf rename(buf[1],dbfile); goto err; } - } #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[2],buf[4]); @@ -2160,52 +2240,13 @@ error: return NULL; } -/* This code MUST COME AFTER anything that uses rename() */ -#ifdef OPENSSL_SYS_WIN32 -int WIN32_rename(const char *from, const char *to) - { -#ifndef OPENSSL_SYS_WINCE - /* Windows rename gives an error if 'to' exists, so delete it - * first and ignore file not found errror - */ - if((remove(to) != 0) && (errno != ENOENT)) - return -1; -#undef rename - return rename(from, to); -#else - /* convert strings to UNICODE */ - { - BOOL result = FALSE; - WCHAR* wfrom; - WCHAR* wto; - int i; - wfrom = malloc((strlen(from)+1)*2); - wto = malloc((strlen(to)+1)*2); - if (wfrom != NULL && wto != NULL) - { - for (i=0; i<(int)strlen(from)+1; i++) - wfrom[i] = (short)from[i]; - for (i=0; i<(int)strlen(to)+1; i++) - wto[i] = (short)to[i]; - result = MoveFile(wfrom, wto); - } - if (wfrom != NULL) - free(wfrom); - if (wto != NULL) - free(wto); - return result; - } -#endif - } -#endif - int args_verify(char ***pargs, int *pargc, int *badarg, BIO *err, X509_VERIFY_PARAM **pm) { ASN1_OBJECT *otmp = NULL; unsigned long flags = 0; int i; - int purpose = 0; + int purpose = 0, depth = -1; char **oldargs = *pargs; char *arg = **pargs, *argn = (*pargs)[1]; if (!strcmp(arg, "-policy")) @@ -2245,6 +2286,21 @@ int args_verify(char ***pargs, int *pargc, } (*pargs)++; } + else if (strcmp(arg,"-verify_depth") == 0) + { + if (!argn) + *badarg = 1; + else + { + depth = atoi(argn); + if(depth < 0) + { + BIO_printf(err, "invalid depth\n"); + *badarg = 1; + } + } + (*pargs)++; + } else if (!strcmp(arg, "-ignore_critical")) flags |= X509_V_FLAG_IGNORE_CRITICAL; else if (!strcmp(arg, "-issuer_checks")) @@ -2257,8 +2313,16 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_POLICY_CHECK; else if (!strcmp(arg, "-explicit_policy")) flags |= X509_V_FLAG_EXPLICIT_POLICY; + else if (!strcmp(arg, "-inhibit_any")) + flags |= X509_V_FLAG_INHIBIT_ANY; + else if (!strcmp(arg, "-inhibit_map")) + flags |= X509_V_FLAG_INHIBIT_MAP; else if (!strcmp(arg, "-x509_strict")) flags |= X509_V_FLAG_X509_STRICT; + else if (!strcmp(arg, "-extended_crl")) + flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; + else if (!strcmp(arg, "-use_deltas")) + flags |= X509_V_FLAG_USE_DELTAS; else if (!strcmp(arg, "-policy_print")) flags |= X509_V_FLAG_NOTIFY_POLICY; else if (!strcmp(arg, "-check_ss_sig")) @@ -2288,6 +2352,9 @@ int args_verify(char ***pargs, int *pargc, if (purpose) X509_VERIFY_PARAM_set_purpose(*pm, purpose); + if (depth >= 0) + X509_VERIFY_PARAM_set_depth(*pm, depth); + end: (*pargs)++; @@ -2299,6 +2366,61 @@ int args_verify(char ***pargs, int *pargc, } +/* Read whole contents of a BIO into an allocated memory buffer and + * return it. + */ + +int bio_to_mem(unsigned char **out, int maxlen, BIO *in) + { + BIO *mem; + int len, ret; + unsigned char tbuf[1024]; + mem = BIO_new(BIO_s_mem()); + if (!mem) + return -1; + for(;;) + { + if ((maxlen != -1) && maxlen < 1024) + len = maxlen; + else + len = 1024; + len = BIO_read(in, tbuf, len); + if (len <= 0) + break; + if (BIO_write(mem, tbuf, len) != len) + { + BIO_free(mem); + return -1; + } + maxlen -= len; + + if (maxlen == 0) + break; + } + ret = BIO_get_mem_data(mem, (char **)out); + BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); + BIO_free(mem); + return ret; + } + +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) + { + int rv; + char *stmp, *vtmp = NULL; + stmp = BUF_strdup(value); + if (!stmp) + return -1; + vtmp = strchr(stmp, ':'); + if (vtmp) + { + *vtmp = 0; + vtmp++; + } + rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); + OPENSSL_free(stmp); + return rv; + } + static void nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes) { @@ -2340,7 +2462,7 @@ void policies_print(BIO *out, X509_STORE_CTX *ctx) BIO_free(out); } -#ifndef OPENSSL_NO_JPAKE +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) static JPAKE_CTX *jpake_init(const char *us, const char *them, const char *secret) @@ -2523,17 +2645,14 @@ void jpake_client_auth(BIO *out, BIO *conn, const char *secret) jpake_send_step3a(bconn, ctx); jpake_receive_step3b(ctx, bconn); - /* - * The problem is that you must use the derived key in the - * session key or you are subject to man-in-the-middle - * attacks. - */ - BIO_puts(out, "JPAKE authentication succeeded (N.B. This version can" - " be MitMed. See the version in HEAD for how to do it" - " properly)\n"); + BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); + + psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); BIO_pop(bconn); BIO_free(bconn); + + JPAKE_CTX_free(ctx); } void jpake_server_auth(BIO *out, BIO *conn, const char *secret) @@ -2555,17 +2674,340 @@ void jpake_server_auth(BIO *out, BIO *conn, const char *secret) jpake_receive_step3a(ctx, bconn); jpake_send_step3b(bconn, ctx); - /* - * The problem is that you must use the derived key in the - * session key or you are subject to man-in-the-middle - * attacks. - */ - BIO_puts(out, "JPAKE authentication succeeded (N.B. This version can" - " be MitMed. See the version in HEAD for how to do it" - " properly)\n"); + BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); + + psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); BIO_pop(bconn); BIO_free(bconn); + + JPAKE_CTX_free(ctx); + } + +#endif + +/* + * Platform-specific sections + */ +#if defined(_WIN32) +# ifdef fileno +# undef fileno +# define fileno(a) (int)_fileno(a) +# endif + +# include +# include + +static int WIN32_rename(const char *from, const char *to) + { + TCHAR *tfrom=NULL,*tto; + DWORD err; + int ret=0; + + if (sizeof(TCHAR) == 1) + { + tfrom = (TCHAR *)from; + tto = (TCHAR *)to; + } + else /* UNICODE path */ + { + size_t i,flen=strlen(from)+1,tlen=strlen(to)+1; + tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen)); + if (tfrom==NULL) goto err; + tto=tfrom+flen; +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101 + if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen)) +#endif + for (i=0;i=101 + if (!MultiByteToWideChar(CP_ACP,0,to, tlen,(WCHAR *)tto, tlen)) +#endif + for (i=0;i + +double app_tminterval(int stop,int usertime) + { + double ret=0; + static clock_t tmstart; + static int warning=1; + + if (usertime && warning) + { + BIO_printf(bio_err,"To get meaningful results, run " + "this program on idle system.\n"); + warning=0; + } + + if (stop==TM_START) tmstart = clock(); + else ret = (clock()-tmstart)/(double)CLOCKS_PER_SEC; + + return (ret); + } + +#elif defined(OPENSSL_SYSTEM_VXWORKS) +#include + +double app_tminterval(int stop,int usertime) + { + double ret=0; +#ifdef CLOCK_REALTIME + static struct timespec tmstart; + struct timespec now; +#else + static unsigned long tmstart; + unsigned long now; +#endif + static int warning=1; + + if (usertime && warning) + { + BIO_printf(bio_err,"To get meaningful results, run " + "this program on idle system.\n"); + warning=0; + } + +#ifdef CLOCK_REALTIME + clock_gettime(CLOCK_REALTIME,&now); + if (stop==TM_START) tmstart = now; + else ret = ( (now.tv_sec+now.tv_nsec*1e-9) + - (tmstart.tv_sec+tmstart.tv_nsec*1e-9) ); +#else + now = tickGet(); + if (stop==TM_START) tmstart = now; + else ret = (now - tmstart)/(double)sysClkRateGet(); +#endif + return (ret); + } + +#elif defined(OPENSSL_SYSTEM_VMS) +#include +#include + +double app_tminterval(int stop,int usertime) + { + static clock_t tmstart; + double ret = 0; + clock_t now; +#ifdef __TMS + struct tms rus; + + now = times(&rus); + if (usertime) now = rus.tms_utime; +#else + if (usertime) + now = clock(); /* sum of user and kernel times */ + else { + struct timeval tv; + gettimeofday(&tv,NULL); + now = (clock_t)( + (unsigned long long)tv.tv_sec*CLK_TCK + + (unsigned long long)tv.tv_usec*(1000000/CLK_TCK) + ); + } +#endif + if (stop==TM_START) tmstart = now; + else ret = (now - tmstart)/(double)(CLK_TCK); + + return (ret); + } + +#elif defined(_SC_CLK_TCK) /* by means of unistd.h */ +#include + +double app_tminterval(int stop,int usertime) + { + double ret = 0; + struct tms rus; + clock_t now = times(&rus); + static clock_t tmstart; + + if (usertime) now = rus.tms_utime; + + if (stop==TM_START) tmstart = now; + else + { + long int tck = sysconf(_SC_CLK_TCK); + ret = (now - tmstart)/(double)tck; + } + + return (ret); + } + +#else +#include +#include + +double app_tminterval(int stop,int usertime) + { + double ret = 0; + struct rusage rus; + struct timeval now; + static struct timeval tmstart; + + if (usertime) getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime; + else gettimeofday(&now,NULL); + + if (stop==TM_START) tmstart = now; + else ret = ( (now.tv_sec+now.tv_usec*1e-6) + - (tmstart.tv_sec+tmstart.tv_usec*1e-6) ); + + return ret; } +#endif + +/* app_isdir section */ +#ifdef _WIN32 +int app_isdir(const char *name) + { + HANDLE hList; + WIN32_FIND_DATA FileData; +#if defined(UNICODE) || defined(_UNICODE) + size_t i, len_0 = strlen(name)+1; + if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0])) + return -1; + +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101 + if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0)) +#endif + for (i=0;i +#ifndef S_ISDIR +# if defined(_S_IFMT) && defined(_S_IFDIR) +# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) +# else +# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) +# endif +#endif + +int app_isdir(const char *name) + { +#if defined(S_ISDIR) + struct stat st; + + if (stat(name,&st)==0) return S_ISDIR(st.st_mode); + else return -1; +#else + return -1; +#endif + } +#endif + +/* raw_read|write section */ +#if defined(_WIN32) && defined(STD_INPUT_HANDLE) +int raw_read_stdin(void *buf,int siz) + { + DWORD n; + if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL)) + return (n); + else return (-1); + } +#else +int raw_read_stdin(void *buf,int siz) + { return read(fileno(stdin),buf,siz); } +#endif + +#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE) +int raw_write_stdout(const void *buf,int siz) + { + DWORD n; + if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL)) + return (n); + else return (-1); + } +#else +int raw_write_stdout(const void *buf,int siz) + { return write(fileno(stdout),buf,siz); } #endif diff --git a/crypto/openssl/apps/apps.h b/crypto/openssl/apps/apps.h index 88579094b1..596a39aceb 100644 --- a/crypto/openssl/apps/apps.h +++ b/crypto/openssl/apps/apps.h @@ -137,11 +137,6 @@ long app_RAND_load_files(char *file); /* `file' is a list of files to read, * (see e_os.h). The string is * destroyed! */ -#ifdef OPENSSL_SYS_WIN32 -#define rename(from,to) WIN32_rename((from),(to)) -int WIN32_rename(const char *oldname,const char *newname); -#endif - #ifndef MONOLITH #define MAIN(a,v) main(a,v) @@ -149,11 +144,9 @@ int WIN32_rename(const char *oldname,const char *newname); #ifndef NON_MAIN CONF *config=NULL; BIO *bio_err=NULL; -int in_FIPS_mode=0; #else extern CONF *config; extern BIO *bio_err; -extern int in_FIPS_mode; #endif #else @@ -162,7 +155,6 @@ extern int in_FIPS_mode; extern CONF *config; extern char *default_config_file; extern BIO *bio_err; -extern int in_FIPS_mode; #endif @@ -176,61 +168,37 @@ extern int in_FIPS_mode; #define do_pipe_sig() #endif +#ifdef OPENSSL_NO_COMP +#define zlib_cleanup() +#else +#define zlib_cleanup() COMP_zlib_cleanup() +#endif + #if defined(MONOLITH) && !defined(OPENSSL_C) # define apps_startup() \ do_pipe_sig() # define apps_shutdown() #else # ifndef OPENSSL_NO_ENGINE -# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN16) || \ - defined(OPENSSL_SYS_WIN32) -# ifdef _O_BINARY -# define apps_startup() \ - do { _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \ - ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \ - ENGINE_load_builtin_engines(); setup_ui_method(); } while(0) -# else -# define apps_startup() \ - do { _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \ +# define apps_startup() \ + do { do_pipe_sig(); CRYPTO_malloc_init(); \ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \ ENGINE_load_builtin_engines(); setup_ui_method(); } while(0) -# endif -# else -# define apps_startup() \ - do { do_pipe_sig(); OpenSSL_add_all_algorithms(); \ - ERR_load_crypto_strings(); ENGINE_load_builtin_engines(); \ - setup_ui_method(); } while(0) -# endif # define apps_shutdown() \ do { CONF_modules_unload(1); destroy_ui_method(); \ - EVP_cleanup(); ENGINE_cleanup(); \ - CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \ - ERR_free_strings(); } while(0) + OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \ + CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \ + ERR_free_strings(); zlib_cleanup();} while(0) # else -# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN16) || \ - defined(OPENSSL_SYS_WIN32) -# ifdef _O_BINARY -# define apps_startup() \ - do { _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \ +# define apps_startup() \ + do { do_pipe_sig(); CRYPTO_malloc_init(); \ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \ setup_ui_method(); } while(0) -# else -# define apps_startup() \ - do { _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \ - ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \ - setup_ui_method(); } while(0) -# endif -# else -# define apps_startup() \ - do { do_pipe_sig(); OpenSSL_add_all_algorithms(); \ - ERR_load_crypto_strings(); \ - setup_ui_method(); } while(0) -# endif # define apps_shutdown() \ do { CONF_modules_unload(1); destroy_ui_method(); \ - EVP_cleanup(); \ - CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \ - ERR_free_strings(); } while(0) + OBJ_cleanup(); EVP_cleanup(); \ + CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \ + ERR_free_strings(); zlib_cleanup(); } while(0) # endif #endif @@ -240,6 +208,7 @@ extern int in_FIPS_mode; # define openssl_fdset(a,b) FD_SET(a, b) #endif + typedef struct args_st { char **data; @@ -282,6 +251,8 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip); STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip); +STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, + const char *pass, ENGINE *e, const char *cert_descrip); X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath); #ifndef OPENSSL_NO_ENGINE ENGINE *setup_engine(BIO *err, const char *engine, int debug); @@ -290,6 +261,7 @@ ENGINE *setup_engine(BIO *err, const char *engine, int debug); #ifndef OPENSSL_NO_OCSP OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, char *host, char *path, char *port, int use_ssl, + STACK_OF(CONF_VALUE) *headers, int req_timeout); #endif @@ -331,13 +303,23 @@ int index_index(CA_DB *db); int save_index(const char *dbfile, const char *suffix, CA_DB *db); int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix); void free_index(CA_DB *db); -int index_name_cmp(const char **a, const char **b); +#define index_name_cmp_noconst(a, b) \ + index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ + (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); int parse_yesno(const char *str, int def); X509_NAME *parse_name(char *str, long chtype, int multirdn); int args_verify(char ***pargs, int *pargc, int *badarg, BIO *err, X509_VERIFY_PARAM **pm); void policies_print(BIO *out, X509_STORE_CTX *ctx); +int bio_to_mem(unsigned char **out, int maxlen, BIO *in); +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value); +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, + const char *algname, ENGINE *e, int do_param); +#ifndef OPENSSL_NO_PSK +extern char *psk_key; +#endif #ifndef OPENSSL_NO_JPAKE void jpake_client_auth(BIO *out, BIO *conn, const char *secret); void jpake_server_auth(BIO *out, BIO *conn, const char *secret); @@ -353,6 +335,10 @@ void jpake_server_auth(BIO *out, BIO *conn, const char *secret); #define FORMAT_ENGINE 7 #define FORMAT_IISSGC 8 /* XXX this stupid macro helps us to avoid * adding yet another param to load_*key() */ +#define FORMAT_PEMRSA 9 /* PEM RSAPubicKey format */ +#define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ +#define FORMAT_MSBLOB 11 /* MS Key blob format */ +#define FORMAT_PVK 12 /* MS PVK file format */ #define EXT_COPY_NONE 0 #define EXT_COPY_ADD 1 @@ -364,4 +350,11 @@ void jpake_server_auth(BIO *out, BIO *conn, const char *secret); #define SERIAL_RAND_BITS 64 +int app_isdir(const char *); +int raw_read_stdin(void *,int); +int raw_write_stdout(const void *,int); + +#define TM_START 0 +#define TM_STOP 1 +double app_tminterval (int stop,int usertime); #endif diff --git a/crypto/openssl/apps/asn1pars.c b/crypto/openssl/apps/asn1pars.c index bde61d02d1..b5d65e725b 100644 --- a/crypto/openssl/apps/asn1pars.c +++ b/crypto/openssl/apps/asn1pars.c @@ -96,7 +96,7 @@ int MAIN(int argc, char **argv) unsigned char *tmpbuf; const unsigned char *ctmpbuf; BUF_MEM *buf=NULL; - STACK *osk=NULL; + STACK_OF(OPENSSL_STRING) *osk=NULL; ASN1_TYPE *at=NULL; informat=FORMAT_PEM; @@ -113,7 +113,7 @@ int MAIN(int argc, char **argv) prog=argv[0]; argc--; argv++; - if ((osk=sk_new_null()) == NULL) + if ((osk=sk_OPENSSL_STRING_new_null()) == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto end; @@ -169,7 +169,7 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"-strparse") == 0) { if (--argc < 1) goto bad; - sk_push(osk,*(++argv)); + sk_OPENSSL_STRING_push(osk,*(++argv)); } else if (strcmp(*argv,"-genstr") == 0) { @@ -302,18 +302,18 @@ bad: /* If any structs to parse go through in sequence */ - if (sk_num(osk)) + if (sk_OPENSSL_STRING_num(osk)) { tmpbuf=(unsigned char *)str; tmplen=num; - for (i=0; i #include #include -#include #include #include #include @@ -83,7 +82,7 @@ # else # include # endif -# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE) && !defined(__TANDEM) +# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE) # include # endif #endif @@ -258,6 +257,7 @@ int MAIN(int argc, char **argv) int doupdatedb=0; long crldays=0; long crlhours=0; + long crlsec=0; long errorline= -1; char *configfile=NULL; char *md=NULL; @@ -305,7 +305,8 @@ int MAIN(int argc, char **argv) ASN1_TIME *tmptm; ASN1_INTEGER *tmpser; char *f; - const char *p, **pp; + const char *p; + char * const *pp; int i,j; const EVP_MD *dgst=NULL; STACK_OF(CONF_VALUE) *attribs=NULL; @@ -456,6 +457,11 @@ EF_ALIGNMENT=0; if (--argc < 1) goto bad; crlhours= atol(*(++argv)); } + else if (strcmp(*argv,"-crlsec") == 0) + { + if (--argc < 1) goto bad; + crlsec = atol(*(++argv)); + } else if (strcmp(*argv,"-infiles") == 0) { argc--; @@ -549,8 +555,10 @@ bad: if (badops) { - for (pp=ca_usage; (*pp != NULL); pp++) - BIO_printf(bio_err,"%s",*pp); + const char **pp2; + + for (pp2=ca_usage; (*pp2 != NULL); pp2++) + BIO_printf(bio_err,"%s",*pp2); goto err; } @@ -825,7 +833,6 @@ bad: /* lookup where to write new certificates */ if ((outdir == NULL) && (req)) { - struct stat sb; if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR)) == NULL) @@ -844,27 +851,23 @@ bad: that to access(). However, time's too short to do that just now. */ +#ifndef _WIN32 if (access(outdir,R_OK|W_OK|X_OK) != 0) +#else + if (_access(outdir,R_OK|W_OK|X_OK) != 0) +#endif { BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir); perror(outdir); goto err; } - if (stat(outdir,&sb) != 0) - { - BIO_printf(bio_err,"unable to stat(%s)\n",outdir); - perror(outdir); - goto err; - } -#ifdef S_ISDIR - if (!S_ISDIR(sb.st_mode)) + if (app_isdir(outdir)<=0) { BIO_printf(bio_err,"%s need to be a directory\n",outdir); perror(outdir); goto err; } -#endif #endif } @@ -879,9 +882,9 @@ bad: if (db == NULL) goto err; /* Lets check some fields */ - for (i=0; idb->data); i++) + for (i=0; idb->data); i++) { - pp=(const char **)sk_value(db->db->data,i); + pp=sk_OPENSSL_PSTRING_value(db->db->data,i); if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) { @@ -894,7 +897,7 @@ bad: BIO_printf(bio_err," in entry %d\n", i+1); goto err; } - if (!check_time_format(pp[DB_exp_date])) + if (!check_time_format((char *)pp[DB_exp_date])) { BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1); goto err; @@ -934,7 +937,7 @@ bad: #endif TXT_DB_write(out,db->db); BIO_printf(bio_err,"%d entries loaded from the database\n", - db->db->data->num); + sk_OPENSSL_PSTRING_num(db->db->data)); BIO_printf(bio_err,"generating index\n"); } @@ -1025,6 +1028,17 @@ bad: goto err; } + if (!strcmp(md, "default")) + { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) + { + BIO_puts(bio_err,"no default digest\n"); + goto err; + } + md = (char *)OBJ_nid2sn(def_nid); + } + if ((dgst=EVP_get_digestbyname(md)) == NULL) { BIO_printf(bio_err,"%s is an unsupported message digest type\n",md); @@ -1094,9 +1108,9 @@ bad: if (startdate == NULL) ERR_clear_error(); } - if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate)) + if (startdate && !ASN1_TIME_set_string(NULL, startdate)) { - BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n"); + BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); goto err; } if (startdate == NULL) startdate="today"; @@ -1108,9 +1122,9 @@ bad: if (enddate == NULL) ERR_clear_error(); } - if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate)) + if (enddate && !ASN1_TIME_set_string(NULL, enddate)) { - BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n"); + BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); goto err; } @@ -1370,7 +1384,7 @@ bad: goto err; } - if (!crldays && !crlhours) + if (!crldays && !crlhours && !crlsec) { if (!NCONF_get_number(conf,section, ENV_DEFAULT_CRL_DAYS, &crldays)) @@ -1379,7 +1393,7 @@ bad: ENV_DEFAULT_CRL_HOURS, &crlhours)) crlhours = 0; } - if ((crldays == 0) && (crlhours == 0)) + if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n"); goto err; @@ -1393,14 +1407,19 @@ bad: if (!tmptm) goto err; X509_gmtime_adj(tmptm,0); X509_CRL_set_lastUpdate(crl, tmptm); - X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60); + if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec, + NULL)) + { + BIO_puts(bio_err, "error setting CRL nextUpdate\n"); + goto err; + } X509_CRL_set_nextUpdate(crl, tmptm); ASN1_TIME_free(tmptm); - for (i=0; idb->data); i++) + for (i=0; idb->data); i++) { - pp=(const char **)sk_value(db->db->data,i); + pp=sk_OPENSSL_PSTRING_value(db->db->data,i); if (pp[DB_type][0] == DB_TYPE_REV) { if ((r=X509_REVOKED_new()) == NULL) goto err; @@ -1426,15 +1445,6 @@ bad: /* we now have a CRL */ if (verbose) BIO_printf(bio_err,"signing CRL\n"); -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - dgst=EVP_dss1(); - else -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) - dgst=EVP_ecdsa(); -#endif /* Add any extensions asked for */ @@ -1467,6 +1477,12 @@ bad: if (crlnumberfile != NULL) /* we have a CRL number that need updating */ if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err; + if (crlnumber) + { + BN_free(crlnumber); + crlnumber = NULL; + } + if (!X509_CRL_sign(crl,pkey,dgst)) goto err; PEM_write_bio_X509_CRL(Sout,crl); @@ -1519,6 +1535,7 @@ err: if (free_key && key) OPENSSL_free(key); BN_free(serial); + BN_free(crlnumber); free_index(db); EVP_PKEY_free(pkey); if (x509) X509_free(x509); @@ -1677,7 +1694,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, int ok= -1,i,j,last,nid; const char *p; CONF_VALUE *cv; - char *row[DB_NUMBER],**rrow=NULL,**irow=NULL; + OPENSSL_STRING row[DB_NUMBER]; + OPENSSL_STRING *irow=NULL; + OPENSSL_STRING *rrow=NULL; char buf[25]; tmptm=ASN1_UTCTIME_new(); @@ -1919,7 +1938,9 @@ again2: if (db->attributes.unique_subject) { - rrow=TXT_DB_get_by_index(db->db,DB_name,row); + OPENSSL_STRING *crow=row; + + rrow=TXT_DB_get_by_index(db->db,DB_name,crow); if (rrow != NULL) { BIO_printf(bio_err, @@ -1995,11 +2016,11 @@ again2: if (strcmp(startdate,"today") == 0) X509_gmtime_adj(X509_get_notBefore(ret),0); - else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate); + else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate); if (enddate == NULL) - X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days); - else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); + X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL); + else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate); if (!X509_set_subject_name(ret,subject)) goto err; @@ -2119,25 +2140,11 @@ again2: } } - -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1(); pktmp=X509_get_pubkey(ret); if (EVP_PKEY_missing_parameters(pktmp) && !EVP_PKEY_missing_parameters(pkey)) EVP_PKEY_copy_parameters(pktmp,pkey); EVP_PKEY_free(pktmp); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) - dgst = EVP_ecdsa(); - pktmp = X509_get_pubkey(ret); - if (EVP_PKEY_missing_parameters(pktmp) && - !EVP_PKEY_missing_parameters(pkey)) - EVP_PKEY_copy_parameters(pktmp, pkey); - EVP_PKEY_free(pktmp); -#endif - if (!X509_sign(ret,pkey,dgst)) goto err; @@ -2239,7 +2246,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, unsigned long nameopt, int default_op, int ext_copy) { STACK_OF(CONF_VALUE) *sk=NULL; - LHASH *parms=NULL; + LHASH_OF(CONF_VALUE) *parms=NULL; X509_REQ *req=NULL; CONF_VALUE *cv=NULL; NETSCAPE_SPKI *spki = NULL; @@ -2373,15 +2380,7 @@ err: static int check_time_format(const char *str) { - ASN1_TIME tm; - - tm.data=(unsigned char *)str; - tm.length=strlen(str); - tm.type=V_ASN1_UTCTIME; - if (ASN1_TIME_check(&tm)) - return 1; - tm.type=V_ASN1_GENERALIZEDTIME; - return ASN1_TIME_check(&tm); + return ASN1_TIME_set_string(NULL, str); } static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) @@ -2396,6 +2395,8 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) row[i]=NULL; row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0); bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL); + if (!bn) + goto err; if (BN_is_zero(bn)) row[DB_serial]=BUF_strdup("00"); else @@ -2465,7 +2466,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) goto err; } - else if (index_name_cmp((const char **)row,(const char **)rrow)) + else if (index_name_cmp_noconst(row, rrow)) { BIO_printf(bio_err,"ERROR:name does not match %s\n", row[DB_name]); @@ -2614,9 +2615,9 @@ static int do_updatedb (CA_DB *db) else a_y2k = 0; - for (i = 0; i < sk_num(db->db->data); i++) + for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { - rrow = (char **) sk_value(db->db->data, i); + rrow = sk_OPENSSL_PSTRING_value(db->db->data, i); if (rrow[DB_type][0] == 'V') { @@ -2863,22 +2864,13 @@ int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) p=(char *)str->data; for (j=str->length; j>0; j--) { -#ifdef CHARSET_EBCDIC - if ((*p >= 0x20) && (*p <= 0x7e)) - BIO_printf(bp,"%c",os_toebcdic[*p]); -#else if ((*p >= ' ') && (*p <= '~')) BIO_printf(bp,"%c",*p); -#endif else if (*p & 0x80) BIO_printf(bp,"\\0x%02X",*p); else if ((unsigned char)*p == 0xf7) BIO_printf(bp,"^?"); -#ifdef CHARSET_EBCDIC - else BIO_printf(bp,"^%c",os_toebcdic[*p+0x40]); -#else else BIO_printf(bp,"^%c",*p+'@'); -#endif p++; } BIO_printf(bp,"'\n"); diff --git a/crypto/openssl/apps/ciphers.c b/crypto/openssl/apps/ciphers.c index 43f0ac594a..3d4c60db9e 100644 --- a/crypto/openssl/apps/ciphers.c +++ b/crypto/openssl/apps/ciphers.c @@ -71,7 +71,8 @@ static const char *ciphers_usage[]={ "usage: ciphers args\n", -" -v - verbose mode, a textual listing of the ciphers in SSLeay\n", +" -v - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n", +" -V - even more verbose\n", " -ssl2 - SSL2 mode\n", " -ssl3 - SSL3 mode\n", " -tls1 - TLS1 mode\n", @@ -83,14 +84,14 @@ int MAIN(int, char **); int MAIN(int argc, char **argv) { int ret=1,i; - int verbose=0; + int verbose=0,Verbose=0; const char **pp; const char *p; int badops=0; SSL_CTX *ctx=NULL; SSL *ssl=NULL; char *ciphers=NULL; - SSL_METHOD *meth=NULL; + const SSL_METHOD *meth=NULL; STACK_OF(SSL_CIPHER) *sk; char buf[512]; BIO *STDout=NULL; @@ -114,6 +115,8 @@ int MAIN(int argc, char **argv) STDout = BIO_push(tmpbio, STDout); } #endif + if (!load_config(bio_err, NULL)) + goto end; argc--; argv++; @@ -121,6 +124,8 @@ int MAIN(int argc, char **argv) { if (strcmp(*argv,"-v") == 0) verbose=1; + else if (strcmp(*argv,"-V") == 0) + verbose=Verbose=1; #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv,"-ssl2") == 0) meth=SSLv2_client_method(); @@ -179,15 +184,33 @@ int MAIN(int argc, char **argv) } BIO_printf(STDout,"\n"); } - else + else /* verbose */ { sk=SSL_get_ciphers(ssl); for (i=0; iid; + int id0 = (int)(id >> 24); + int id1 = (int)((id >> 16) & 0xffL); + int id2 = (int)((id >> 8) & 0xffL); + int id3 = (int)(id & 0xffL); + + if ((id & 0xff000000L) == 0x02000000L) + BIO_printf(STDout, " 0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */ + else if ((id & 0xff000000L) == 0x03000000L) + BIO_printf(STDout, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */ + else + BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ + } + + BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf)); } } diff --git a/crypto/openssl/apps/cms.c b/crypto/openssl/apps/cms.c index 6d227acabe..d29a884902 100644 --- a/crypto/openssl/apps/cms.c +++ b/crypto/openssl/apps/cms.c @@ -71,8 +71,9 @@ static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int cms_cb(int ok, X509_STORE_CTX *ctx); static void receipt_request_print(BIO *out, CMS_ContentInfo *cms); -static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst, - STACK *rr_from); +static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, + int rr_allorfirst, + STACK_OF(OPENSSL_STRING) *rr_from); #define SMIME_OP 0x10 #define SMIME_IP 0x20 @@ -94,6 +95,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst, #define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP) #define SMIME_VERIFY_RECEIPT (16 | SMIME_IP) +int verify_err = 0; + int MAIN(int, char **); int MAIN(int argc, char **argv) @@ -105,7 +108,7 @@ int MAIN(int argc, char **argv) const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *signerfile = NULL, *recipfile = NULL; - STACK *sksigners = NULL, *skkeys = NULL; + STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; char *certsoutfile = NULL; const EVP_CIPHER *cipher = NULL; @@ -116,9 +119,10 @@ int MAIN(int argc, char **argv) STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; int badarg = 0; - int flags = CMS_DETACHED; + int flags = CMS_DETACHED, noout = 0, print = 0; + int verify_retcode = 0; int rr_print = 0, rr_allorfirst = -1; - STACK *rr_to = NULL, *rr_from = NULL; + STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; CMS_ReceiptRequest *rr = NULL; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; @@ -166,6 +170,8 @@ int MAIN(int argc, char **argv) operation = SMIME_RESIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; + else if (!strcmp (*args, "-verify_retcode")) + verify_retcode = 1; else if (!strcmp(*args,"-verify_receipt")) { operation = SMIME_VERIFY_RECEIPT; @@ -252,21 +258,17 @@ int MAIN(int argc, char **argv) else if (!strcmp (*args, "-no_attr_verify")) flags |= CMS_NO_ATTR_VERIFY; else if (!strcmp (*args, "-stream")) - { - args++; - continue; - } + flags |= CMS_STREAM; else if (!strcmp (*args, "-indef")) - { - args++; - continue; - } + flags |= CMS_STREAM; else if (!strcmp (*args, "-noindef")) flags &= ~CMS_STREAM; else if (!strcmp (*args, "-nooldmime")) flags |= CMS_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= CMS_CRLFEOL; + else if (!strcmp (*args, "-noout")) + noout = 1; else if (!strcmp (*args, "-receipt_request_print")) rr_print = 1; else if (!strcmp (*args, "-receipt_request_all")) @@ -279,8 +281,8 @@ int MAIN(int argc, char **argv) goto argerr; args++; if (!rr_from) - rr_from = sk_new_null(); - sk_push(rr_from, *args); + rr_from = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(rr_from, *args); } else if (!strcmp(*args,"-receipt_request_to")) { @@ -288,9 +290,14 @@ int MAIN(int argc, char **argv) goto argerr; args++; if (!rr_to) - rr_to = sk_new_null(); - sk_push(rr_to, *args); + rr_to = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(rr_to, *args); } + else if (!strcmp (*args, "-print")) + { + noout = 1; + print = 1; + } else if (!strcmp(*args,"-secretkey")) { long ltmp; @@ -380,13 +387,13 @@ int MAIN(int argc, char **argv) if (signerfile) { if (!sksigners) - sksigners = sk_new_null(); - sk_push(sksigners, signerfile); + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); if (!keyfile) keyfile = signerfile; if (!skkeys) - skkeys = sk_new_null(); - sk_push(skkeys, keyfile); + skkeys = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = *++args; @@ -428,12 +435,12 @@ int MAIN(int argc, char **argv) goto argerr; } if (!sksigners) - sksigners = sk_new_null(); - sk_push(sksigners, signerfile); + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (!skkeys) - skkeys = sk_new_null(); - sk_push(skkeys, keyfile); + skkeys = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = *++args; } @@ -532,13 +539,13 @@ int MAIN(int argc, char **argv) if (signerfile) { if (!sksigners) - sksigners = sk_new_null(); - sk_push(sksigners, signerfile); + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys) - skkeys = sk_new_null(); + skkeys = sk_OPENSSL_STRING_new_null(); if (!keyfile) keyfile = signerfile; - sk_push(skkeys, keyfile); + sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { @@ -697,7 +704,7 @@ int MAIN(int argc, char **argv) if (secret_key && !secret_keyid) { - BIO_printf(bio_err, "No sectre key id\n"); + BIO_printf(bio_err, "No secret key id\n"); goto end; } @@ -873,7 +880,7 @@ int MAIN(int argc, char **argv) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; - X509_STORE_set_verify_cb_func(store, cms_cb); + X509_STORE_set_verify_cb(store, cms_cb); if (vpm) X509_STORE_set1_param(store, vpm); } @@ -973,11 +980,11 @@ int MAIN(int argc, char **argv) } else flags |= CMS_REUSE_DIGEST; - for (i = 0; i < sk_num(sksigners); i++) + for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { CMS_SignerInfo *si; - signerfile = sk_value(sksigners, i); - keyfile = sk_value(skkeys, i); + signerfile = sk_OPENSSL_STRING_value(sksigners, i); + keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) @@ -1075,6 +1082,8 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Verification failure\n"); + if (verify_retcode) + ret = verify_err + 32; goto end; } if (signerfile) @@ -1107,7 +1116,12 @@ int MAIN(int argc, char **argv) } else { - if (outformat == FORMAT_SMIME) + if (noout) + { + if (print) + CMS_ContentInfo_print_ctx(out, cms, 0, NULL); + } + else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s\n", to); @@ -1121,9 +1135,9 @@ int MAIN(int argc, char **argv) ret = SMIME_write_CMS(out, cms, in, flags); } else if (outformat == FORMAT_PEM) - ret = PEM_write_bio_CMS(out, cms); + ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (outformat == FORMAT_ASN1) - ret = i2d_CMS_bio(out,cms); + ret = i2d_CMS_bio_stream(out,cms, in, flags); else { BIO_printf(bio_err, "Bad output format for CMS file\n"); @@ -1146,9 +1160,9 @@ end: if (vpm) X509_VERIFY_PARAM_free(vpm); if (sksigners) - sk_free(sksigners); + sk_OPENSSL_STRING_free(sksigners); if (skkeys) - sk_free(skkeys); + sk_OPENSSL_STRING_free(skkeys); if (secret_key) OPENSSL_free(secret_key); if (secret_keyid) @@ -1158,9 +1172,9 @@ end: if (rr) CMS_ReceiptRequest_free(rr); if (rr_to) - sk_free(rr_to); + sk_OPENSSL_STRING_free(rr_to); if (rr_from) - sk_free(rr_from); + sk_OPENSSL_STRING_free(rr_from); X509_STORE_free(store); X509_free(cert); X509_free(recip); @@ -1199,6 +1213,8 @@ static int cms_cb(int ok, X509_STORE_CTX *ctx) error = X509_STORE_CTX_get_error(ctx); + verify_err = error; + if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) && ((error != X509_V_OK) || (ok != 2))) return ok; @@ -1280,7 +1296,7 @@ static void receipt_request_print(BIO *out, CMS_ContentInfo *cms) } } -static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK *ns) +static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns) { int i; STACK_OF(GENERAL_NAMES) *ret; @@ -1289,12 +1305,10 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK *ns) ret = sk_GENERAL_NAMES_new_null(); if (!ret) goto err; - for (i = 0; i < sk_num(ns); i++) + for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) { - CONF_VALUE cnf; - cnf.name = "email"; - cnf.value = sk_value(ns, i); - gen = v2i_GENERAL_NAME(NULL, NULL, &cnf); + char *str = sk_OPENSSL_STRING_value(ns, i); + gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0); if (!gen) goto err; gens = GENERAL_NAMES_new(); @@ -1321,8 +1335,9 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK *ns) } -static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst, - STACK *rr_from) +static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, + int rr_allorfirst, + STACK_OF(OPENSSL_STRING) *rr_from) { STACK_OF(GENERAL_NAMES) *rct_to, *rct_from; CMS_ReceiptRequest *rr; diff --git a/crypto/openssl/apps/crl2p7.c b/crypto/openssl/apps/crl2p7.c index b2f2d121d5..bbc83774db 100644 --- a/crypto/openssl/apps/crl2p7.c +++ b/crypto/openssl/apps/crl2p7.c @@ -63,7 +63,6 @@ #include #include #include -#include #include "apps.h" #include #include @@ -93,7 +92,7 @@ int MAIN(int argc, char **argv) PKCS7 *p7 = NULL; PKCS7_SIGNED *p7s = NULL; X509_CRL *crl=NULL; - STACK *certflst=NULL; + STACK_OF(OPENSSL_STRING) *certflst=NULL; STACK_OF(X509_CRL) *crl_stack=NULL; STACK_OF(X509) *cert_stack=NULL; int ret=1,nocrl=0; @@ -141,8 +140,8 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"-certfile") == 0) { if (--argc < 1) goto bad; - if(!certflst) certflst = sk_new_null(); - sk_push(certflst,*(++argv)); + if(!certflst) certflst = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(certflst,*(++argv)); } else { @@ -227,8 +226,8 @@ bad: if ((cert_stack=sk_X509_new_null()) == NULL) goto end; p7s->cert=cert_stack; - if(certflst) for(i = 0; i < sk_num(certflst); i++) { - certfile = sk_value(certflst, i); + if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) { + certfile = sk_OPENSSL_STRING_value(certflst, i); if (add_certs_from_file(cert_stack,certfile) < 0) { BIO_printf(bio_err, "error loading certificates\n"); @@ -237,7 +236,7 @@ bad: } } - sk_free(certflst); + sk_OPENSSL_STRING_free(certflst); if (outfile == NULL) { @@ -295,19 +294,12 @@ end: */ static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile) { - struct stat st; BIO *in=NULL; int count=0; int ret= -1; STACK_OF(X509_INFO) *sk=NULL; X509_INFO *xi; - if ((stat(certfile,&st) != 0)) - { - BIO_printf(bio_err,"unable to load the file, %s\n",certfile); - goto end; - } - in=BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0)) { diff --git a/crypto/openssl/apps/dgst.c b/crypto/openssl/apps/dgst.c index 9ebfc22e79..9bf38ce73b 100644 --- a/crypto/openssl/apps/dgst.c +++ b/crypto/openssl/apps/dgst.c @@ -75,8 +75,29 @@ #define PROG dgst_main int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, - EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title, - const char *file,BIO *bmd,const char *hmac_key, int non_fips_allow); + EVP_PKEY *key, unsigned char *sigin, int siglen, + const char *sig_name, const char *md_name, + const char *file,BIO *bmd); + +static void list_md_fn(const EVP_MD *m, + const char *from, const char *to, void *arg) + { + const char *mname; + /* Skip aliases */ + if (!m) + return; + mname = OBJ_nid2ln(EVP_MD_type(m)); + /* Skip shortnames */ + if (strcmp(from, mname)) + return; + /* Skip clones */ + if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) + return; + if (strchr(mname, ' ')) + mname= EVP_MD_name(m); + BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n", + mname, mname); + } int MAIN(int, char **); @@ -89,7 +110,6 @@ int MAIN(int argc, char **argv) BIO *in=NULL,*inp; BIO *bmd=NULL; BIO *out = NULL; - const char *name; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; int separator=0; @@ -101,16 +121,16 @@ int MAIN(int argc, char **argv) EVP_PKEY *sigkey = NULL; unsigned char *sigbuf = NULL; int siglen = 0; - unsigned int sig_flags = 0; char *passargin = NULL, *passin = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif char *hmac_key=NULL; - int non_fips_allow = 0; + char *mac_name=NULL; + STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; apps_startup(); -ERR_load_crypto_strings(); + if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) { BIO_printf(bio_err,"out of memory\n"); @@ -135,6 +155,8 @@ ERR_load_crypto_strings(); if ((*argv)[0] != '-') break; if (strcmp(*argv,"-c") == 0) separator=1; + else if (strcmp(*argv,"-r") == 0) + separator=2; else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) break; @@ -169,27 +191,6 @@ ERR_load_crypto_strings(); keyfile=*(++argv); do_verify = 1; } - else if (strcmp(*argv,"-x931") == 0) - sig_flags = EVP_MD_CTX_FLAG_PAD_X931; - else if (strcmp(*argv,"-pss_saltlen") == 0) - { - int saltlen; - if (--argc < 1) break; - saltlen=atoi(*(++argv)); - if (saltlen == -1) - sig_flags = EVP_MD_CTX_FLAG_PSS_MREC; - else if (saltlen == -2) - sig_flags = EVP_MD_CTX_FLAG_PSS_MDLEN; - else if (saltlen < -2 || saltlen >= 0xFFFE) - { - BIO_printf(bio_err, "Invalid PSS salt length %d\n", saltlen); - goto end; - } - else - sig_flags = saltlen; - sig_flags <<= 16; - sig_flags |= EVP_MD_CTX_FLAG_PAD_PSS; - } else if (strcmp(*argv,"-signature") == 0) { if (--argc < 1) break; @@ -205,6 +206,7 @@ ERR_load_crypto_strings(); { if (--argc < 1) break; engine= *(++argv); + e = setup_engine(bio_err, engine, 0); } #endif else if (strcmp(*argv,"-hex") == 0) @@ -213,16 +215,36 @@ ERR_load_crypto_strings(); out_bin = 1; else if (strcmp(*argv,"-d") == 0) debug=1; - else if (strcmp(*argv,"-non-fips-allow") == 0) - non_fips_allow=1; - else if (!strcmp(*argv,"-fips-fingerprint")) - hmac_key = "etaonrishdlcupfm"; else if (!strcmp(*argv,"-hmac")) { if (--argc < 1) break; hmac_key=*++argv; } + else if (!strcmp(*argv,"-mac")) + { + if (--argc < 1) + break; + mac_name=*++argv; + } + else if (strcmp(*argv,"-sigopt") == 0) + { + if (--argc < 1) + break; + if (!sigopts) + sigopts = sk_OPENSSL_STRING_new_null(); + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) + break; + } + else if (strcmp(*argv,"-macopt") == 0) + { + if (--argc < 1) + break; + if (!macopts) + macopts = sk_OPENSSL_STRING_new_null(); + if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) + break; + } else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL) md=m; else @@ -231,12 +253,9 @@ ERR_load_crypto_strings(); argv++; } - if (md == NULL) - md=EVP_md5(); if(do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); - err = 1; goto end; } @@ -245,6 +264,7 @@ ERR_load_crypto_strings(); BIO_printf(bio_err,"unknown option '%s'\n",*argv); BIO_printf(bio_err,"options are\n"); BIO_printf(bio_err,"-c to output the digest with separating colons\n"); + BIO_printf(bio_err,"-r to output the digest in coreutils format\n"); BIO_printf(bio_err,"-d to output debug info\n"); BIO_printf(bio_err,"-hex output as hex dump\n"); BIO_printf(bio_err,"-binary output in binary form\n"); @@ -252,49 +272,20 @@ ERR_load_crypto_strings(); BIO_printf(bio_err,"-verify file verify a signature using public key in file\n"); BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n"); BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n"); + BIO_printf(bio_err,"-out filename output to filename rather than stdout\n"); BIO_printf(bio_err,"-signature file signature to verify\n"); - BIO_printf(bio_err,"-binary output in binary form\n"); + BIO_printf(bio_err,"-sigopt nm:v signature parameter\n"); BIO_printf(bio_err,"-hmac key create hashed MAC with key\n"); + BIO_printf(bio_err,"-mac algorithm create MAC (not neccessarily HMAC)\n"); + BIO_printf(bio_err,"-macopt nm:v MAC algorithm parameters or key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n"); #endif - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm (default)\n", - LN_md5,LN_md5); - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_md4,LN_md4); - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_md2,LN_md2); -#ifndef OPENSSL_NO_SHA - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_sha1,LN_sha1); - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_sha,LN_sha); -#ifndef OPENSSL_NO_SHA256 - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_sha224,LN_sha224); - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_sha256,LN_sha256); -#endif -#ifndef OPENSSL_NO_SHA512 - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_sha384,LN_sha384); - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_sha512,LN_sha512); -#endif -#endif - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_mdc2,LN_mdc2); - BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", - LN_ripemd160,LN_ripemd160); - err=1; + EVP_MD_do_all_sorted(list_md_fn, bio_err); goto end; } -#ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); -#endif - in=BIO_new(BIO_s_file()); bmd=BIO_new(BIO_f_md()); if (debug) @@ -317,8 +308,10 @@ ERR_load_crypto_strings(); } if(out_bin == -1) { - if(keyfile) out_bin = 1; - else out_bin = 0; + if(keyfile) + out_bin = 1; + else + out_bin = 0; } if(randfile) @@ -344,6 +337,11 @@ ERR_load_crypto_strings(); ERR_print_errors(bio_err); goto end; } + if ((!!mac_name + !!keyfile + !!hmac_key) > 1) + { + BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); + goto end; + } if(keyfile) { @@ -361,6 +359,101 @@ ERR_load_crypto_strings(); } } + if (mac_name) + { + EVP_PKEY_CTX *mac_ctx = NULL; + int r = 0; + if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0)) + goto mac_end; + if (macopts) + { + char *macopt; + for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) + { + macopt = sk_OPENSSL_STRING_value(macopts, i); + if (pkey_ctrl_string(mac_ctx, macopt) <= 0) + { + BIO_printf(bio_err, + "MAC parameter error \"%s\"\n", + macopt); + ERR_print_errors(bio_err); + goto mac_end; + } + } + } + if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) + { + BIO_puts(bio_err, "Error generating key\n"); + ERR_print_errors(bio_err); + goto mac_end; + } + r = 1; + mac_end: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + if (r == 0) + goto end; + } + + if (hmac_key) + { + sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, + (unsigned char *)hmac_key, -1); + if (!sigkey) + goto end; + } + + if (sigkey) + { + EVP_MD_CTX *mctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + int r; + if (!BIO_get_md_ctx(bmd, &mctx)) + { + BIO_printf(bio_err, "Error getting context\n"); + ERR_print_errors(bio_err); + goto end; + } + if (do_verify) + r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey); + else + r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey); + if (!r) + { + BIO_printf(bio_err, "Error setting context\n"); + ERR_print_errors(bio_err); + goto end; + } + if (sigopts) + { + char *sigopt; + for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) + { + sigopt = sk_OPENSSL_STRING_value(sigopts, i); + if (pkey_ctrl_string(pctx, sigopt) <= 0) + { + BIO_printf(bio_err, + "parameter error \"%s\"\n", + sigopt); + ERR_print_errors(bio_err); + goto end; + } + } + } + } + /* we use md as a filter, reading from 'in' */ + else + { + if (md == NULL) + md = EVP_md5(); + if (!BIO_set_md(bmd,md)) + { + BIO_printf(bio_err, "Error setting digest %s\n", pname); + ERR_print_errors(bio_err); + goto end; + } + } + if(sigfile && sigkey) { BIO *sigbio; sigbio = BIO_new_file(sigfile, "rb"); @@ -381,67 +474,51 @@ ERR_load_crypto_strings(); goto end; } } + inp=BIO_push(bmd,in); - if (non_fips_allow) - { - EVP_MD_CTX *md_ctx; - BIO_get_md_ctx(bmd,&md_ctx); - EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - } - - if (sig_flags) + if (md == NULL) { - EVP_MD_CTX *md_ctx; - BIO_get_md_ctx(bmd,&md_ctx); - EVP_MD_CTX_set_flags(md_ctx, sig_flags); + EVP_MD_CTX *tctx; + BIO_get_md_ctx(bmd, &tctx); + md = EVP_MD_CTX_md(tctx); } - /* we use md as a filter, reading from 'in' */ - if (!BIO_set_md(bmd,md)) - { - BIO_printf(bio_err, "Error setting digest %s\n", pname); - ERR_print_errors(bio_err); - goto end; - } - - inp=BIO_push(bmd,in); - if (argc == 0) { BIO_set_fp(in,stdin,BIO_NOCLOSE); err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, - siglen,"","(stdin)",bmd,hmac_key,non_fips_allow); + siglen,NULL,NULL,"stdin",bmd); } else { - name=OBJ_nid2sn(md->type); + const char *md_name = NULL, *sig_name = NULL; + if(!out_bin) + { + if (sigkey) + { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_get0_asn1(sigkey); + if (ameth) + EVP_PKEY_asn1_get0_info(NULL, NULL, + NULL, NULL, &sig_name, ameth); + } + md_name = EVP_MD_name(md); + } err = 0; for (i=0; i 0) BIO_printf(out, "Verified OK\n"); else if(i == 0) @@ -516,25 +586,39 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, { EVP_MD_CTX *ctx; BIO_get_md_ctx(bp, &ctx); - if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) + len = BUFSIZE; + if(!EVP_DigestSignFinal(ctx, buf, &len)) { BIO_printf(bio_err, "Error Signing Data\n"); ERR_print_errors(bio_err); return 1; } } - else if(hmac_key) - { - HMAC_Final(&hmac_ctx,buf,&len); - HMAC_CTX_cleanup(&hmac_ctx); - } else + { len=BIO_gets(bp,(char *)buf,BUFSIZE); + if ((int)len <0) + { + ERR_print_errors(bio_err); + return 1; + } + } if(binout) BIO_write(out, buf, len); + else if (sep == 2) + { + for (i=0; i<(int)len; i++) + BIO_printf(out, "%02x",buf[i]); + BIO_printf(out, " *%s\n", file); + } else { - BIO_write(out,title,strlen(title)); + if (sig_name) + BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file); + else if (md_name) + BIO_printf(out, "%s(%s)= ", md_name, file); + else + BIO_printf(out, "(%s)= ", file); for (i=0; i<(int)len; i++) { if (sep && (i != 0)) @@ -543,10 +627,6 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, } BIO_printf(out, "\n"); } - if (hmac_key) - { - BIO_set_md_ctx(bmd,md_ctx); - } return 0; } diff --git a/crypto/openssl/apps/dh.c b/crypto/openssl/apps/dh.c index c4d891e125..e9609d630d 100644 --- a/crypto/openssl/apps/dh.c +++ b/crypto/openssl/apps/dh.c @@ -349,4 +349,10 @@ end: apps_shutdown(); OPENSSL_EXIT(ret); } +#else /* !OPENSSL_NO_DH */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + #endif diff --git a/crypto/openssl/apps/dhparam.c b/crypto/openssl/apps/dhparam.c index 04bd57c6e8..5fab29eb87 100644 --- a/crypto/openssl/apps/dhparam.c +++ b/crypto/openssl/apps/dhparam.c @@ -554,4 +554,10 @@ static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb) return 1; } +#else /* !OPENSSL_NO_DH */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + #endif diff --git a/crypto/openssl/apps/dsa.c b/crypto/openssl/apps/dsa.c index 5e68a56cfd..5222487ab9 100644 --- a/crypto/openssl/apps/dsa.c +++ b/crypto/openssl/apps/dsa.c @@ -65,11 +65,11 @@ #include "apps.h" #include #include +#include #include #include #include #include -#include #undef PROG #define PROG dsa_main @@ -112,6 +112,8 @@ int MAIN(int argc, char **argv) char *passin = NULL, *passout = NULL; int modulus=0; + int pvk_encr = 2; + apps_startup(); if (bio_err == NULL) @@ -171,6 +173,12 @@ int MAIN(int argc, char **argv) engine= *(++argv); } #endif + else if (strcmp(*argv,"-pvk-strong") == 0) + pvk_encr=2; + else if (strcmp(*argv,"-pvk-weak") == 0) + pvk_encr=1; + else if (strcmp(*argv,"-pvk-none") == 0) + pvk_encr=0; else if (strcmp(*argv,"-noout") == 0) noout=1; else if (strcmp(*argv,"-text") == 0) @@ -238,16 +246,30 @@ bad: goto end; } + in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); - if (out == NULL) + if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } + if (infile == NULL) + BIO_set_fp(in,stdin,BIO_NOCLOSE); + else + { + if (BIO_read_filename(in,infile) <= 0) + { + perror(infile); + goto end; + } + } + BIO_printf(bio_err,"read DSA key\n"); - { + + { EVP_PKEY *pkey; + if (pubin) pkey = load_pubkey(bio_err, infile, informat, 1, passin, e, "Public Key"); @@ -255,10 +277,12 @@ bad: pkey = load_key(bio_err, infile, informat, 1, passin, e, "Private Key"); - if (pkey != NULL) - dsa = pkey == NULL ? NULL : EVP_PKEY_get1_DSA(pkey); - EVP_PKEY_free(pkey); - } + if (pkey) + { + dsa = EVP_PKEY_get1_DSA(pkey); + EVP_PKEY_free(pkey); + } + } if (dsa == NULL) { BIO_printf(bio_err,"unable to load Key\n"); @@ -310,11 +334,24 @@ bad: i=PEM_write_bio_DSA_PUBKEY(out,dsa); else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc, NULL,0,NULL, passout); +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4) + } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { + EVP_PKEY *pk; + pk = EVP_PKEY_new(); + EVP_PKEY_set1_DSA(pk, dsa); + if (outformat == FORMAT_PVK) + i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); + else if (pubin || pubout) + i = i2b_PublicKey_bio(out, pk); + else + i = i2b_PrivateKey_bio(out, pk); + EVP_PKEY_free(pk); +#endif } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } - if (!i) + if (i <= 0) { BIO_printf(bio_err,"unable to write private key\n"); ERR_print_errors(bio_err); @@ -330,4 +367,10 @@ end: apps_shutdown(); OPENSSL_EXIT(ret); } +#else /* !OPENSSL_NO_DSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + #endif diff --git a/crypto/openssl/apps/ec.c b/crypto/openssl/apps/ec.c index 771e15f357..31194b48df 100644 --- a/crypto/openssl/apps/ec.c +++ b/crypto/openssl/apps/ec.c @@ -400,4 +400,10 @@ end: apps_shutdown(); OPENSSL_EXIT(ret); } +#else /* !OPENSSL_NO_EC */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + #endif diff --git a/crypto/openssl/apps/ecparam.c b/crypto/openssl/apps/ecparam.c index 4e1fc837ed..e9aa0a184a 100644 --- a/crypto/openssl/apps/ecparam.c +++ b/crypto/openssl/apps/ecparam.c @@ -725,4 +725,10 @@ static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var, BIO_printf(out, "\n\t};\n\n"); return 1; } +#else /* !OPENSSL_NO_EC */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + #endif diff --git a/crypto/openssl/apps/enc.c b/crypto/openssl/apps/enc.c index 8f5e5b8935..3c2c91e920 100644 --- a/crypto/openssl/apps/enc.c +++ b/crypto/openssl/apps/enc.c @@ -67,6 +67,7 @@ #include #include #include +#include #include int set_hex(char *in,unsigned char *out,int size); @@ -116,6 +117,10 @@ int MAIN(int argc, char **argv) char *hkey=NULL,*hiv=NULL,*hsalt = NULL; char *md=NULL; int enc=1,printkey=0,i,base64=0; +#ifdef ZLIB + int do_zlib=0; + BIO *bzl = NULL; +#endif int debug=0,olb64=0,nosalt=0; const EVP_CIPHER *cipher=NULL,*c; EVP_CIPHER_CTX *ctx = NULL; @@ -127,7 +132,6 @@ int MAIN(int argc, char **argv) char *engine = NULL; #endif const EVP_MD *dgst=NULL; - int non_fips_allow = 0; apps_startup(); @@ -142,9 +146,18 @@ int MAIN(int argc, char **argv) program_name(argv[0],pname,sizeof pname); if (strcmp(pname,"base64") == 0) base64=1; +#ifdef ZLIB + if (strcmp(pname,"zlib") == 0) + do_zlib=1; +#endif cipher=EVP_get_cipherbyname(pname); +#ifdef ZLIB + if (!do_zlib && !base64 && (cipher == NULL) + && (strcmp(pname,"enc") != 0)) +#else if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0)) +#endif { BIO_printf(bio_err,"%s is an unknown cipher\n",pname); goto bad; @@ -200,6 +213,10 @@ int MAIN(int argc, char **argv) base64=1; else if (strcmp(*argv,"-base64") == 0) base64=1; +#ifdef ZLIB + else if (strcmp(*argv,"-z") == 0) + do_zlib=1; +#endif else if (strcmp(*argv,"-bufsize") == 0) { if (--argc < 1) goto bad; @@ -267,8 +284,6 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; md= *(++argv); } - else if (strcmp(*argv,"-non-fips-allow") == 0) - non_fips_allow = 1; else if ((argv[0][0] == '-') && ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { @@ -291,9 +306,11 @@ bad: BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile"); BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md"); BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n",""); + BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S"); BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv"); BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]"); BIO_printf(bio_err,"%-14s buffer size\n","-bufsize "); + BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e"); #endif @@ -322,10 +339,7 @@ bad: if (dgst == NULL) { - if (in_FIPS_mode) - dgst = EVP_sha1(); - else - dgst = EVP_md5(); + dgst = EVP_md5(); } if (bufsize != NULL) @@ -457,6 +471,19 @@ bad: rbio=in; wbio=out; +#ifdef ZLIB + + if (do_zlib) + { + if ((bzl=BIO_new(BIO_f_zlib())) == NULL) + goto end; + if (enc) + wbio=BIO_push(bzl,wbio); + else + rbio=BIO_push(bzl,rbio); + } +#endif + if (base64) { if ((b64=BIO_new(BIO_f_base64())) == NULL) @@ -561,11 +588,6 @@ bad: */ BIO_get_cipher_ctx(benc, &ctx); - - if (non_fips_allow) - EVP_CIPHER_CTX_set_flags(ctx, - EVP_CIPH_FLAG_NON_FIPS_ALLOW); - if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", @@ -656,6 +678,9 @@ end: if (out != NULL) BIO_free_all(out); if (benc != NULL) BIO_free(benc); if (b64 != NULL) BIO_free(b64); +#ifdef ZLIB + if (bzl != NULL) BIO_free(bzl); +#endif if(pass) OPENSSL_free(pass); apps_shutdown(); OPENSSL_EXIT(ret); diff --git a/crypto/openssl/apps/engine.c b/crypto/openssl/apps/engine.c index 17bd81fb79..9a0294398e 100644 --- a/crypto/openssl/apps/engine.c +++ b/crypto/openssl/apps/engine.c @@ -92,7 +92,7 @@ static const char *engine_usage[]={ NULL }; -static void identity(void *ptr) +static void identity(char *ptr) { return; } @@ -148,11 +148,6 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent) if(flags & ENGINE_CMD_FLAG_NUMERIC) { - if(started) - { - BIO_printf(bio_out, "|"); - err = 1; - } BIO_printf(bio_out, "NUMERIC"); started = 1; } @@ -205,7 +200,7 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent char *desc = NULL; int flags; int xpos = 0; - STACK *cmds = NULL; + STACK_OF(OPENSSL_STRING) *cmds = NULL; if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) || ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE, 0, NULL, NULL)) <= 0)) @@ -216,7 +211,7 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent return 1; } - cmds = sk_new_null(); + cmds = sk_OPENSSL_STRING_new_null(); if(!cmds) goto err; @@ -289,15 +284,17 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent BIO_printf(bio_out, "\n"); ret = 1; err: - if(cmds) sk_pop_free(cmds, identity); + if(cmds) sk_OPENSSL_STRING_pop_free(cmds, identity); if(name) OPENSSL_free(name); if(desc) OPENSSL_free(desc); return ret; } -static void util_do_cmds(ENGINE *e, STACK *cmds, BIO *bio_out, const char *indent) +static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds, + BIO *bio_out, const char *indent) { - int loop, res, num = sk_num(cmds); + int loop, res, num = sk_OPENSSL_STRING_num(cmds); + if(num < 0) { BIO_printf(bio_out, "[Error]: internal stack error\n"); @@ -307,7 +304,7 @@ static void util_do_cmds(ENGINE *e, STACK *cmds, BIO *bio_out, const char *inden { char buf[256]; const char *cmd, *arg; - cmd = sk_value(cmds, loop); + cmd = sk_OPENSSL_STRING_value(cmds, loop); res = 1; /* assume success */ /* Check if this command has no ":arg" */ if((arg = strstr(cmd, ":")) == NULL) @@ -347,9 +344,9 @@ int MAIN(int argc, char **argv) const char **pp; int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0; ENGINE *e; - STACK *engines = sk_new_null(); - STACK *pre_cmds = sk_new_null(); - STACK *post_cmds = sk_new_null(); + STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null(); + STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null(); + STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null(); int badops=1; BIO *bio_out=NULL; const char *indent = " "; @@ -396,20 +393,20 @@ int MAIN(int argc, char **argv) argc--; argv++; if (argc == 0) goto skip_arg_loop; - sk_push(pre_cmds,*argv); + sk_OPENSSL_STRING_push(pre_cmds,*argv); } else if (strcmp(*argv,"-post") == 0) { argc--; argv++; if (argc == 0) goto skip_arg_loop; - sk_push(post_cmds,*argv); + sk_OPENSSL_STRING_push(post_cmds,*argv); } else if ((strncmp(*argv,"-h",2) == 0) || (strcmp(*argv,"-?") == 0)) goto skip_arg_loop; else - sk_push(engines,*argv); + sk_OPENSSL_STRING_push(engines,*argv); argc--; argv++; } @@ -424,17 +421,17 @@ skip_arg_loop: goto end; } - if (sk_num(engines) == 0) + if (sk_OPENSSL_STRING_num(engines) == 0) { for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) { - sk_push(engines,(char *)ENGINE_get_id(e)); + sk_OPENSSL_STRING_push(engines,(char *)ENGINE_get_id(e)); } } - for (i=0; i +#include +#include "apps.h" +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, + const char *file, ENGINE *e); +static int genpkey_cb(EVP_PKEY_CTX *ctx); + +#define PROG genpkey_main + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) + { + ENGINE *e = NULL; + char **args, *outfile = NULL; + char *passarg = NULL; + BIO *in = NULL, *out = NULL; + const EVP_CIPHER *cipher = NULL; + int outformat; + int text = 0; + EVP_PKEY *pkey=NULL; + EVP_PKEY_CTX *ctx = NULL; + char *pass = NULL; + int badarg = 0; + int ret = 1, rv; + + int do_param = 0; + + if (bio_err == NULL) + bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); + + if (!load_config(bio_err, NULL)) + goto end; + + outformat=FORMAT_PEM; + + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + args = argv + 1; + while (!badarg && *args && *args[0] == '-') + { + if (!strcmp(*args,"-outform")) + { + if (args[1]) + { + args++; + outformat=str2fmt(*args); + } + else badarg = 1; + } + else if (!strcmp(*args,"-pass")) + { + if (!args[1]) goto bad; + passarg= *(++args); + } +#ifndef OPENSSL_NO_ENGINE + else if (strcmp(*args,"-engine") == 0) + { + if (!args[1]) + goto bad; + e = setup_engine(bio_err, *(++args), 0); + } +#endif + else if (!strcmp (*args, "-paramfile")) + { + if (!args[1]) + goto bad; + args++; + if (do_param == 1) + goto bad; + if (!init_keygen_file(bio_err, &ctx, *args, e)) + goto end; + } + else if (!strcmp (*args, "-out")) + { + if (args[1]) + { + args++; + outfile = *args; + } + else badarg = 1; + } + else if (strcmp(*args,"-algorithm") == 0) + { + if (!args[1]) + goto bad; + if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param)) + goto end; + } + else if (strcmp(*args,"-pkeyopt") == 0) + { + if (!args[1]) + goto bad; + if (!ctx) + { + BIO_puts(bio_err, "No keytype specified\n"); + goto bad; + } + else if (pkey_ctrl_string(ctx, *(++args)) <= 0) + { + BIO_puts(bio_err, "parameter setting error\n"); + ERR_print_errors(bio_err); + goto end; + } + } + else if (strcmp(*args,"-genparam") == 0) + { + if (ctx) + goto bad; + do_param = 1; + } + else if (strcmp(*args,"-text") == 0) + text=1; + else + { + cipher = EVP_get_cipherbyname(*args + 1); + if (!cipher) + { + BIO_printf(bio_err, "Unknown cipher %s\n", + *args + 1); + badarg = 1; + } + if (do_param == 1) + badarg = 1; + } + args++; + } + + if (!ctx) + badarg = 1; + + if (badarg) + { + bad: + BIO_printf(bio_err, "Usage: genpkey [options]\n"); + BIO_printf(bio_err, "where options may be\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); + BIO_printf(bio_err, "-pass arg output file pass phrase source\n"); + BIO_printf(bio_err, "- use cipher to encrypt the key\n"); +#ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); +#endif + BIO_printf(bio_err, "-paramfile file parameters file\n"); + BIO_printf(bio_err, "-algorithm alg the public key algorithm\n"); + BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option \n" + " to value \n"); + BIO_printf(bio_err, "-genparam generate parameters, not key\n"); + BIO_printf(bio_err, "-text print the in text\n"); + BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n"); + goto end; + } + + if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) + { + BIO_puts(bio_err, "Error getting password\n"); + goto end; + } + + if (outfile) + { + if (!(out = BIO_new_file (outfile, "wb"))) + { + BIO_printf(bio_err, + "Can't open output file %s\n", outfile); + goto end; + } + } + else + { + out = BIO_new_fp (stdout, BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } + + EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); + EVP_PKEY_CTX_set_app_data(ctx, bio_err); + + if (do_param) + { + if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) + { + BIO_puts(bio_err, "Error generating parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + else + { + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + { + BIO_puts(bio_err, "Error generating key\n"); + ERR_print_errors(bio_err); + goto end; + } + } + + if (do_param) + rv = PEM_write_bio_Parameters(out, pkey); + else if (outformat == FORMAT_PEM) + rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, + NULL, pass); + else if (outformat == FORMAT_ASN1) + rv = i2d_PrivateKey_bio(out, pkey); + else + { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + + if (rv <= 0) + { + BIO_puts(bio_err, "Error writing key\n"); + ERR_print_errors(bio_err); + } + + if (text) + { + if (do_param) + rv = EVP_PKEY_print_params(out, pkey, 0, NULL); + else + rv = EVP_PKEY_print_private(out, pkey, 0, NULL); + + if (rv <= 0) + { + BIO_puts(bio_err, "Error printing key\n"); + ERR_print_errors(bio_err); + } + } + + ret = 0; + + end: + if (pkey) + EVP_PKEY_free(pkey); + if (ctx) + EVP_PKEY_CTX_free(ctx); + if (out) + BIO_free_all(out); + BIO_free(in); + if (pass) + OPENSSL_free(pass); + + return ret; + } + +static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, + const char *file, ENGINE *e) + { + BIO *pbio; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + if (*pctx) + { + BIO_puts(err, "Parameters already set!\n"); + return 0; + } + + pbio = BIO_new_file(file, "r"); + if (!pbio) + { + BIO_printf(err, "Can't open parameter file %s\n", file); + return 0; + } + + pkey = PEM_read_bio_Parameters(pbio, NULL); + BIO_free(pbio); + + if (!pkey) + { + BIO_printf(bio_err, "Error reading parameter file %s\n", file); + return 0; + } + + ctx = EVP_PKEY_CTX_new(pkey, e); + if (!ctx) + goto err; + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + EVP_PKEY_free(pkey); + *pctx = ctx; + return 1; + + err: + BIO_puts(err, "Error initializing context\n"); + ERR_print_errors(err); + if (ctx) + EVP_PKEY_CTX_free(ctx); + if (pkey) + EVP_PKEY_free(pkey); + return 0; + + } + +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, + const char *algname, ENGINE *e, int do_param) + { + EVP_PKEY_CTX *ctx = NULL; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng = NULL; + int pkey_id; + + if (*pctx) + { + BIO_puts(err, "Algorithm already set!\n"); + return 0; + } + + ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); + +#ifndef OPENSSL_NO_ENGINE + if (!ameth && e) + ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); +#endif + + if (!ameth) + { + BIO_printf(bio_err, "Algorithm %s not found\n", algname); + return 0; + } + + ERR_clear_error(); + + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); +#ifndef OPENSSL_NO_ENGINE + if (tmpeng) + ENGINE_finish(tmpeng); +#endif + ctx = EVP_PKEY_CTX_new_id(pkey_id, e); + + if (!ctx) + goto err; + if (do_param) + { + if (EVP_PKEY_paramgen_init(ctx) <= 0) + goto err; + } + else + { + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + } + + *pctx = ctx; + return 1; + + err: + BIO_printf(err, "Error initializing %s context\n", algname); + ERR_print_errors(err); + if (ctx) + EVP_PKEY_CTX_free(ctx); + return 0; + + } + +static int genpkey_cb(EVP_PKEY_CTX *ctx) + { + char c='*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p; + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (p == 0) c='.'; + if (p == 1) c='+'; + if (p == 2) c='*'; + if (p == 3) c='\n'; + BIO_write(b,&c,1); + (void)BIO_flush(b); +#ifdef LINT + p=n; +#endif + return 1; + } diff --git a/crypto/openssl/apps/genrsa.c b/crypto/openssl/apps/genrsa.c index 5759acbf9b..37e9310910 100644 --- a/crypto/openssl/apps/genrsa.c +++ b/crypto/openssl/apps/genrsa.c @@ -95,7 +95,6 @@ int MAIN(int argc, char **argv) int ret=1; int i,num=DEFBITS; long l; - int use_x931 = 0; const EVP_CIPHER *enc=NULL; unsigned long f4=RSA_F4; char *outfile=NULL; @@ -139,8 +138,6 @@ int MAIN(int argc, char **argv) f4=3; else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0) f4=RSA_F4; - else if (strcmp(*argv,"-x931") == 0) - use_x931 = 1; #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { @@ -268,22 +265,15 @@ bad: BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n", num); - +#ifdef OPENSSL_NO_ENGINE rsa = RSA_new(); +#else + rsa = RSA_new_method(e); +#endif if (!rsa) goto err; - if (use_x931) - { - BIGNUM *pubexp; - pubexp = BN_new(); - if (!BN_set_word(pubexp, f4)) - goto err; - if (!RSA_X931_generate_key_ex(rsa, num, pubexp, &cb)) - goto err; - BN_free(pubexp); - } - else if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) + if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) goto err; app_RAND_write_file(NULL, bio_err); diff --git a/crypto/openssl/apps/ocsp.c b/crypto/openssl/apps/ocsp.c index 251044d77f..01847dfad7 100644 --- a/crypto/openssl/apps/ocsp.c +++ b/crypto/openssl/apps/ocsp.c @@ -56,25 +56,53 @@ * */ #ifndef OPENSSL_NO_OCSP + +#ifdef OPENSSL_SYS_VMS +#define _XOPEN_SOURCE_EXTENDED /* So fd_set and friends get properly defined + on OpenVMS */ +#endif + #define USE_SOCKETS + #include #include #include +#include #include "apps.h" /* needs to be included before the openssl headers! */ #include -#include +#include #include - +#include +#include +#include +#include + +#if defined(NETWARE_CLIB) +# ifdef NETWARE_BSDSOCK +# include +# include +# else +# include +# endif +#elif defined(NETWARE_LIBC) +# ifdef NETWARE_BSDSOCK +# include +# else +# include +# endif +#endif + /* Maximum leeway in validity period: default 5 minutes */ #define MAX_VALIDITY_PERIOD (5 * 60) -static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); -static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, - STACK *names, STACK_OF(OCSP_CERTID) *ids, - long nsec, long maxage); + STACK_OF(OPENSSL_STRING) *names, + STACK_OF(OCSP_CERTID) *ids, long nsec, + long maxage); static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, X509 *ca, X509 *rcert, EVP_PKEY *rkey, @@ -86,6 +114,7 @@ static BIO *init_responder(char *port); static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port); static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, + STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout); #undef PROG @@ -104,6 +133,7 @@ int MAIN(int argc, char **argv) char *rsignfile = NULL, *rkeyfile = NULL; char *outfile = NULL; int add_nonce = 1, noverify = 0, use_ssl = -1; + STACK_OF(CONF_VALUE) *headers = NULL; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; OCSP_BASICRESP *bs = NULL; @@ -126,7 +156,7 @@ int MAIN(int argc, char **argv) int badarg = 0; int i; int ignore_err = 0; - STACK *reqnames = NULL; + STACK_OF(OPENSSL_STRING) *reqnames = NULL; STACK_OF(OCSP_CERTID) *ids = NULL; X509 *rca_cert = NULL; @@ -134,6 +164,7 @@ int MAIN(int argc, char **argv) char *rca_filename = NULL; CA_DB *rdb = NULL; int nmin = 0, ndays = -1; + const EVP_MD *cert_id_md = NULL; if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); @@ -142,7 +173,7 @@ int MAIN(int argc, char **argv) SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); args = argv + 1; - reqnames = sk_new_null(); + reqnames = sk_OPENSSL_STRING_new_null(); ids = sk_OCSP_CERTID_new_null(); while (!badarg && *args && *args[0] == '-') { @@ -202,6 +233,16 @@ int MAIN(int argc, char **argv) } else badarg = 1; } + else if (!strcmp(*args, "-header")) + { + if (args[1] && args[2]) + { + if (!X509V3_add_value(args[1], args[2], &headers)) + goto end; + args += 2; + } + else badarg = 1; + } else if (!strcmp(*args, "-ignore_err")) ignore_err = 1; else if (!strcmp(*args, "-noverify")) @@ -401,9 +442,10 @@ int MAIN(int argc, char **argv) cert = load_cert(bio_err, *args, FORMAT_PEM, NULL, e, "certificate"); if(!cert) goto end; - if(!add_ocsp_cert(&req, cert, issuer, ids)) + if (!cert_id_md) cert_id_md = EVP_sha1(); + if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) goto end; - if(!sk_push(reqnames, *args)) + if(!sk_OPENSSL_STRING_push(reqnames, *args)) goto end; } else badarg = 1; @@ -413,9 +455,10 @@ int MAIN(int argc, char **argv) if (args[1]) { args++; - if(!add_ocsp_serial(&req, *args, issuer, ids)) + if (!cert_id_md) cert_id_md = EVP_sha1(); + if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids)) goto end; - if(!sk_push(reqnames, *args)) + if(!sk_OPENSSL_STRING_push(reqnames, *args)) goto end; } else badarg = 1; @@ -515,7 +558,10 @@ int MAIN(int argc, char **argv) } else badarg = 1; } - else badarg = 1; + else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL) + { + badarg = 1; + } args++; } @@ -571,6 +617,7 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "-ndays n number of days before next update\n"); BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); + BIO_printf (bio_err, "- use specified digest in the request"); goto end; } @@ -677,7 +724,8 @@ int MAIN(int argc, char **argv) "signer private key"); if (!key) goto end; - if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags)) + + if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags)) { BIO_printf(bio_err, "Error signing OCSP request\n"); goto end; @@ -721,7 +769,7 @@ int MAIN(int argc, char **argv) { #ifndef OPENSSL_NO_SOCK resp = process_responder(bio_err, req, host, path, - port, use_ssl, req_timeout); + port, use_ssl, headers, req_timeout); if (!resp) goto end; #else @@ -866,10 +914,11 @@ end: OCSP_REQUEST_free(req); OCSP_RESPONSE_free(resp); OCSP_BASICRESP_free(bs); - sk_free(reqnames); + sk_OPENSSL_STRING_free(reqnames); sk_OCSP_CERTID_free(ids); sk_X509_pop_free(sign_other, X509_free); sk_X509_pop_free(verify_other, X509_free); + sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); if (use_ssl != -1) { @@ -881,7 +930,7 @@ end: OPENSSL_EXIT(ret); } -static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer, STACK_OF(OCSP_CERTID) *ids) { OCSP_CERTID *id; @@ -892,7 +941,7 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, } if(!*req) *req = OCSP_REQUEST_new(); if(!*req) goto err; - id = OCSP_cert_to_id(NULL, cert, issuer); + id = OCSP_cert_to_id(cert_id_md, cert, issuer); if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; if(!OCSP_request_add0_id(*req, id)) goto err; return 1; @@ -902,7 +951,7 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, return 0; } -static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids) { OCSP_CERTID *id; @@ -924,7 +973,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, BIO_printf(bio_err, "Error converting serial number %s\n", serial); return 0; } - id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); + id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); ASN1_INTEGER_free(sno); if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; if(!OCSP_request_add0_id(*req, id)) goto err; @@ -936,8 +985,9 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, } static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, - STACK *names, STACK_OF(OCSP_CERTID) *ids, - long nsec, long maxage) + STACK_OF(OPENSSL_STRING) *names, + STACK_OF(OCSP_CERTID) *ids, long nsec, + long maxage) { OCSP_CERTID *id; char *name; @@ -947,13 +997,13 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; - if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids)) + if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids)) return 1; for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { id = sk_OCSP_CERTID_value(ids, i); - name = sk_value(names, i); + name = sk_OPENSSL_STRING_value(names, i); BIO_printf(out, "%s: ", name); if(!OCSP_resp_find_status(bs, id, &status, &reason, @@ -1010,7 +1060,6 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db OCSP_BASICRESP *bs = NULL; int i, id_count, ret = 1; - id_count = OCSP_request_onereq_count(req); if (id_count <= 0) @@ -1019,7 +1068,6 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db goto end; } - ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca); bs = OCSP_BASICRESP_new(); thisupd = X509_gmtime_adj(NULL, 0); @@ -1032,8 +1080,23 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db OCSP_ONEREQ *one; ASN1_INTEGER *serial; char **inf; + ASN1_OBJECT *cert_id_md_oid; + const EVP_MD *cert_id_md; one = OCSP_request_onereq_get0(req, i); cid = OCSP_onereq_get0_id(one); + + OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid); + + cert_id_md = EVP_get_digestbyobj(cert_id_md_oid); + if (! cert_id_md) + { + *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, + NULL); + goto end; + } + if (ca_id) OCSP_CERTID_free(ca_id); + ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca); + /* Is this request about our CA? */ if (OCSP_id_issuer_cmp(ca_id, cid)) { @@ -1078,8 +1141,8 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db } OCSP_copy_nonce(bs, req); - - OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags); + + OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags); *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); @@ -1211,10 +1274,12 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) } static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, + STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout) { int fd; int rv; + int i; OCSP_REQ_CTX *ctx = NULL; OCSP_RESPONSE *rsp = NULL; fd_set confds; @@ -1231,16 +1296,13 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, return NULL; } - if (req_timeout == -1) - return OCSP_sendreq_bio(cbio, path, req); - if (BIO_get_fd(cbio, &fd) <= 0) { BIO_puts(err, "Can't get connection fd\n"); goto err; } - if (rv <= 0) + if (req_timeout != -1 && rv <= 0) { FD_ZERO(&confds); openssl_fdset(fd, &confds); @@ -1255,15 +1317,27 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, } - ctx = OCSP_sendreq_new(cbio, path, req, -1); + ctx = OCSP_sendreq_new(cbio, path, NULL, -1); if (!ctx) return NULL; + + for (i = 0; i < sk_CONF_VALUE_num(headers); i++) + { + CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); + if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) + goto err; + } + + if (!OCSP_REQ_CTX_set1_req(ctx, req)) + goto err; for (;;) { rv = OCSP_sendreq_nbio(&rsp, ctx); if (rv != -1) break; + if (req_timeout == -1) + continue; FD_ZERO(&confds); openssl_fdset(fd, &confds); tv.tv_usec = 0; @@ -1287,7 +1361,7 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, BIO_puts(err, "Select error\n"); break; } - + } err: if (ctx) @@ -1298,6 +1372,7 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, char *host, char *path, char *port, int use_ssl, + STACK_OF(CONF_VALUE) *headers, int req_timeout) { BIO *cbio = NULL; @@ -1332,14 +1407,14 @@ OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } - resp = query_responder(err, cbio, path, req, req_timeout); + resp = query_responder(err, cbio, path, headers, req, req_timeout); if (!resp) BIO_printf(bio_err, "Error querying OCSP responsder\n"); end: - if (ctx) - SSL_CTX_free(ctx); if (cbio) BIO_free_all(cbio); + if (ctx) + SSL_CTX_free(ctx); return resp; } diff --git a/crypto/openssl/apps/openssl.c b/crypto/openssl/apps/openssl.c index 480fef9e14..851e639735 100644 --- a/crypto/openssl/apps/openssl.c +++ b/crypto/openssl/apps/openssl.c @@ -135,19 +135,17 @@ * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper * functions. */ -/* static unsigned long MS_CALLBACK hash(FUNCTION *a); */ -static unsigned long MS_CALLBACK hash(const void *a_void); -/* static int MS_CALLBACK cmp(FUNCTION *a,FUNCTION *b); */ -static int MS_CALLBACK cmp(const void *a_void,const void *b_void); -static LHASH *prog_init(void ); -static int do_cmd(LHASH *prog,int argc,char *argv[]); +static LHASH_OF(FUNCTION) *prog_init(void ); +static int do_cmd(LHASH_OF(FUNCTION) *prog,int argc,char *argv[]); +static void list_pkey(BIO *out); +static void list_cipher(BIO *out); +static void list_md(BIO *out); char *default_config_file=NULL; /* Make sure there is only one when MONOLITH is defined */ #ifdef MONOLITH CONF *config=NULL; BIO *bio_err=NULL; -int in_FIPS_mode=0; #endif @@ -227,28 +225,12 @@ int main(int Argc, char *Argv[]) int n,i,ret=0; int argc; char **argv,*p; - LHASH *prog=NULL; + LHASH_OF(FUNCTION) *prog=NULL; long errline; arg.data=NULL; arg.count=0; - in_FIPS_mode = 0; - - if(getenv("OPENSSL_FIPS")) { -#ifdef OPENSSL_FIPS - if (!FIPS_mode_set(1)) { - ERR_load_crypto_strings(); - ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); - EXIT(1); - } - in_FIPS_mode = 1; -#else - fprintf(stderr, "FIPS mode not supported.\n"); - EXIT(1); -#endif - } - if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); @@ -290,9 +272,21 @@ int main(int Argc, char *Argv[]) i=NCONF_load(config,p,&errline); if (i == 0) { - NCONF_free(config); - config = NULL; - ERR_clear_error(); + if (ERR_GET_REASON(ERR_peek_last_error()) + == CONF_R_NO_SUCH_FILE) + { + BIO_printf(bio_err, + "WARNING: can't open config file: %s\n",p); + ERR_clear_error(); + NCONF_free(config); + config = NULL; + } + else + { + ERR_print_errors(bio_err); + NCONF_free(config); + exit(1); + } } prog=prog_init(); @@ -301,7 +295,7 @@ int main(int Argc, char *Argv[]) program_name(Argv[0],pname,sizeof pname); f.name=pname; - fp=(FUNCTION *)lh_retrieve(prog,&f); + fp=lh_FUNCTION_retrieve(prog,&f); if (fp != NULL) { Argv[0]=pname; @@ -368,7 +362,7 @@ end: NCONF_free(config); config=NULL; } - if (prog != NULL) lh_free(prog); + if (prog != NULL) lh_FUNCTION_free(prog); if (arg.data != NULL) OPENSSL_free(arg.data); apps_shutdown(); @@ -384,9 +378,13 @@ end: #define LIST_STANDARD_COMMANDS "list-standard-commands" #define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands" +#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms" #define LIST_CIPHER_COMMANDS "list-cipher-commands" +#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms" +#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms" + -static int do_cmd(LHASH *prog, int argc, char *argv[]) +static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) { FUNCTION f,*fp; int i,ret=1,tp,nl; @@ -394,7 +392,22 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) if ((argc <= 0) || (argv[0] == NULL)) { ret=0; goto end; } f.name=argv[0]; - fp=(FUNCTION *)lh_retrieve(prog,&f); + fp=lh_FUNCTION_retrieve(prog,&f); + if (fp == NULL) + { + if (EVP_get_digestbyname(argv[0])) + { + f.type = FUNC_TYPE_MD; + f.func = dgst_main; + fp = &f; + } + else if (EVP_get_cipherbyname(argv[0])) + { + f.type = FUNC_TYPE_CIPHER; + f.func = enc_main; + fp = &f; + } + } if (fp != NULL) { ret=fp->func(argc,argv); @@ -409,7 +422,7 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) } #endif f.name=argv[0]+3; - ret = (lh_retrieve(prog,&f) != NULL); + ret = (lh_FUNCTION_retrieve(prog,&f) != NULL); if (!ret) BIO_printf(bio_stdout, "%s\n", argv[0]); else @@ -427,7 +440,10 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) } else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) || (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) || - (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0)) + (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) || + (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) || + (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) || + (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)) { int list_type; BIO *bio_stdout; @@ -436,6 +452,12 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) list_type = FUNC_TYPE_GENERAL; else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) list_type = FUNC_TYPE_MD; + else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) + list_type = FUNC_TYPE_MD_ALG; + else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0) + list_type = FUNC_TYPE_PKEY; + else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) + list_type = FUNC_TYPE_CIPHER_ALG; else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */ list_type = FUNC_TYPE_CIPHER; bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE); @@ -445,10 +467,23 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) bio_stdout = BIO_push(tmpbio, bio_stdout); } #endif - - for (fp=functions; fp->name != NULL; fp++) - if (fp->type == list_type) - BIO_printf(bio_stdout, "%s\n", fp->name); + + if (!load_config(bio_err, NULL)) + goto end; + + if (list_type == FUNC_TYPE_PKEY) + list_pkey(bio_stdout); + if (list_type == FUNC_TYPE_MD_ALG) + list_md(bio_stdout); + if (list_type == FUNC_TYPE_CIPHER_ALG) + list_cipher(bio_stdout); + else + { + for (fp=functions; fp->name != NULL; fp++) + if (fp->type == list_type) + BIO_printf(bio_stdout, "%s\n", + fp->name); + } BIO_free_all(bio_stdout); ret=0; goto end; @@ -511,9 +546,94 @@ static int SortFnByName(const void *_f1,const void *_f2) return strcmp(f1->name,f2->name); } -static LHASH *prog_init(void) +static void list_pkey(BIO *out) { - LHASH *ret; + int i; + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) + { + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id, pkey_base_id, pkey_flags; + const char *pinfo, *pem_str; + ameth = EVP_PKEY_asn1_get0(i); + EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, + &pinfo, &pem_str, ameth); + if (pkey_flags & ASN1_PKEY_ALIAS) + { + BIO_printf(out, "Name: %s\n", + OBJ_nid2ln(pkey_id)); + BIO_printf(out, "\tType: Alias to %s\n", + OBJ_nid2ln(pkey_base_id)); + } + else + { + BIO_printf(out, "Name: %s\n", pinfo); + BIO_printf(out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? + "External" : "Builtin"); + BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); + if (pem_str == NULL) + pem_str = "(none)"; + BIO_printf(out, "\tPEM string: %s\n", pem_str); + } + + } + } + +static void list_cipher_fn(const EVP_CIPHER *c, + const char *from, const char *to, void *arg) + { + if (c) + BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); + else + { + if (!from) + from = ""; + if (!to) + to = ""; + BIO_printf(arg, "%s => %s\n", from, to); + } + } + +static void list_cipher(BIO *out) + { + EVP_CIPHER_do_all_sorted(list_cipher_fn, out); + } + +static void list_md_fn(const EVP_MD *m, + const char *from, const char *to, void *arg) + { + if (m) + BIO_printf(arg, "%s\n", EVP_MD_name(m)); + else + { + if (!from) + from = ""; + if (!to) + to = ""; + BIO_printf(arg, "%s => %s\n", from, to); + } + } + +static void list_md(BIO *out) + { + EVP_MD_do_all_sorted(list_md_fn, out); + } + +static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b) + { + return strncmp(a->name,b->name,8); + } +static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION) + +static unsigned long MS_CALLBACK function_hash(const FUNCTION *a) + { + return lh_strhash(a->name); + } +static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION) + +static LHASH_OF(FUNCTION) *prog_init(void) + { + LHASH_OF(FUNCTION) *ret; FUNCTION *f; size_t i; @@ -522,23 +642,11 @@ static LHASH *prog_init(void) ; qsort(functions,i,sizeof *functions,SortFnByName); - if ((ret=lh_new(hash, cmp)) == NULL) + if ((ret=lh_FUNCTION_new()) == NULL) return(NULL); for (f=functions; f->name != NULL; f++) - lh_insert(ret,f); + (void)lh_FUNCTION_insert(ret,f); return(ret); } -/* static int MS_CALLBACK cmp(FUNCTION *a, FUNCTION *b) */ -static int MS_CALLBACK cmp(const void *a_void, const void *b_void) - { - return(strncmp(((const FUNCTION *)a_void)->name, - ((const FUNCTION *)b_void)->name,8)); - } - -/* static unsigned long MS_CALLBACK hash(FUNCTION *a) */ -static unsigned long MS_CALLBACK hash(const void *a_void) - { - return(lh_strhash(((const FUNCTION *)a_void)->name)); - } diff --git a/crypto/openssl/apps/openssl.cnf b/crypto/openssl/apps/openssl.cnf index 9e59020c17..9d2cd5bfa5 100644 --- a/crypto/openssl/apps/openssl.cnf +++ b/crypto/openssl/apps/openssl.cnf @@ -21,12 +21,17 @@ oid_section = new_oids [ new_oids ] -# We can add new OIDs in here for use by 'ca' and 'req'. +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. # Add a simple OID like this: # testoid1=1.2.3.4 # Or use config file substitution like this: # testoid2=${testoid1}.5.6 +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + #################################################################### [ ca ] default_ca = CA_default # The default ca section @@ -67,7 +72,7 @@ cert_opt = ca_default # Certificate field options default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL -default_md = sha1 # which md to use. +default_md = default # use public key default MD preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look @@ -110,13 +115,12 @@ x509_extensions = v3_ca # The extentions to add to the self signed cert # This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString. -# utf8only: only UTF8Strings. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. -# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings -# so use this option with caution! -string_mask = nombstr +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only # req_extensions = v3_req # The extensions to add to a certificate request @@ -207,6 +211,9 @@ authorityKeyIdentifier=keyid,issuer #nsCaPolicyUrl #nsSslServerName +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + [ v3_req ] # Extensions to add to a certificate request @@ -224,7 +231,7 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid:always,issuer:always +authorityKeyIdentifier=keyid:always,issuer # This is what PKIX recommends but some broken software chokes on critical # extensions. @@ -257,7 +264,7 @@ basicConstraints = CA:true # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. # issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always +authorityKeyIdentifier=keyid:always [ proxy_cert_ext ] # These extensions should be added when creating a proxy certificate @@ -290,7 +297,7 @@ nsComment = "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always +authorityKeyIdentifier=keyid,issuer # This stuff is for subjectAltName and issuerAltname. # Import the email address. @@ -311,3 +318,33 @@ authorityKeyIdentifier=keyid,issuer:always # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./demoCA # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) + +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = md5, sha1 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) diff --git a/crypto/openssl/apps/pkcs12.c b/crypto/openssl/apps/pkcs12.c index 0db0b79765..514a02e0f1 100644 --- a/crypto/openssl/apps/pkcs12.c +++ b/crypto/openssl/apps/pkcs12.c @@ -68,12 +68,6 @@ #include #include -#ifdef OPENSSL_SYS_NETWARE -/* Rename these functions to avoid name clashes on NetWare OS */ -#define uni2asc OPENSSL_uni2asc -#define asc2uni OPENSSL_asc2uni -#endif - #define PROG pkcs12_main const EVP_CIPHER *enc; @@ -94,6 +88,7 @@ int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); int alg_print(BIO *x, X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); +static int set_pbe(BIO *err, int *ppbe, const char *str); int MAIN(int, char **); @@ -117,16 +112,17 @@ int MAIN(int argc, char **argv) int maciter = PKCS12_DEFAULT_ITER; int twopass = 0; int keytype = 0; - int cert_pbe; + int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; int ret = 1; int macver = 1; int noprompt = 0; - STACK *canames = NULL; + STACK_OF(OPENSSL_STRING) *canames = NULL; char *cpass = NULL, *mpass = NULL; char *passargin = NULL, *passargout = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL; char *inrand = NULL; + char *macalg = NULL; char *CApath = NULL, *CAfile = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; @@ -134,13 +130,6 @@ int MAIN(int argc, char **argv) apps_startup(); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - else -#endif - cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; - enc = EVP_des_ede3_cbc(); if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); @@ -191,33 +180,18 @@ int MAIN(int argc, char **argv) maciter = 1; else if (!strcmp (*args, "-nomac")) maciter = -1; + else if (!strcmp (*args, "-macalg")) + if (args[1]) { + args++; + macalg = *args; + } else badarg = 1; else if (!strcmp (*args, "-nodes")) enc=NULL; else if (!strcmp (*args, "-certpbe")) { - if (args[1]) { - args++; - if (!strcmp(*args, "NONE")) - cert_pbe = -1; - else - cert_pbe=OBJ_txt2nid(*args); - if(cert_pbe == NID_undef) { - BIO_printf(bio_err, - "Unknown PBE algorithm %s\n", *args); - badarg = 1; - } - } else badarg = 1; + if (!set_pbe(bio_err, &cert_pbe, *++args)) + badarg = 1; } else if (!strcmp (*args, "-keypbe")) { - if (args[1]) { - args++; - if (!strcmp(*args, "NONE")) - key_pbe = -1; - else - key_pbe=OBJ_txt2nid(*args); - if(key_pbe == NID_undef) { - BIO_printf(bio_err, - "Unknown PBE algorithm %s\n", *args); - badarg = 1; - } - } else badarg = 1; + if (!set_pbe(bio_err, &key_pbe, *++args)) + badarg = 1; } else if (!strcmp (*args, "-rand")) { if (args[1]) { args++; @@ -248,8 +222,8 @@ int MAIN(int argc, char **argv) } else if (!strcmp (*args, "-caname")) { if (args[1]) { args++; - if (!canames) canames = sk_new_null(); - sk_push(canames, *args); + if (!canames) canames = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(canames, *args); } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { @@ -338,11 +312,14 @@ int MAIN(int argc, char **argv) #endif BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); + BIO_printf (bio_err, "-nomaciter don't use MAC iteration\n"); BIO_printf (bio_err, "-maciter use MAC iteration\n"); + BIO_printf (bio_err, "-nomac don't generate MAC\n"); BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); + BIO_printf (bio_err, "-macalg alg digest algorithm used in MAC (default SHA1)\n"); BIO_printf (bio_err, "-keyex set MS key exchange type\n"); BIO_printf (bio_err, "-keysig set MS key signature type\n"); BIO_printf (bio_err, "-password p set import/export password source\n"); @@ -354,8 +331,8 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); - BIO_printf(bio_err, "-LMK Add local machine keyset attribute to private key\n"); + BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); + BIO_printf(bio_err, "-LMK Add local machine keyset attribute to private key\n"); goto end; } @@ -445,6 +422,7 @@ int MAIN(int argc, char **argv) EVP_PKEY *key = NULL; X509 *ucert = NULL, *x = NULL; STACK_OF(X509) *certs=NULL; + const EVP_MD *macmd = NULL; unsigned char *catmp = NULL; int i; @@ -571,9 +549,9 @@ int MAIN(int argc, char **argv) /* Add any CA names */ - for (i = 0; i < sk_num(canames); i++) + for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { - catmp = (unsigned char *)sk_value(canames, i); + catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); X509_alias_set1(sk_X509_value(certs, i), catmp, -1); } @@ -611,8 +589,18 @@ int MAIN(int argc, char **argv) goto export_end; } + if (macalg) + { + macmd = EVP_get_digestbyname(macalg); + if (!macmd) + { + BIO_printf(bio_err, "Unknown digest algorithm %s\n", + macalg); + } + } + if (maciter != -1) - PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL); + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); @@ -699,7 +687,7 @@ int MAIN(int argc, char **argv) #endif BIO_free(in); BIO_free_all(out); - if (canames) sk_free(canames); + if (canames) sk_OPENSSL_STRING_free(canames); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); @@ -935,7 +923,7 @@ int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name) av = sk_ASN1_TYPE_value(attr->value.set, 0); switch(av->type) { case V_ASN1_BMPSTRING: - value = uni2asc(av->value.bmpstring->data, + value = OPENSSL_uni2asc(av->value.bmpstring->data, av->value.bmpstring->length); BIO_printf(out, "%s\n", value); OPENSSL_free(value); @@ -968,4 +956,22 @@ void hex_prin(BIO *out, unsigned char *buf, int len) for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]); } +static int set_pbe(BIO *err, int *ppbe, const char *str) + { + if (!str) + return 0; + if (!strcmp(str, "NONE")) + { + *ppbe = -1; + return 1; + } + *ppbe=OBJ_txt2nid(str); + if (*ppbe == NID_undef) + { + BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); + return 0; + } + return 1; + } + #endif diff --git a/crypto/openssl/apps/pkcs7.c b/crypto/openssl/apps/pkcs7.c index da4dbe7a07..86d31b99a7 100644 --- a/crypto/openssl/apps/pkcs7.c +++ b/crypto/openssl/apps/pkcs7.c @@ -90,7 +90,7 @@ int MAIN(int argc, char **argv) BIO *in=NULL,*out=NULL; int informat,outformat; char *infile,*outfile,*prog; - int print_certs=0,text=0,noout=0; + int print_certs=0,text=0,noout=0,p7_print=0; int ret=1; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; @@ -139,6 +139,8 @@ int MAIN(int argc, char **argv) noout=1; else if (strcmp(*argv,"-text") == 0) text=1; + else if (strcmp(*argv,"-print") == 0) + p7_print=1; else if (strcmp(*argv,"-print_certs") == 0) print_certs=1; #ifndef OPENSSL_NO_ENGINE @@ -238,6 +240,9 @@ bad: } } + if (p7_print) + PKCS7_print_ctx(out, p7, 0, NULL); + if (print_certs) { STACK_OF(X509) *certs=NULL; diff --git a/crypto/openssl/apps/pkcs8.c b/crypto/openssl/apps/pkcs8.c index 9633a149bc..7edeb179dd 100644 --- a/crypto/openssl/apps/pkcs8.c +++ b/crypto/openssl/apps/pkcs8.c @@ -80,11 +80,12 @@ int MAIN(int argc, char **argv) int informat, outformat; int p8_broken = PKCS8_OK; int nocrypt = 0; - X509_SIG *p8; - PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8 = NULL; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey=NULL; char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; int badarg = 0; + int ret = 1; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif @@ -225,7 +226,7 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif - return 1; + goto end; } #ifndef OPENSSL_NO_ENGINE @@ -235,7 +236,7 @@ int MAIN(int argc, char **argv) if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); - return 1; + goto end; } if ((pbe_nid == -1) && !cipher) @@ -247,7 +248,7 @@ int MAIN(int argc, char **argv) { BIO_printf(bio_err, "Can't open input file %s\n", infile); - return (1); + goto end; } } else @@ -259,7 +260,7 @@ int MAIN(int argc, char **argv) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); - return (1); + goto end; } } else @@ -274,21 +275,15 @@ int MAIN(int argc, char **argv) } if (topk8) { - BIO_free(in); /* Not needed in this section */ pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); if (!pkey) - { - BIO_free_all(out); - return 1; - } + goto end; if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); - EVP_PKEY_free(pkey); - BIO_free_all(out); - return 1; + goto end; } if (nocrypt) { @@ -299,10 +294,7 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Bad format specified for key\n"); - PKCS8_PRIV_KEY_INFO_free(p8inf); - EVP_PKEY_free(pkey); - BIO_free_all(out); - return (1); + goto end; } } else @@ -313,12 +305,7 @@ int MAIN(int argc, char **argv) { p8pass = pass; if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1)) - { - PKCS8_PRIV_KEY_INFO_free(p8inf); - EVP_PKEY_free(pkey); - BIO_free_all(out); - return (1); - } + goto end; } app_RAND_load_file(NULL, bio_err, 0); if (!(p8 = PKCS8_encrypt(pbe_nid, cipher, @@ -327,10 +314,7 @@ int MAIN(int argc, char **argv) { BIO_printf(bio_err, "Error encrypting key\n"); ERR_print_errors(bio_err); - PKCS8_PRIV_KEY_INFO_free(p8inf); - EVP_PKEY_free(pkey); - BIO_free_all(out); - return (1); + goto end; } app_RAND_write_file(NULL, bio_err); if (outformat == FORMAT_PEM) @@ -340,22 +324,12 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Bad format specified for key\n"); - PKCS8_PRIV_KEY_INFO_free(p8inf); - EVP_PKEY_free(pkey); - BIO_free_all(out); - return (1); + goto end; } - X509_SIG_free(p8); } - PKCS8_PRIV_KEY_INFO_free (p8inf); - EVP_PKEY_free(pkey); - BIO_free_all(out); - if (passin) - OPENSSL_free(passin); - if (passout) - OPENSSL_free(passout); - return (0); + ret = 0; + goto end; } if (nocrypt) @@ -367,7 +341,7 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Bad format specified for key\n"); - return (1); + goto end; } } else @@ -379,14 +353,14 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Bad format specified for key\n"); - return (1); + goto end; } if (!p8) { BIO_printf (bio_err, "Error reading key\n"); ERR_print_errors(bio_err); - return (1); + goto end; } if (passin) p8pass = passin; @@ -396,21 +370,20 @@ int MAIN(int argc, char **argv) EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0); } p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); - X509_SIG_free(p8); } if (!p8inf) { BIO_printf(bio_err, "Error decrypting key\n"); ERR_print_errors(bio_err); - return (1); + goto end; } if (!(pkey = EVP_PKCS82PKEY(p8inf))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); - return (1); + goto end; } if (p8inf->broken) @@ -430,13 +403,16 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "DSA public key include in PrivateKey\n"); break; + case PKCS8_NEG_PRIVKEY: + BIO_printf(bio_err, "DSA private key value is negative\n"); + break; + default: BIO_printf(bio_err, "Unknown broken type\n"); break; } } - PKCS8_PRIV_KEY_INFO_free(p8inf); if (outformat == FORMAT_PEM) PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); else if (outformat == FORMAT_ASN1) @@ -444,10 +420,13 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Bad format specified for key\n"); - return (1); + goto end; } + ret = 0; end: + X509_SIG_free(p8); + PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); @@ -456,5 +435,5 @@ int MAIN(int argc, char **argv) if (passout) OPENSSL_free(passout); - return (0); + return ret; } diff --git a/crypto/openssl/apps/pkey.c b/crypto/openssl/apps/pkey.c new file mode 100644 index 0000000000..17e6702fb1 --- /dev/null +++ b/crypto/openssl/apps/pkey.c @@ -0,0 +1,284 @@ +/* apps/pkey.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include +#include "apps.h" +#include +#include +#include + +#define PROG pkey_main + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) + { + ENGINE *e = NULL; + char **args, *infile = NULL, *outfile = NULL; + char *passargin = NULL, *passargout = NULL; + BIO *in = NULL, *out = NULL; + const EVP_CIPHER *cipher = NULL; + int informat, outformat; + int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; + EVP_PKEY *pkey=NULL; + char *passin = NULL, *passout = NULL; + int badarg = 0; +#ifndef OPENSSL_NO_ENGINE + char *engine=NULL; +#endif + int ret = 1; + + if (bio_err == NULL) + bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); + + if (!load_config(bio_err, NULL)) + goto end; + + informat=FORMAT_PEM; + outformat=FORMAT_PEM; + + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + args = argv + 1; + while (!badarg && *args && *args[0] == '-') + { + if (!strcmp(*args,"-inform")) + { + if (args[1]) + { + args++; + informat=str2fmt(*args); + } + else badarg = 1; + } + else if (!strcmp(*args,"-outform")) + { + if (args[1]) + { + args++; + outformat=str2fmt(*args); + } + else badarg = 1; + } + else if (!strcmp(*args,"-passin")) + { + if (!args[1]) goto bad; + passargin= *(++args); + } + else if (!strcmp(*args,"-passout")) + { + if (!args[1]) goto bad; + passargout= *(++args); + } +#ifndef OPENSSL_NO_ENGINE + else if (strcmp(*args,"-engine") == 0) + { + if (!args[1]) goto bad; + engine= *(++args); + } +#endif + else if (!strcmp (*args, "-in")) + { + if (args[1]) + { + args++; + infile = *args; + } + else badarg = 1; + } + else if (!strcmp (*args, "-out")) + { + if (args[1]) + { + args++; + outfile = *args; + } + else badarg = 1; + } + else if (strcmp(*args,"-pubin") == 0) + { + pubin=1; + pubout=1; + pubtext=1; + } + else if (strcmp(*args,"-pubout") == 0) + pubout=1; + else if (strcmp(*args,"-text_pub") == 0) + { + pubtext=1; + text=1; + } + else if (strcmp(*args,"-text") == 0) + text=1; + else if (strcmp(*args,"-noout") == 0) + noout=1; + else + { + cipher = EVP_get_cipherbyname(*args + 1); + if (!cipher) + { + BIO_printf(bio_err, "Unknown cipher %s\n", + *args + 1); + badarg = 1; + } + } + args++; + } + + if (badarg) + { + bad: + BIO_printf(bio_err, "Usage pkey [options]\n"); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); + BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); + BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-passout arg output file pass phrase source\n"); +#ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); +#endif + return 1; + } + +#ifndef OPENSSL_NO_ENGINE + e = setup_engine(bio_err, engine, 0); +#endif + + if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) + { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + + if (outfile) + { + if (!(out = BIO_new_file (outfile, "wb"))) + { + BIO_printf(bio_err, + "Can't open output file %s\n", outfile); + goto end; + } + } + else + { + out = BIO_new_fp (stdout, BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } + + if (pubin) + pkey = load_pubkey(bio_err, infile, informat, 1, + passin, e, "Public Key"); + else + pkey = load_key(bio_err, infile, informat, 1, + passin, e, "key"); + if (!pkey) + goto end; + + if (!noout) + { + if (outformat == FORMAT_PEM) + { + if (pubout) + PEM_write_bio_PUBKEY(out,pkey); + else + PEM_write_bio_PrivateKey(out, pkey, cipher, + NULL, 0, NULL, passout); + } + else if (outformat == FORMAT_ASN1) + { + if (pubout) + i2d_PUBKEY_bio(out, pkey); + else + i2d_PrivateKey_bio(out, pkey); + } + else + { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + + } + + if (text) + { + if (pubtext) + EVP_PKEY_print_public(out, pkey, 0, NULL); + else + EVP_PKEY_print_private(out, pkey, 0, NULL); + } + + ret = 0; + + end: + EVP_PKEY_free(pkey); + BIO_free_all(out); + BIO_free(in); + if (passin) + OPENSSL_free(passin); + if (passout) + OPENSSL_free(passout); + + return ret; + } diff --git a/crypto/openssl/crypto/x509/x509cset.c b/crypto/openssl/apps/pkeyparam.c similarity index 51% copy from crypto/openssl/crypto/x509/x509cset.c copy to crypto/openssl/apps/pkeyparam.c index 7f4004b291..7f18010f9d 100644 --- a/crypto/openssl/crypto/x509/x509cset.c +++ b/crypto/openssl/apps/pkeyparam.c @@ -1,9 +1,9 @@ -/* crypto/x509/x509cset.c */ +/* apps/pkeyparam.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. + * project 2006 */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -55,116 +55,147 @@ * Hudson (tjh@cryptsoft.com). * */ - #include -#include "cryptlib.h" -#include -#include +#include +#include "apps.h" +#include +#include #include -#include -int X509_CRL_set_version(X509_CRL *x, long version) - { - if (x == NULL) return(0); - if (x->crl->version == NULL) - { - if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL) - return(0); - } - return(ASN1_INTEGER_set(x->crl->version,version)); - } +#define PROG pkeyparam_main -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +int MAIN(int, char **); + +int MAIN(int argc, char **argv) { - if ((x == NULL) || (x->crl == NULL)) return(0); - return(X509_NAME_set(&x->crl->issuer,name)); - } + char **args, *infile = NULL, *outfile = NULL; + BIO *in = NULL, *out = NULL; + int text = 0, noout = 0; + EVP_PKEY *pkey=NULL; + int badarg = 0; +#ifndef OPENSSL_NO_ENGINE + ENGINE *e = NULL; + char *engine=NULL; +#endif + int ret = 1; + if (bio_err == NULL) + bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); -int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) - { - ASN1_TIME *in; + if (!load_config(bio_err, NULL)) + goto end; - if (x == NULL) return(0); - in=x->crl->lastUpdate; - if (in != tm) + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + args = argv + 1; + while (!badarg && *args && *args[0] == '-') { - in=M_ASN1_TIME_dup(tm); - if (in != NULL) + if (!strcmp (*args, "-in")) { - M_ASN1_TIME_free(x->crl->lastUpdate); - x->crl->lastUpdate=in; + if (args[1]) + { + args++; + infile = *args; + } + else badarg = 1; } - } - return(in != NULL); - } - -int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) - { - ASN1_TIME *in; - - if (x == NULL) return(0); - in=x->crl->nextUpdate; - if (in != tm) - { - in=M_ASN1_TIME_dup(tm); - if (in != NULL) + else if (!strcmp (*args, "-out")) { - M_ASN1_TIME_free(x->crl->nextUpdate); - x->crl->nextUpdate=in; + if (args[1]) + { + args++; + outfile = *args; + } + else badarg = 1; } +#ifndef OPENSSL_NO_ENGINE + else if (strcmp(*args,"-engine") == 0) + { + if (!args[1]) goto bad; + engine= *(++args); + } +#endif + + else if (strcmp(*args,"-text") == 0) + text=1; + else if (strcmp(*args,"-noout") == 0) + noout=1; + args++; } - return(in != NULL); - } -int X509_CRL_sort(X509_CRL *c) - { - int i; - X509_REVOKED *r; - /* sort the data so it will be written in serial - * number order */ - sk_X509_REVOKED_sort(c->crl->revoked); - for (i=0; icrl->revoked); i++) + if (badarg) { - r=sk_X509_REVOKED_value(c->crl->revoked,i); - r->sequence=i; +#ifndef OPENSSL_NO_ENGINE + bad: +#endif + BIO_printf(bio_err, "Usage pkeyparam [options]\n"); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-text print parameters as text\n"); + BIO_printf(bio_err, "-noout don't output encoded parameters\n"); +#ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); +#endif + return 1; } - c->crl->enc.modified = 1; - return 1; - } -int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) - { - ASN1_TIME *in; +#ifndef OPENSSL_NO_ENGINE + e = setup_engine(bio_err, engine, 0); +#endif - if (x == NULL) return(0); - in=x->revocationDate; - if (in != tm) + if (infile) { - in=M_ASN1_TIME_dup(tm); - if (in != NULL) + if (!(in = BIO_new_file (infile, "r"))) { - M_ASN1_TIME_free(x->revocationDate); - x->revocationDate=in; + BIO_printf(bio_err, + "Can't open input file %s\n", infile); + goto end; } } - return(in != NULL); - } + else + in = BIO_new_fp (stdin, BIO_NOCLOSE); -int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) - { - ASN1_INTEGER *in; - - if (x == NULL) return(0); - in=x->serialNumber; - if (in != serial) + if (outfile) + { + if (!(out = BIO_new_file (outfile, "w"))) + { + BIO_printf(bio_err, + "Can't open output file %s\n", outfile); + goto end; + } + } + else { - in=M_ASN1_INTEGER_dup(serial); - if (in != NULL) + out = BIO_new_fp (stdout, BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS { - M_ASN1_INTEGER_free(x->serialNumber); - x->serialNumber=in; + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); } +#endif } - return(in != NULL); + + pkey = PEM_read_bio_Parameters(in, NULL); + if (!pkey) + { + BIO_printf(bio_err, "Error reading parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + + if (!noout) + PEM_write_bio_Parameters(out,pkey); + + if (text) + EVP_PKEY_print_params(out, pkey, 0, NULL); + + ret = 0; + + end: + EVP_PKEY_free(pkey); + BIO_free_all(out); + BIO_free(in); + + return ret; } diff --git a/crypto/openssl/apps/pkeyutl.c b/crypto/openssl/apps/pkeyutl.c new file mode 100644 index 0000000000..22a6c4bf39 --- /dev/null +++ b/crypto/openssl/apps/pkeyutl.c @@ -0,0 +1,570 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 "apps.h" +#include +#include +#include +#include + +#define KEY_PRIVKEY 1 +#define KEY_PUBKEY 2 +#define KEY_CERT 3 + +static void usage(void); + +#undef PROG + +#define PROG pkeyutl_main + +static EVP_PKEY_CTX *init_ctx(int *pkeysize, + char *keyfile, int keyform, int key_type, + char *passargin, int pkey_op, ENGINE *e); + +static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, + const char *file); + +static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, + unsigned char *out, size_t *poutlen, + unsigned char *in, size_t inlen); + +int MAIN(int argc, char **); + +int MAIN(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + char *infile = NULL, *outfile = NULL, *sigfile = NULL; + ENGINE *e = NULL; + int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; + int keyform = FORMAT_PEM, peerform = FORMAT_PEM; + char badarg = 0, rev = 0; + char hexdump = 0, asn1parse = 0; + EVP_PKEY_CTX *ctx = NULL; + char *passargin = NULL; + int keysize = -1; + + unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; + size_t buf_outlen; + int buf_inlen = 0, siglen = -1; + + int ret = 1, rv = -1; + + argc--; + argv++; + + if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + if (!load_config(bio_err, NULL)) + goto end; + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + + while(argc >= 1) + { + if (!strcmp(*argv,"-in")) + { + if (--argc < 1) badarg = 1; + infile= *(++argv); + } + else if (!strcmp(*argv,"-out")) + { + if (--argc < 1) badarg = 1; + outfile= *(++argv); + } + else if (!strcmp(*argv,"-sigfile")) + { + if (--argc < 1) badarg = 1; + sigfile= *(++argv); + } + else if(!strcmp(*argv, "-inkey")) + { + if (--argc < 1) + badarg = 1; + else + { + ctx = init_ctx(&keysize, + *(++argv), keyform, key_type, + passargin, pkey_op, e); + if (!ctx) + { + BIO_puts(bio_err, + "Error initializing context\n"); + ERR_print_errors(bio_err); + badarg = 1; + } + } + } + else if (!strcmp(*argv,"-peerkey")) + { + if (--argc < 1) + badarg = 1; + else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) + badarg = 1; + } + else if (!strcmp(*argv,"-passin")) + { + if (--argc < 1) badarg = 1; + passargin= *(++argv); + } + else if (strcmp(*argv,"-peerform") == 0) + { + if (--argc < 1) badarg = 1; + peerform=str2fmt(*(++argv)); + } + else if (strcmp(*argv,"-keyform") == 0) + { + if (--argc < 1) badarg = 1; + keyform=str2fmt(*(++argv)); + } +#ifndef OPENSSL_NO_ENGINE + else if(!strcmp(*argv, "-engine")) + { + if (--argc < 1) + badarg = 1; + else + e = setup_engine(bio_err, *(++argv), 0); + } +#endif + else if(!strcmp(*argv, "-pubin")) + key_type = KEY_PUBKEY; + else if(!strcmp(*argv, "-certin")) + key_type = KEY_CERT; + else if(!strcmp(*argv, "-asn1parse")) + asn1parse = 1; + else if(!strcmp(*argv, "-hexdump")) + hexdump = 1; + else if(!strcmp(*argv, "-sign")) + pkey_op = EVP_PKEY_OP_SIGN; + else if(!strcmp(*argv, "-verify")) + pkey_op = EVP_PKEY_OP_VERIFY; + else if(!strcmp(*argv, "-verifyrecover")) + pkey_op = EVP_PKEY_OP_VERIFYRECOVER; + else if(!strcmp(*argv, "-rev")) + rev = 1; + else if(!strcmp(*argv, "-encrypt")) + pkey_op = EVP_PKEY_OP_ENCRYPT; + else if(!strcmp(*argv, "-decrypt")) + pkey_op = EVP_PKEY_OP_DECRYPT; + else if(!strcmp(*argv, "-derive")) + pkey_op = EVP_PKEY_OP_DERIVE; + else if (strcmp(*argv,"-pkeyopt") == 0) + { + if (--argc < 1) + badarg = 1; + else if (!ctx) + { + BIO_puts(bio_err, + "-pkeyopt command before -inkey\n"); + badarg = 1; + } + else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) + { + BIO_puts(bio_err, "parameter setting error\n"); + ERR_print_errors(bio_err); + goto end; + } + } + else badarg = 1; + if(badarg) + { + usage(); + goto end; + } + argc--; + argv++; + } + + if (!ctx) + { + usage(); + goto end; + } + + if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) + { + BIO_puts(bio_err, "Signature file specified for non verify\n"); + goto end; + } + + if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) + { + BIO_puts(bio_err, "No signature file specified for verify\n"); + goto end; + } + +/* FIXME: seed PRNG only if needed */ + app_RAND_load_file(NULL, bio_err, 0); + + if (pkey_op != EVP_PKEY_OP_DERIVE) + { + if(infile) + { + if(!(in = BIO_new_file(infile, "rb"))) + { + BIO_puts(bio_err, + "Error Opening Input File\n"); + ERR_print_errors(bio_err); + goto end; + } + } + else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + } + + if(outfile) + { + if(!(out = BIO_new_file(outfile, "wb"))) + { + BIO_printf(bio_err, "Error Creating Output File\n"); + ERR_print_errors(bio_err); + goto end; + } + } + else + { + out = BIO_new_fp(stdout, BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } + + if (sigfile) + { + BIO *sigbio = BIO_new_file(sigfile, "rb"); + if (!sigbio) + { + BIO_printf(bio_err, "Can't open signature file %s\n", + sigfile); + goto end; + } + siglen = bio_to_mem(&sig, keysize * 10, sigbio); + BIO_free(sigbio); + if (siglen <= 0) + { + BIO_printf(bio_err, "Error reading signature data\n"); + goto end; + } + } + + if (in) + { + /* Read the input data */ + buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); + if(buf_inlen <= 0) + { + BIO_printf(bio_err, "Error reading input Data\n"); + exit(1); + } + if(rev) + { + size_t i; + unsigned char ctmp; + size_t l = (size_t)buf_inlen; + for(i = 0; i < l/2; i++) + { + ctmp = buf_in[i]; + buf_in[i] = buf_in[l - 1 - i]; + buf_in[l - 1 - i] = ctmp; + } + } + } + + if(pkey_op == EVP_PKEY_OP_VERIFY) + { + rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, + buf_in, (size_t)buf_inlen); + if (rv == 0) + BIO_puts(out, "Signature Verification Failure\n"); + else if (rv == 1) + BIO_puts(out, "Signature Verified Successfully\n"); + if (rv >= 0) + goto end; + } + else + { + rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, + buf_in, (size_t)buf_inlen); + if (rv > 0) + { + buf_out = OPENSSL_malloc(buf_outlen); + if (!buf_out) + rv = -1; + else + rv = do_keyop(ctx, pkey_op, + buf_out, (size_t *)&buf_outlen, + buf_in, (size_t)buf_inlen); + } + } + + if(rv <= 0) + { + BIO_printf(bio_err, "Public Key operation error\n"); + ERR_print_errors(bio_err); + goto end; + } + ret = 0; + if(asn1parse) + { + if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) + ERR_print_errors(bio_err); + } + else if(hexdump) + BIO_dump(out, (char *)buf_out, buf_outlen); + else + BIO_write(out, buf_out, buf_outlen); + + end: + if (ctx) + EVP_PKEY_CTX_free(ctx); + BIO_free(in); + BIO_free_all(out); + if (buf_in) + OPENSSL_free(buf_in); + if (buf_out) + OPENSSL_free(buf_out); + if (sig) + OPENSSL_free(sig); + return ret; +} + +static void usage() +{ + BIO_printf(bio_err, "Usage: pkeyutl [options]\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n"); + BIO_printf(bio_err, "-inkey file input key\n"); + BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); + BIO_printf(bio_err, "-pubin input is a public key\n"); + BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n"); + BIO_printf(bio_err, "-pkeyopt X:Y public key options\n"); + BIO_printf(bio_err, "-sign sign with private key\n"); + BIO_printf(bio_err, "-verify verify with public key\n"); + BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n"); + BIO_printf(bio_err, "-encrypt encrypt with public key\n"); + BIO_printf(bio_err, "-decrypt decrypt with private key\n"); + BIO_printf(bio_err, "-derive derive shared secret\n"); + BIO_printf(bio_err, "-hexdump hex dump output\n"); +#ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); +#endif + BIO_printf(bio_err, "-passin arg pass phrase source\n"); + +} + +static EVP_PKEY_CTX *init_ctx(int *pkeysize, + char *keyfile, int keyform, int key_type, + char *passargin, int pkey_op, ENGINE *e) + { + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + char *passin = NULL; + int rv = -1; + X509 *x; + if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) + || (pkey_op == EVP_PKEY_OP_DERIVE)) + && (key_type != KEY_PRIVKEY)) + { + BIO_printf(bio_err, "A private key is needed for this operation\n"); + goto end; + } + if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) + { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + switch(key_type) + { + case KEY_PRIVKEY: + pkey = load_key(bio_err, keyfile, keyform, 0, + passin, e, "Private Key"); + break; + + case KEY_PUBKEY: + pkey = load_pubkey(bio_err, keyfile, keyform, 0, + NULL, e, "Public Key"); + break; + + case KEY_CERT: + x = load_cert(bio_err, keyfile, keyform, + NULL, e, "Certificate"); + if(x) + { + pkey = X509_get_pubkey(x); + X509_free(x); + } + break; + + } + + *pkeysize = EVP_PKEY_size(pkey); + + if (!pkey) + goto end; + + ctx = EVP_PKEY_CTX_new(pkey, e); + + EVP_PKEY_free(pkey); + + if (!ctx) + goto end; + + switch(pkey_op) + { + case EVP_PKEY_OP_SIGN: + rv = EVP_PKEY_sign_init(ctx); + break; + + case EVP_PKEY_OP_VERIFY: + rv = EVP_PKEY_verify_init(ctx); + break; + + case EVP_PKEY_OP_VERIFYRECOVER: + rv = EVP_PKEY_verify_recover_init(ctx); + break; + + case EVP_PKEY_OP_ENCRYPT: + rv = EVP_PKEY_encrypt_init(ctx); + break; + + case EVP_PKEY_OP_DECRYPT: + rv = EVP_PKEY_decrypt_init(ctx); + break; + + case EVP_PKEY_OP_DERIVE: + rv = EVP_PKEY_derive_init(ctx); + break; + } + + if (rv <= 0) + { + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + } + + end: + + if (passin) + OPENSSL_free(passin); + + return ctx; + + + } + +static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, + const char *file) + { + EVP_PKEY *peer = NULL; + int ret; + if (!ctx) + { + BIO_puts(err, "-peerkey command before -inkey\n"); + return 0; + } + + peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key"); + + if (!peer) + { + BIO_printf(bio_err, "Error reading peer key %s\n", file); + ERR_print_errors(err); + return 0; + } + + ret = EVP_PKEY_derive_set_peer(ctx, peer); + + EVP_PKEY_free(peer); + if (ret <= 0) + ERR_print_errors(err); + return ret; + } + +static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, + unsigned char *out, size_t *poutlen, + unsigned char *in, size_t inlen) + { + int rv = 0; + switch(pkey_op) + { + case EVP_PKEY_OP_VERIFYRECOVER: + rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_SIGN: + rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_ENCRYPT: + rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_DECRYPT: + rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_DERIVE: + rv = EVP_PKEY_derive(ctx, out, poutlen); + break; + + } + return rv; + } diff --git a/crypto/openssl/apps/prime.c b/crypto/openssl/apps/prime.c index af2fed15af..f1aaef8725 100644 --- a/crypto/openssl/apps/prime.c +++ b/crypto/openssl/apps/prime.c @@ -62,6 +62,9 @@ int MAIN(int argc, char **argv) { int hex=0; int checks=20; + int generate=0; + int bits=0; + int safe=0; BIGNUM *bn=NULL; BIO *bio_out; @@ -77,6 +80,15 @@ int MAIN(int argc, char **argv) { if(!strcmp(*argv,"-hex")) hex=1; + else if(!strcmp(*argv,"-generate")) + generate=1; + else if(!strcmp(*argv,"-bits")) + if(--argc < 1) + goto bad; + else + bits=atoi(*++argv); + else if(!strcmp(*argv,"-safe")) + safe=1; else if(!strcmp(*argv,"-checks")) if(--argc < 1) goto bad; @@ -91,13 +103,13 @@ int MAIN(int argc, char **argv) ++argv; } - if (argv[0] == NULL) + if (argv[0] == NULL && !generate) { BIO_printf(bio_err,"No prime specified\n"); goto bad; } - if ((bio_out=BIO_new(BIO_s_file())) != NULL) + if ((bio_out=BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS @@ -108,14 +120,32 @@ int MAIN(int argc, char **argv) #endif } - if(hex) - BN_hex2bn(&bn,argv[0]); + if(generate) + { + char *s; + + if(!bits) + { + BIO_printf(bio_err,"Specifiy the number of bits.\n"); + return 1; + } + bn=BN_new(); + BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL); + s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn); + BIO_printf(bio_out,"%s\n",s); + OPENSSL_free(s); + } else - BN_dec2bn(&bn,argv[0]); + { + if(hex) + BN_hex2bn(&bn,argv[0]); + else + BN_dec2bn(&bn,argv[0]); - BN_print(bio_out,bn); - BIO_printf(bio_out," is %sprime\n", - BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not "); + BN_print(bio_out,bn); + BIO_printf(bio_out," is %sprime\n", + BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not "); + } BN_free(bn); BIO_free_all(bio_out); diff --git a/crypto/openssl/apps/progs.h b/crypto/openssl/apps/progs.h index aafd800bdf..79e479a337 100644 --- a/crypto/openssl/apps/progs.h +++ b/crypto/openssl/apps/progs.h @@ -22,6 +22,7 @@ extern int ecparam_main(int argc,char *argv[]); extern int x509_main(int argc,char *argv[]); extern int genrsa_main(int argc,char *argv[]); extern int gendsa_main(int argc,char *argv[]); +extern int genpkey_main(int argc,char *argv[]); extern int s_server_main(int argc,char *argv[]); extern int s_client_main(int argc,char *argv[]); extern int speed_main(int argc,char *argv[]); @@ -35,22 +36,30 @@ extern int ciphers_main(int argc,char *argv[]); extern int nseq_main(int argc,char *argv[]); extern int pkcs12_main(int argc,char *argv[]); extern int pkcs8_main(int argc,char *argv[]); +extern int pkey_main(int argc,char *argv[]); +extern int pkeyparam_main(int argc,char *argv[]); +extern int pkeyutl_main(int argc,char *argv[]); extern int spkac_main(int argc,char *argv[]); extern int smime_main(int argc,char *argv[]); extern int rand_main(int argc,char *argv[]); extern int engine_main(int argc,char *argv[]); extern int ocsp_main(int argc,char *argv[]); extern int prime_main(int argc,char *argv[]); +extern int ts_main(int argc,char *argv[]); #define FUNC_TYPE_GENERAL 1 #define FUNC_TYPE_MD 2 #define FUNC_TYPE_CIPHER 3 +#define FUNC_TYPE_PKEY 4 +#define FUNC_TYPE_MD_ALG 5 +#define FUNC_TYPE_CIPHER_ALG 6 typedef struct { int type; const char *name; int (*func)(int argc,char *argv[]); } FUNCTION; +DECLARE_LHASH_OF(FUNCTION); FUNCTION functions[] = { {FUNC_TYPE_GENERAL,"verify",verify_main}, @@ -96,6 +105,7 @@ FUNCTION functions[] = { #ifndef OPENSSL_NO_DSA {FUNC_TYPE_GENERAL,"gendsa",gendsa_main}, #endif + {FUNC_TYPE_GENERAL,"genpkey",genpkey_main}, #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3)) {FUNC_TYPE_GENERAL,"s_server",s_server_main}, #endif @@ -123,14 +133,20 @@ FUNCTION functions[] = { {FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main}, #endif {FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main}, + {FUNC_TYPE_GENERAL,"pkey",pkey_main}, + {FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main}, + {FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main}, {FUNC_TYPE_GENERAL,"spkac",spkac_main}, {FUNC_TYPE_GENERAL,"smime",smime_main}, {FUNC_TYPE_GENERAL,"rand",rand_main}, #ifndef OPENSSL_NO_ENGINE {FUNC_TYPE_GENERAL,"engine",engine_main}, #endif +#ifndef OPENSSL_NO_OCSP {FUNC_TYPE_GENERAL,"ocsp",ocsp_main}, +#endif {FUNC_TYPE_GENERAL,"prime",prime_main}, + {FUNC_TYPE_GENERAL,"ts",ts_main}, #ifndef OPENSSL_NO_MD2 {FUNC_TYPE_MD,"md2",dgst_main}, #endif @@ -189,6 +205,9 @@ FUNCTION functions[] = { {FUNC_TYPE_CIPHER,"camellia-256-ecb",enc_main}, #endif {FUNC_TYPE_CIPHER,"base64",enc_main}, +#ifdef ZLIB + {FUNC_TYPE_CIPHER,"zlib",enc_main}, +#endif #ifndef OPENSSL_NO_DES {FUNC_TYPE_CIPHER,"des",enc_main}, #endif diff --git a/crypto/openssl/apps/req.c b/crypto/openssl/apps/req.c index 314197de83..820cd18fc7 100644 --- a/crypto/openssl/apps/req.c +++ b/crypto/openssl/apps/req.c @@ -141,39 +141,33 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def, int n_max, unsigned long chtype); static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, int nid,int n_min,int n_max, unsigned long chtype, int mval); -#ifndef OPENSSL_NO_RSA -static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb); -#endif +static int genpkey_cb(EVP_PKEY_CTX *ctx); static int req_check_len(int len,int n_min,int n_max); static int check_end(const char *str, const char *end); +static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type, + long *pkeylen, char **palgnam, + ENGINE *keygen_engine); #ifndef MONOLITH static char *default_config_file=NULL; #endif static CONF *req_conf=NULL; static int batch=0; -#define TYPE_RSA 1 -#define TYPE_DSA 2 -#define TYPE_DH 3 -#define TYPE_EC 4 - int MAIN(int, char **); int MAIN(int argc, char **argv) { - ENGINE *e = NULL; -#ifndef OPENSSL_NO_DSA - DSA *dsa_params=NULL; -#endif -#ifndef OPENSSL_NO_ECDSA - EC_KEY *ec_params = NULL; -#endif + ENGINE *e = NULL, *gen_eng = NULL; unsigned long nmflag = 0, reqflag = 0; int ex=1,x509=0,days=30; X509 *x509ss=NULL; X509_REQ *req=NULL; + EVP_PKEY_CTX *genctx = NULL; + const char *keyalg = NULL; + char *keyalgstr = NULL; + STACK_OF(OPENSSL_STRING) *pkeyopts = NULL; EVP_PKEY *pkey=NULL; - int i=0,badops=0,newreq=0,verbose=0,pkey_type=TYPE_RSA; + int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1; long newkey = -1; BIO *in=NULL,*out=NULL; int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM; @@ -193,7 +187,7 @@ int MAIN(int argc, char **argv) char *p; char *subj = NULL; int multirdn = 0; - const EVP_MD *md_alg=NULL,*digest=EVP_sha1(); + const EVP_MD *md_alg=NULL,*digest=NULL; unsigned long chtype = MBSTRING_ASC; #ifndef MONOLITH char *to_free; @@ -236,6 +230,16 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; engine= *(++argv); } + else if (strcmp(*argv,"-keygen_engine") == 0) + { + if (--argc < 1) goto bad; + gen_eng = ENGINE_by_id(*(++argv)); + if (gen_eng == NULL) + { + BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); + goto end; + } + } #endif else if (strcmp(*argv,"-key") == 0) { @@ -292,126 +296,20 @@ int MAIN(int argc, char **argv) } else if (strcmp(*argv,"-newkey") == 0) { - int is_numeric; - - if (--argc < 1) goto bad; - p= *(++argv); - is_numeric = p[0] >= '0' && p[0] <= '9'; - if (strncmp("rsa:",p,4) == 0 || is_numeric) - { - pkey_type=TYPE_RSA; - if(!is_numeric) - p+=4; - newkey= atoi(p); - } - else -#ifndef OPENSSL_NO_DSA - if (strncmp("dsa:",p,4) == 0) - { - X509 *xtmp=NULL; - EVP_PKEY *dtmp; - - pkey_type=TYPE_DSA; - p+=4; - if ((in=BIO_new_file(p,"r")) == NULL) - { - perror(p); - goto end; - } - if ((dsa_params=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL) - { - ERR_clear_error(); - (void)BIO_reset(in); - if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) - { - BIO_printf(bio_err,"unable to load DSA parameters from file\n"); - goto end; - } - - if ((dtmp=X509_get_pubkey(xtmp)) == NULL) goto end; - if (dtmp->type == EVP_PKEY_DSA) - dsa_params=DSAparams_dup(dtmp->pkey.dsa); - EVP_PKEY_free(dtmp); - X509_free(xtmp); - if (dsa_params == NULL) - { - BIO_printf(bio_err,"Certificate does not contain DSA parameters\n"); - goto end; - } - } - BIO_free(in); - in=NULL; - newkey=BN_num_bits(dsa_params->p); - } - else -#endif -#ifndef OPENSSL_NO_ECDSA - if (strncmp("ec:",p,3) == 0) - { - X509 *xtmp=NULL; - EVP_PKEY *dtmp; - EC_GROUP *group; - - pkey_type=TYPE_EC; - p+=3; - if ((in=BIO_new_file(p,"r")) == NULL) - { - perror(p); - goto end; - } - if ((ec_params = EC_KEY_new()) == NULL) - goto end; - group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); - if (group == NULL) - { - EC_KEY_free(ec_params); - ERR_clear_error(); - (void)BIO_reset(in); - if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) - { - BIO_printf(bio_err,"unable to load EC parameters from file\n"); - goto end; - } - - if ((dtmp=X509_get_pubkey(xtmp))==NULL) - goto end; - if (dtmp->type == EVP_PKEY_EC) - ec_params = EC_KEY_dup(dtmp->pkey.ec); - EVP_PKEY_free(dtmp); - X509_free(xtmp); - if (ec_params == NULL) - { - BIO_printf(bio_err,"Certificate does not contain EC parameters\n"); - goto end; - } - } - else - { - if (EC_KEY_set_group(ec_params, group) == 0) - goto end; - EC_GROUP_free(group); - } - - BIO_free(in); - in=NULL; - newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params)); - } - else -#endif -#ifndef OPENSSL_NO_DH - if (strncmp("dh:",p,4) == 0) - { - pkey_type=TYPE_DH; - p+=3; - } - else -#endif - { + if (--argc < 1) goto bad; - } - + keyalg = *(++argv); newreq=1; } + else if (strcmp(*argv,"-pkeyopt") == 0) + { + if (--argc < 1) + goto bad; + if (!pkeyopts) + pkeyopts = sk_OPENSSL_STRING_new_null(); + if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv))) + goto bad; + } else if (strcmp(*argv,"-batch") == 0) batch=1; else if (strcmp(*argv,"-newhdr") == 0) @@ -467,11 +365,6 @@ int MAIN(int argc, char **argv) serial = s2i_ASN1_INTEGER(NULL, *(++argv)); if (!serial) goto bad; } - else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL) - { - /* ok */ - digest=md_alg; - } else if (strcmp(*argv,"-extensions") == 0) { if (--argc < 1) goto bad; @@ -482,6 +375,11 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; req_exts = *(++argv); } + else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL) + { + /* ok */ + digest=md_alg; + } else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -730,15 +628,20 @@ bad: if (newreq && (pkey == NULL)) { -#ifndef OPENSSL_NO_RSA - BN_GENCB cb; -#endif char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE"); if (randfile == NULL) ERR_clear_error(); app_RAND_load_file(randfile, bio_err, 0); if (inrand) app_RAND_load_files(inrand); + + if (keyalg) + { + genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey, + &keyalgstr, gen_eng); + if (!genctx) + goto end; + } if (newkey <= 0) { @@ -746,57 +649,54 @@ bad: newkey=DEFAULT_KEY_LENGTH; } - if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA)) + if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { BIO_printf(bio_err,"private key length is too short,\n"); BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey); goto end; } - BIO_printf(bio_err,"Generating a %ld bit %s private key\n", - newkey,(pkey_type == TYPE_RSA)?"RSA": - (pkey_type == TYPE_DSA)?"DSA":"EC"); - if ((pkey=EVP_PKEY_new()) == NULL) goto end; - -#ifndef OPENSSL_NO_RSA - BN_GENCB_set(&cb, req_cb, bio_err); - if (pkey_type == TYPE_RSA) - { - RSA *rsa = RSA_new(); - BIGNUM *bn = BN_new(); - if(!bn || !rsa || !BN_set_word(bn, 0x10001) || - !RSA_generate_key_ex(rsa, newkey, bn, &cb) || - !EVP_PKEY_assign_RSA(pkey, rsa)) - { - if(bn) BN_free(bn); - if(rsa) RSA_free(rsa); + if (!genctx) + { + genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey, + &keyalgstr, gen_eng); + if (!genctx) goto end; - } - BN_free(bn); } - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey_type == TYPE_DSA) + + if (pkeyopts) { - if (!DSA_generate_key(dsa_params)) goto end; - if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end; - dsa_params=NULL; + char *genopt; + for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) + { + genopt = sk_OPENSSL_STRING_value(pkeyopts, i); + if (pkey_ctrl_string(genctx, genopt) <= 0) + { + BIO_printf(bio_err, + "parameter error \"%s\"\n", + genopt); + ERR_print_errors(bio_err); + goto end; + } + } } -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey_type == TYPE_EC) + + BIO_printf(bio_err,"Generating a %ld bit %s private key\n", + newkey, keyalgstr); + + EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); + EVP_PKEY_CTX_set_app_data(genctx, bio_err); + + if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { - if (!EC_KEY_generate_key(ec_params)) goto end; - if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params)) - goto end; - ec_params = NULL; + BIO_puts(bio_err, "Error Generating Key\n"); + goto end; } -#endif - app_RAND_write_file(randfile, bio_err); + EVP_PKEY_CTX_free(genctx); + genctx = NULL; - if (pkey == NULL) goto end; + app_RAND_write_file(randfile, bio_err); if (keyout == NULL) { @@ -895,14 +795,7 @@ loop: BIO_printf(bio_err,"you need to specify a private key\n"); goto end; } -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - digest=EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) - digest=EVP_ecdsa(); -#endif + if (req == NULL) { req=X509_REQ_new(); @@ -945,7 +838,7 @@ loop: if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end; if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end; - if (!X509_gmtime_adj(X509_get_notAfter(x509ss), (long)60*60*24*days)) goto end; + if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end; if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end; tmppkey = X509_REQ_get_pubkey(req); if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end; @@ -967,7 +860,10 @@ loop: } if (!(i=X509_sign(x509ss,pkey,digest))) + { + ERR_print_errors(bio_err); goto end; + } } else { @@ -988,7 +884,10 @@ loop: goto end; } if (!(i=X509_REQ_sign(req,pkey,digest))) + { + ERR_print_errors(bio_err); goto end; + } } } @@ -1125,7 +1024,7 @@ loop: } fprintf(stdout,"Modulus="); #ifndef OPENSSL_NO_RSA - if (tpubkey->type == EVP_PKEY_RSA) + if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) BN_print(out,tpubkey->pkey.rsa->n); else #endif @@ -1181,18 +1080,22 @@ end: BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); + if (genctx) + EVP_PKEY_CTX_free(genctx); + if (pkeyopts) + sk_OPENSSL_STRING_free(pkeyopts); +#ifndef OPENSSL_NO_ENGINE + if (gen_eng) + ENGINE_free(gen_eng); +#endif + if (keyalgstr) + OPENSSL_free(keyalgstr); X509_REQ_free(req); X509_free(x509ss); ASN1_INTEGER_free(serial); if(passargin && passin) OPENSSL_free(passin); if(passargout && passout) OPENSSL_free(passout); OBJ_cleanup(); -#ifndef OPENSSL_NO_DSA - if (dsa_params != NULL) DSA_free(dsa_params); -#endif -#ifndef OPENSSL_NO_ECDSA - if (ec_params != NULL) EC_KEY_free(ec_params); -#endif apps_shutdown(); OPENSSL_EXIT(ex); } @@ -1433,11 +1336,17 @@ start2: for (;;) BIO_snprintf(buf,sizeof buf,"%s_min",type); if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min)) + { + ERR_clear_error(); n_min = -1; + } BIO_snprintf(buf,sizeof buf,"%s_max",type); if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max)) + { + ERR_clear_error(); n_max = -1; + } if (!add_attribute_object(req, v->value,def,value,nid,n_min,n_max, chtype)) @@ -1641,24 +1550,6 @@ err: return(0); } -#ifndef OPENSSL_NO_RSA -static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb) - { - char c='*'; - - if (p == 0) c='.'; - if (p == 1) c='+'; - if (p == 2) c='*'; - if (p == 3) c='\n'; - BIO_write(cb->arg,&c,1); - (void)BIO_flush(cb->arg); -#ifdef LINT - p=n; -#endif - return 1; - } -#endif - static int req_check_len(int len, int n_min, int n_max) { if ((n_min > 0) && (len < n_min)) @@ -1685,3 +1576,183 @@ static int check_end(const char *str, const char *end) tmp = str + slen - elen; return strcmp(tmp, end); } + +static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type, + long *pkeylen, char **palgnam, + ENGINE *keygen_engine) + { + EVP_PKEY_CTX *gctx = NULL; + EVP_PKEY *param = NULL; + long keylen = -1; + BIO *pbio = NULL; + const char *paramfile = NULL; + + if (gstr == NULL) + { + *pkey_type = EVP_PKEY_RSA; + keylen = *pkeylen; + } + else if (gstr[0] >= '0' && gstr[0] <= '9') + { + *pkey_type = EVP_PKEY_RSA; + keylen = atol(gstr); + *pkeylen = keylen; + } + else if (!strncmp(gstr, "param:", 6)) + paramfile = gstr + 6; + else + { + const char *p = strchr(gstr, ':'); + int len; + ENGINE *tmpeng; + const EVP_PKEY_ASN1_METHOD *ameth; + + if (p) + len = p - gstr; + else + len = strlen(gstr); + /* The lookup of a the string will cover all engines so + * keep a note of the implementation. + */ + + ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len); + + if (!ameth) + { + BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); + return NULL; + } + + EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, + ameth); +#ifndef OPENSSL_NO_ENGINE + if (tmpeng) + ENGINE_finish(tmpeng); +#endif + if (*pkey_type == EVP_PKEY_RSA) + { + if (p) + { + keylen = atol(p + 1); + *pkeylen = keylen; + } + } + else if (p) + paramfile = p + 1; + } + + if (paramfile) + { + pbio = BIO_new_file(paramfile, "r"); + if (!pbio) + { + BIO_printf(err, "Can't open parameter file %s\n", + paramfile); + return NULL; + } + param = PEM_read_bio_Parameters(pbio, NULL); + + if (!param) + { + X509 *x; + (void)BIO_reset(pbio); + x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); + if (x) + { + param = X509_get_pubkey(x); + X509_free(x); + } + } + + BIO_free(pbio); + + if (!param) + { + BIO_printf(err, "Error reading parameter file %s\n", + paramfile); + return NULL; + } + if (*pkey_type == -1) + *pkey_type = EVP_PKEY_id(param); + else if (*pkey_type != EVP_PKEY_base_id(param)) + { + BIO_printf(err, "Key Type does not match parameters\n"); + EVP_PKEY_free(param); + return NULL; + } + } + + if (palgnam) + { + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng; + const char *anam; + ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type); + if (!ameth) + { + BIO_puts(err, "Internal error: can't find key algorithm\n"); + return NULL; + } + EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); + *palgnam = BUF_strdup(anam); +#ifndef OPENSSL_NO_ENGINE + if (tmpeng) + ENGINE_finish(tmpeng); +#endif + } + + if (param) + { + gctx = EVP_PKEY_CTX_new(param, keygen_engine); + *pkeylen = EVP_PKEY_bits(param); + EVP_PKEY_free(param); + } + else + gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine); + + if (!gctx) + { + BIO_puts(err, "Error allocating keygen context\n"); + ERR_print_errors(err); + return NULL; + } + + if (EVP_PKEY_keygen_init(gctx) <= 0) + { + BIO_puts(err, "Error initializing keygen context\n"); + ERR_print_errors(err); + return NULL; + } +#ifndef OPENSSL_NO_RSA + if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) + { + if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) + { + BIO_puts(err, "Error setting RSA keysize\n"); + ERR_print_errors(err); + EVP_PKEY_CTX_free(gctx); + return NULL; + } + } +#endif + + return gctx; + } + +static int genpkey_cb(EVP_PKEY_CTX *ctx) + { + char c='*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p; + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (p == 0) c='.'; + if (p == 1) c='+'; + if (p == 2) c='*'; + if (p == 3) c='\n'; + BIO_write(b,&c,1); + (void)BIO_flush(b); +#ifdef LINT + p=n; +#endif + return 1; + } diff --git a/crypto/openssl/apps/rsa.c b/crypto/openssl/apps/rsa.c index 930f1f038a..a17708fe9c 100644 --- a/crypto/openssl/apps/rsa.c +++ b/crypto/openssl/apps/rsa.c @@ -115,6 +115,8 @@ int MAIN(int argc, char **argv) #endif int modulus=0; + int pvk_encr = 2; + apps_startup(); if (bio_err == NULL) @@ -177,6 +179,16 @@ int MAIN(int argc, char **argv) pubin=1; else if (strcmp(*argv,"-pubout") == 0) pubout=1; + else if (strcmp(*argv,"-RSAPublicKey_in") == 0) + pubin = 2; + else if (strcmp(*argv,"-RSAPublicKey_out") == 0) + pubout = 2; + else if (strcmp(*argv,"-pvk-strong") == 0) + pvk_encr=2; + else if (strcmp(*argv,"-pvk-weak") == 0) + pvk_encr=1; + else if (strcmp(*argv,"-pvk-none") == 0) + pvk_encr=0; else if (strcmp(*argv,"-noout") == 0) noout=1; else if (strcmp(*argv,"-text") == 0) @@ -257,10 +269,23 @@ bad: EVP_PKEY *pkey; if (pubin) - pkey = load_pubkey(bio_err, infile, - (informat == FORMAT_NETSCAPE && sgckey ? - FORMAT_IISSGC : informat), 1, + { + int tmpformat=-1; + if (pubin == 2) + { + if (informat == FORMAT_PEM) + tmpformat = FORMAT_PEMRSA; + else if (informat == FORMAT_ASN1) + tmpformat = FORMAT_ASN1RSA; + } + else if (informat == FORMAT_NETSCAPE && sgckey) + tmpformat = FORMAT_IISSGC; + else + tmpformat = informat; + + pkey = load_pubkey(bio_err, infile, tmpformat, 1, passin, e, "Public Key"); + } else pkey = load_key(bio_err, infile, (informat == FORMAT_NETSCAPE && sgckey ? @@ -268,7 +293,7 @@ bad: passin, e, "Private Key"); if (pkey != NULL) - rsa = pkey == NULL ? NULL : EVP_PKEY_get1_RSA(pkey); + rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); } @@ -346,7 +371,13 @@ bad: } BIO_printf(bio_err,"writing RSA key\n"); if (outformat == FORMAT_ASN1) { - if(pubout || pubin) i=i2d_RSA_PUBKEY_bio(out,rsa); + if(pubout || pubin) + { + if (pubout == 2) + i=i2d_RSAPublicKey_bio(out,rsa); + else + i=i2d_RSA_PUBKEY_bio(out,rsa); + } else i=i2d_RSAPrivateKey_bio(out,rsa); } #ifndef OPENSSL_NO_RC4 @@ -370,14 +401,32 @@ bad: #endif else if (outformat == FORMAT_PEM) { if(pubout || pubin) - i=PEM_write_bio_RSA_PUBKEY(out,rsa); + { + if (pubout == 2) + i=PEM_write_bio_RSAPublicKey(out,rsa); + else + i=PEM_write_bio_RSA_PUBKEY(out,rsa); + } else i=PEM_write_bio_RSAPrivateKey(out,rsa, enc,NULL,0,NULL,passout); +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) + } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { + EVP_PKEY *pk; + pk = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(pk, rsa); + if (outformat == FORMAT_PVK) + i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); + else if (pubin || pubout) + i = i2b_PublicKey_bio(out, pk); + else + i = i2b_PrivateKey_bio(out, pk); + EVP_PKEY_free(pk); +#endif } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } - if (!i) + if (i <= 0) { BIO_printf(bio_err,"unable to write key\n"); ERR_print_errors(bio_err); diff --git a/crypto/openssl/apps/rsautl.c b/crypto/openssl/apps/rsautl.c index 923e2b682f..b01f004eb3 100644 --- a/crypto/openssl/apps/rsautl.c +++ b/crypto/openssl/apps/rsautl.c @@ -342,4 +342,10 @@ static void usage() } +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + #endif diff --git a/crypto/openssl/apps/s_apps.h b/crypto/openssl/apps/s_apps.h index f5a39bae66..820e5c5815 100644 --- a/crypto/openssl/apps/s_apps.h +++ b/crypto/openssl/apps/s_apps.h @@ -117,7 +117,7 @@ #include #endif -#ifdef OPENSSL_SYS_MSDOS +#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) #define _kbhit kbhit #endif @@ -162,7 +162,7 @@ int extract_port(char *str, short *port_ptr); int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, - int argi, long argl, long ret); + int argi, long argl, long ret); #ifdef HEADER_SSL_H void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret); diff --git a/crypto/openssl/apps/s_cb.c b/crypto/openssl/apps/s_cb.c index 97caffc401..c4f5512247 100644 --- a/crypto/openssl/apps/s_cb.c +++ b/crypto/openssl/apps/s_cb.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -126,12 +126,12 @@ int verify_depth=0; int verify_error=X509_V_OK; +int verify_return_error=0; unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; int cookie_initialized=0; int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) { - char buf[256]; X509 *err_cert; int err,depth; @@ -139,15 +139,23 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) err= X509_STORE_CTX_get_error(ctx); depth= X509_STORE_CTX_get_error_depth(ctx); - X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf); - BIO_printf(bio_err,"depth=%d %s\n",depth,buf); + BIO_printf(bio_err,"depth=%d ",depth); + if (err_cert) + { + X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); + } + else + BIO_puts(bio_err, "\n"); if (!ok) { BIO_printf(bio_err,"verify error:num=%d:%s\n",err, X509_verify_cert_error_string(err)); if (verify_depth >= depth) { - ok=1; + if (!verify_return_error) + ok=1; verify_error=X509_V_OK; } else @@ -156,25 +164,33 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; } } - switch (ctx->error) + switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf); - BIO_printf(bio_err,"issuer= %s\n",buf); + BIO_puts(bio_err,"issuer= "); + X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: BIO_printf(bio_err,"notBefore="); - ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert)); + ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); BIO_printf(bio_err,"\n"); break; case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: BIO_printf(bio_err,"notAfter="); - ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert)); + ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); BIO_printf(bio_err,"\n"); break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(bio_err, ctx); + break; } + if (err == X509_V_OK && ok == 2) + policies_print(bio_err, ctx); + BIO_printf(bio_err,"verify return:%d\n",ok); return(ok); } @@ -263,7 +279,7 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key) } long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, - int argi, long argl, long ret) + int argi, long argl, long ret) { BIO *out; @@ -272,15 +288,15 @@ long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) { - BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n", - (void *)bio,argp,argi,ret,ret); + BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n", + (void *)bio,argp,(unsigned long)argi,ret,ret); BIO_dump(out,argp,(int)ret); return(ret); } else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) { - BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n", - (void *)bio,argp,argi,ret,ret); + BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n", + (void *)bio,argp,(unsigned long)argi,ret,ret); BIO_dump(out,argp,(int)ret); } return(ret); @@ -341,14 +357,14 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * case TLS1_VERSION: str_version = "TLS 1.0 "; break; - default: - str_version = "???"; case DTLS1_VERSION: str_version = "DTLS 1.0 "; break; case DTLS1_BAD_VER: str_version = "DTLS 1.0 (bad) "; break; + default: + str_version = "???"; } if (version == SSL2_VERSION) @@ -518,6 +534,21 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * case 100: str_details2 = " no_renegotiation"; break; + case 110: + str_details2 = " unsupported_extension"; + break; + case 111: + str_details2 = " certificate_unobtainable"; + break; + case 112: + str_details2 = " unrecognized_name"; + break; + case 113: + str_details2 = " bad_certificate_status_response"; + break; + case 114: + str_details2 = " bad_certificate_hash_value"; + break; } } } @@ -539,6 +570,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * case 2: str_details1 = ", ServerHello"; break; + case 3: + str_details1 = ", HelloVerifyRequest"; + break; case 11: str_details1 = ", Certificate"; break; @@ -554,9 +588,6 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * case 15: str_details1 = ", CertificateVerify"; break; - case 3: - str_details1 = ", HelloVerifyRequest"; - break; case 16: str_details1 = ", ClientKeyExchange"; break; @@ -642,6 +673,12 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, extname = "renegotiate"; break; +#ifdef TLSEXT_TYPE_opaque_prf_input + case TLSEXT_TYPE_opaque_prf_input: + extname = "opaque PRF input"; + break; +#endif + default: extname = "unknown"; break; @@ -659,8 +696,14 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign { unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned int length, resultlength; - struct sockaddr_in peer; - + union { + struct sockaddr sa; + struct sockaddr_in s4; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 s6; +#endif + } peer; + /* Initialize a random secret */ if (!cookie_initialized) { @@ -676,8 +719,23 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); /* Create buffer with peer's address and port */ - length = sizeof(peer.sin_addr); - length += sizeof(peer.sin_port); + length = 0; + switch (peer.sa.sa_family) + { + case AF_INET: + length += sizeof(struct in_addr); + length += sizeof(peer.s4.sin_port); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + length += sizeof(struct in6_addr); + length += sizeof(peer.s6.sin6_port); + break; +#endif + default: + OPENSSL_assert(0); + break; + } buffer = OPENSSL_malloc(length); if (buffer == NULL) @@ -685,9 +743,31 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign BIO_printf(bio_err,"out of memory\n"); return 0; } - - memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); - memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); + + switch (peer.sa.sa_family) + { + case AF_INET: + memcpy(buffer, + &peer.s4.sin_port, + sizeof(peer.s4.sin_port)); + memcpy(buffer + sizeof(peer.s4.sin_port), + &peer.s4.sin_addr, + sizeof(struct in_addr)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(buffer, + &peer.s6.sin6_port, + sizeof(peer.s6.sin6_port)); + memcpy(buffer + sizeof(peer.s6.sin6_port), + &peer.s6.sin6_addr, + sizeof(struct in6_addr)); + break; +#endif + default: + OPENSSL_assert(0); + break; + } /* Calculate HMAC of buffer using the secret */ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, @@ -704,8 +784,14 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned { unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned int length, resultlength; - struct sockaddr_in peer; - + union { + struct sockaddr sa; + struct sockaddr_in s4; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 s6; +#endif + } peer; + /* If secret isn't initialized yet, the cookie can't be valid */ if (!cookie_initialized) return 0; @@ -714,24 +800,61 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); /* Create buffer with peer's address and port */ - length = sizeof(peer.sin_addr); - length += sizeof(peer.sin_port); - buffer = (unsigned char*) OPENSSL_malloc(length); + length = 0; + switch (peer.sa.sa_family) + { + case AF_INET: + length += sizeof(struct in_addr); + length += sizeof(peer.s4.sin_port); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + length += sizeof(struct in6_addr); + length += sizeof(peer.s6.sin6_port); + break; +#endif + default: + OPENSSL_assert(0); + break; + } + buffer = OPENSSL_malloc(length); if (buffer == NULL) { BIO_printf(bio_err,"out of memory\n"); return 0; } - - memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); - memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); + + switch (peer.sa.sa_family) + { + case AF_INET: + memcpy(buffer, + &peer.s4.sin_port, + sizeof(peer.s4.sin_port)); + memcpy(buffer + sizeof(peer.s4.sin_port), + &peer.s4.sin_addr, + sizeof(struct in_addr)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(buffer, + &peer.s6.sin6_port, + sizeof(peer.s6.sin6_port)); + memcpy(buffer + sizeof(peer.s6.sin6_port), + &peer.s6.sin6_addr, + sizeof(struct in6_addr)); + break; +#endif + default: + OPENSSL_assert(0); + break; + } /* Calculate HMAC of buffer using the secret */ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, buffer, length, result, &resultlength); OPENSSL_free(buffer); - + if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) return 1; diff --git a/crypto/openssl/apps/s_client.c b/crypto/openssl/apps/s_client.c index 2f743f0a0a..34ad2cec78 100644 --- a/crypto/openssl/apps/s_client.c +++ b/crypto/openssl/apps/s_client.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -108,8 +108,35 @@ * Hudson (tjh@cryptsoft.com). * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include +#include #include #include #include @@ -135,23 +162,19 @@ typedef unsigned int u_int; #include #include #include +#include #include "s_apps.h" #include "timeouts.h" -#ifdef OPENSSL_SYS_WINCE -/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */ -#ifdef fileno -#undef fileno -#endif -#define fileno(a) (int)_fileno(a) -#endif - - #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ #undef FIONBIO #endif +#if defined(OPENSSL_SYS_BEOS_R5) +#include +#endif + #undef PROG #define PROG s_client_main @@ -166,6 +189,7 @@ typedef unsigned int u_int; extern int verify_depth; extern int verify_error; +extern int verify_return_error; #ifdef FIONBIO static int c_nbio=0; @@ -188,6 +212,69 @@ static BIO *bio_c_out=NULL; static int c_quiet=0; static int c_ign_eof=0; +#ifndef OPENSSL_NO_PSK +/* Default PSK identity and key */ +static char *psk_identity="Client_identity"; +/*char *psk_key=NULL; by default PSK is not used */ + +static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len) + { + unsigned int psk_len = 0; + int ret; + BIGNUM *bn=NULL; + + if (c_debug) + BIO_printf(bio_c_out, "psk_client_cb\n"); + if (!hint) + { + /* no ServerKeyExchange message*/ + if (c_debug) + BIO_printf(bio_c_out,"NULL received PSK identity hint, continuing anyway\n"); + } + else if (c_debug) + BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint); + + /* lookup PSK identity and PSK key based on the given identity hint here */ + ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity); + if (ret < 0 || (unsigned int)ret > max_identity_len) + goto out_err; + if (c_debug) + BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret); + ret=BN_hex2bn(&bn, psk_key); + if (!ret) + { + BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key); + if (bn) + BN_free(bn); + return 0; + } + + if ((unsigned int)BN_num_bytes(bn) > max_psk_len) + { + BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n", + max_psk_len, BN_num_bytes(bn)); + BN_free(bn); + return 0; + } + + psk_len=BN_bn2bin(bn, psk); + BN_free(bn); + if (psk_len == 0) + goto out_err; + + if (c_debug) + BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len); + + return psk_len; + out_err: + if (c_debug) + BIO_printf(bio_err, "Error in PSK client callback\n"); + return 0; + } +#endif + static void sc_usage(void) { BIO_printf(bio_err,"usage: s_client args\n"); @@ -196,7 +283,7 @@ static void sc_usage(void) BIO_printf(bio_err," -port port - use -connect instead\n"); BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); - BIO_printf(bio_err," -verify depth - turn on peer certificate verification\n"); + BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n"); BIO_printf(bio_err," -key arg - Private key file to use, in cert file if\n"); @@ -222,6 +309,13 @@ static void sc_usage(void) BIO_printf(bio_err," -quiet - no s_client output\n"); BIO_printf(bio_err," -ign_eof - ignore input eof (default when -quiet)\n"); BIO_printf(bio_err," -no_ign_eof - don't ignore input eof\n"); +#ifndef OPENSSL_NO_PSK + BIO_printf(bio_err," -psk_identity arg - PSK identity\n"); + BIO_printf(bio_err," -psk arg - PSK in hex (without 0x)\n"); +# ifndef OPENSSL_NO_JPAKE + BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n"); +# endif +#endif BIO_printf(bio_err," -ssl2 - just use SSLv2\n"); BIO_printf(bio_err," -ssl3 - just use SSLv3\n"); BIO_printf(bio_err," -tls1 - just use TLSv1\n"); @@ -273,6 +367,7 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) return SSL_TLSEXT_ERR_OK; } #endif + enum { PROTO_OFF = 0, @@ -287,9 +382,8 @@ int MAIN(int, char **); int MAIN(int argc, char **argv) { - int off=0, clr = 0; - SSL *con=NULL,*con2=NULL; - X509_STORE *store = NULL; + unsigned int off=0, clr=0; + SSL *con=NULL; int s,k,width,state=0; char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; int cbuf_len,cbuf_off; @@ -310,12 +404,11 @@ int MAIN(int argc, char **argv) SSL_CTX *ctx=NULL; int ret=1,in_init=1,i,nbio_test=0; int starttls_proto = PROTO_OFF; - int prexit = 0, vflags = 0; - SSL_METHOD *meth=NULL; -#ifdef sock_type -#undef sock_type -#endif - int sock_type=SOCK_STREAM; + int prexit = 0; + X509_VERIFY_PARAM *vpm = NULL; + int badarg = 0; + const SSL_METHOD *meth=NULL; + int socket_type=SOCK_STREAM; BIO *sbio; char *inrand=NULL; int mbuf_len=0; @@ -326,10 +419,12 @@ int MAIN(int argc, char **argv) ENGINE *ssl_client_engine=NULL; #endif ENGINE *e=NULL; -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) struct timeval tv; +#if defined(OPENSSL_SYS_BEOS_R5) + int stdin_set = 0; +#endif #endif - #ifndef OPENSSL_NO_TLSEXT char *servername = NULL; tlsextctx tlsextcbp = @@ -429,10 +524,14 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; cert_format = str2fmt(*(++argv)); } - else if (strcmp(*argv,"-crl_check") == 0) - vflags |= X509_V_FLAG_CRL_CHECK; - else if (strcmp(*argv,"-crl_check_all") == 0) - vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; + else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) + { + if (badarg) + goto bad; + continue; + } + else if (strcmp(*argv,"-verify_return_error") == 0) + verify_return_error = 1; else if (strcmp(*argv,"-prexit") == 0) prexit=1; else if (strcmp(*argv,"-crlf") == 0) @@ -468,6 +567,27 @@ int MAIN(int argc, char **argv) nbio_test=1; else if (strcmp(*argv,"-state") == 0) state=1; +#ifndef OPENSSL_NO_PSK + else if (strcmp(*argv,"-psk_identity") == 0) + { + if (--argc < 1) goto bad; + psk_identity=*(++argv); + } + else if (strcmp(*argv,"-psk") == 0) + { + size_t j; + + if (--argc < 1) goto bad; + psk_key=*(++argv); + for (j = 0; j < strlen(psk_key); j++) + { + if (isxdigit((int)psk_key[j])) + continue; + BIO_printf(bio_err,"Not a hex number '%s'\n",*argv); + goto bad; + } + } +#endif #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv,"-ssl2") == 0) meth=SSLv2_client_method(); @@ -484,7 +604,7 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"-dtls1") == 0) { meth=DTLSv1_client_method(); - sock_type=SOCK_DGRAM; + socket_type=SOCK_DGRAM; } else if (strcmp(*argv,"-timeout") == 0) enable_timeouts=1; @@ -531,6 +651,8 @@ int MAIN(int argc, char **argv) off|=SSL_OP_NO_SSLv3; else if (strcmp(*argv,"-no_ssl2") == 0) off|=SSL_OP_NO_SSLv2; + else if (strcmp(*argv,"-no_comp") == 0) + { off|=SSL_OP_NO_COMPRESSION; } #ifndef OPENSSL_NO_TLSEXT else if (strcmp(*argv,"-no_ticket") == 0) { off|=SSL_OP_NO_TICKET; } @@ -617,6 +739,26 @@ bad: goto end; } +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) + if (jpake_secret) + { + if (psk_key) + { + BIO_printf(bio_err, + "Can't use JPAKE and PSK together\n"); + goto end; + } + psk_identity = "JPAKE"; + } + + if (cipher) + { + BIO_printf(bio_err, "JPAKE sets cipher to PSK\n"); + goto end; + } + cipher = "PSK"; +#endif + OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); @@ -632,6 +774,7 @@ bad: goto end; } } + #endif if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { @@ -699,6 +842,9 @@ bad: goto end; } + if (vpm) + SSL_CTX_set1_param(ctx, vpm); + #ifndef OPENSSL_NO_ENGINE if (ssl_client_engine) { @@ -713,6 +859,18 @@ bad: } #endif +#ifndef OPENSSL_NO_PSK +#ifdef OPENSSL_NO_JPAKE + if (psk_key != NULL) +#else + if (psk_key != NULL || jpake_secret) +#endif + { + if (c_debug) + BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n"); + SSL_CTX_set_psk_client_callback(ctx, psk_client_cb); + } +#endif if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL|off); else @@ -723,7 +881,7 @@ bad: /* DTLS: partial reads end up discarding unread UDP bytes :-( * Setting read ahead solves this problem. */ - if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); + if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); if (cipher != NULL) @@ -749,8 +907,6 @@ bad: /* goto end; */ } - store = SSL_CTX_get_cert_store(ctx); - X509_STORE_set_flags(store, vflags); #ifndef OPENSSL_NO_TLSEXT if (servername != NULL) { @@ -795,7 +951,6 @@ bad: } } #endif - #ifndef OPENSSL_NO_KRB5 if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL) { @@ -803,10 +958,15 @@ bad: } #endif /* OPENSSL_NO_KRB5 */ /* SSL_set_cipher_list(con,"RC4-MD5"); */ +#if 0 +#ifdef TLSEXT_TYPE_opaque_prf_input + SSL_set_tlsext_opaque_prf_input(con, "Test client", 11); +#endif +#endif re_start: - if (init_client(&s,host,port,sock_type) == 0) + if (init_client(&s,host,port,socket_type) == 0) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); SHUTDOWN(s); @@ -842,7 +1002,7 @@ re_start: (void)BIO_ctrl_set_connected(sbio, 1, &peer); - if ( enable_timeouts) + if (enable_timeouts) { timeout.tv_sec = 0; timeout.tv_usec = DGRAM_RCV_TIMEOUT; @@ -1063,6 +1223,14 @@ SSL_set_tlsext_status_ids(con, ids); if (in_init) { in_init=0; +#if 0 /* This test doesn't really work as intended (needs to be fixed) */ +#ifndef OPENSSL_NO_TLSEXT + if (servername != NULL && !SSL_session_reused(con)) + { + BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not "); + } +#endif +#endif if (sess_out) { BIO *stmp = BIO_new_file(sess_out, "w"); @@ -1100,22 +1268,22 @@ SSL_set_tlsext_status_ids(con, ids); if (!ssl_pending) { -#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5) if (tty_on) { - if (read_tty) FD_SET(fileno(stdin),&readfds); - if (write_tty) FD_SET(fileno(stdout),&writefds); + if (read_tty) openssl_fdset(fileno(stdin),&readfds); + if (write_tty) openssl_fdset(fileno(stdout),&writefds); } if (read_ssl) - FD_SET(SSL_get_fd(con),&readfds); + openssl_fdset(SSL_get_fd(con),&readfds); if (write_ssl) - FD_SET(SSL_get_fd(con),&writefds); + openssl_fdset(SSL_get_fd(con),&writefds); #else if(!tty_on || !write_tty) { if (read_ssl) - FD_SET(SSL_get_fd(con),&readfds); + openssl_fdset(SSL_get_fd(con),&readfds); if (write_ssl) - FD_SET(SSL_get_fd(con),&writefds); + openssl_fdset(SSL_get_fd(con),&writefds); } #endif /* printf("mode tty(%d %d%d) ssl(%d%d)\n", @@ -1160,6 +1328,25 @@ SSL_set_tlsext_status_ids(con, ids); } else i=select(width,(void *)&readfds,(void *)&writefds, NULL,timeoutp); } +#elif defined(OPENSSL_SYS_BEOS_R5) + /* Under BeOS-R5 the situation is similar to DOS */ + i=0; + stdin_set = 0; + (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + if(!write_tty) { + if(read_tty) { + tv.tv_sec = 1; + tv.tv_usec = 0; + i=select(width,(void *)&readfds,(void *)&writefds, + NULL,&tv); + if (read(fileno(stdin), sbuf, 0) >= 0) + stdin_set = 1; + if (!i && (stdin_set != 1 || !read_tty)) + continue; + } else i=select(width,(void *)&readfds,(void *)&writefds, + NULL,timeoutp); + } + (void)fcntl(fileno(stdin), F_SETFL, 0); #else i=select(width,(void *)&readfds,(void *)&writefds, NULL,timeoutp); @@ -1218,6 +1405,7 @@ SSL_set_tlsext_status_ids(con, ids); if (cbuf_len != 0) { BIO_printf(bio_c_out,"shutdown\n"); + ret = 0; goto shut; } else @@ -1245,8 +1433,8 @@ SSL_set_tlsext_status_ids(con, ids); goto shut; } } -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) - /* Assume Windows/DOS can always write */ +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) + /* Assume Windows/DOS/BeOS can always write */ else if (!ssl_pending && write_tty) #else else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds)) @@ -1255,11 +1443,12 @@ SSL_set_tlsext_status_ids(con, ids); #ifdef CHARSET_EBCDIC ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len); #endif - i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len); + i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len); if (i <= 0) { BIO_printf(bio_c_out,"DONE\n"); + ret = 0; goto shut; /* goto end; */ } @@ -1314,10 +1503,12 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 BIO_printf(bio_c_out,"read X BLOCK\n"); break; case SSL_ERROR_SYSCALL: - BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error()); + ret=get_last_socket_error(); + BIO_printf(bio_err,"read:errno=%d\n",ret); goto shut; case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_c_out,"closed\n"); + ret=0; goto shut; case SSL_ERROR_SSL: ERR_print_errors(bio_err); @@ -1333,7 +1524,9 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) #endif #elif defined (OPENSSL_SYS_NETWARE) - else if (_kbhit()) + else if (_kbhit()) +#elif defined(OPENSSL_SYS_BEOS_R5) + else if (stdin_set) #else else if (FD_ISSET(fileno(stdin),&readfds)) #endif @@ -1342,7 +1535,7 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 { int j, lf_num; - i=read(fileno(stdin),cbuf,BUFSIZZ/2); + i=raw_read_stdin(cbuf,BUFSIZZ/2); lf_num = 0; /* both loops are skipped when i <= 0 */ for (j = 0; j < i; j++) @@ -1361,11 +1554,12 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 assert(lf_num == 0); } else - i=read(fileno(stdin),cbuf,BUFSIZZ); + i=raw_read_stdin(cbuf,BUFSIZZ); if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { BIO_printf(bio_err,"DONE\n"); + ret=0; goto shut; } @@ -1388,14 +1582,20 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 read_tty=0; } } + + ret=0; shut: + if (in_init) + print_stuff(bio_c_out,con,full_log); SSL_shutdown(con); SHUTDOWN(SSL_get_fd(con)); - ret=0; end: - if(prexit) print_stuff(bio_c_out,con,1); - if (con != NULL) SSL_free(con); - if (con2 != NULL) SSL_free(con2); + if (con != NULL) + { + if (prexit != 0) + print_stuff(bio_c_out,con,1); + SSL_free(con); + } if (ctx != NULL) SSL_CTX_free(ctx); if (cert) X509_free(cert); @@ -1424,7 +1624,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) char buf[BUFSIZ]; STACK_OF(X509) *sk; STACK_OF(X509_NAME) *sk2; - SSL_CIPHER *c; + const SSL_CIPHER *c; X509_NAME *xn; int j,i; #ifndef OPENSSL_NO_COMP @@ -1577,4 +1777,5 @@ static int ocsp_resp_cb(SSL *s, void *arg) OCSP_RESPONSE_free(rsp); return 1; } -#endif /* ndef OPENSSL_NO_TLSEXT */ + +#endif diff --git a/crypto/openssl/apps/s_server.c b/crypto/openssl/apps/s_server.c index 88b308ca38..1a06d19bb1 100644 --- a/crypto/openssl/apps/s_server.c +++ b/crypto/openssl/apps/s_server.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -113,6 +113,32 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ /* Until the key-gen callbacks are modified to use newer prototypes, we allow * deprecated functions for openssl-internal code */ @@ -121,11 +147,11 @@ #endif #include +#include #include #include #include -#include #include #ifdef OPENSSL_NO_STDIO #define APPS_WIN16 @@ -163,19 +189,15 @@ typedef unsigned int u_int; #include "s_apps.h" #include "timeouts.h" -#ifdef OPENSSL_SYS_WINCE -/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */ -#ifdef fileno -#undef fileno -#endif -#define fileno(a) (int)_fileno(a) -#endif - #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ #undef FIONBIO #endif +#if defined(OPENSSL_SYS_BEOS_R5) +#include +#endif + #ifndef OPENSSL_NO_RSA static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); #endif @@ -196,14 +218,6 @@ static DH *get_dh512(void); static void s_server_init(void); #endif -#ifndef S_ISDIR -# if defined(_S_IFMT) && defined(_S_IFDIR) -# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) -# else -# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) -# endif -#endif - #ifndef OPENSSL_NO_DH static unsigned char dh512_p[]={ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, @@ -245,7 +259,7 @@ static int accept_socket= -1; #undef PROG #define PROG s_server_main -extern int verify_depth; +extern int verify_depth, verify_return_error; static char *cipher=NULL; static int s_server_verify=SSL_VERIFY_NONE; @@ -288,6 +302,72 @@ static long socket_mtu; static int cert_chain = 0; #endif +#ifndef OPENSSL_NO_PSK +static char *psk_identity="Client_identity"; +char *psk_key=NULL; /* by default PSK is not used */ + +static unsigned int psk_server_cb(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len) + { + unsigned int psk_len = 0; + int ret; + BIGNUM *bn = NULL; + + if (s_debug) + BIO_printf(bio_s_out,"psk_server_cb\n"); + if (!identity) + { + BIO_printf(bio_err,"Error: client did not send PSK identity\n"); + goto out_err; + } + if (s_debug) + BIO_printf(bio_s_out,"identity_len=%d identity=%s\n", + identity ? (int)strlen(identity) : 0, identity); + + /* here we could lookup the given identity e.g. from a database */ + if (strcmp(identity, psk_identity) != 0) + { + BIO_printf(bio_s_out, "PSK error: client identity not found" + " (got '%s' expected '%s')\n", identity, + psk_identity); + goto out_err; + } + if (s_debug) + BIO_printf(bio_s_out, "PSK client identity found\n"); + + /* convert the PSK key to binary */ + ret = BN_hex2bn(&bn, psk_key); + if (!ret) + { + BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key); + if (bn) + BN_free(bn); + return 0; + } + if (BN_num_bytes(bn) > (int)max_psk_len) + { + BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n", + max_psk_len, BN_num_bytes(bn)); + BN_free(bn); + return 0; + } + + ret = BN_bn2bin(bn, psk); + BN_free(bn); + + if (ret < 0) + goto out_err; + psk_len = (unsigned int)ret; + + if (s_debug) + BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len); + return psk_len; + out_err: + if (s_debug) + BIO_printf(bio_err, "Error in PSK server callback\n"); + return 0; + } +#endif #ifdef MONOLITH static void s_server_init(void) @@ -352,7 +432,7 @@ static void sv_usage(void) #ifndef OPENSSL_NO_ECDH BIO_printf(bio_err," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ " Use \"openssl ecparam -list_curves\" for all names\n" \ - " (default is sect163r2).\n"); + " (default is nistp256).\n"); #endif #ifdef FIONBIO BIO_printf(bio_err," -nbio - Run with non-blocking IO\n"); @@ -369,6 +449,13 @@ static void sv_usage(void) BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n"); BIO_printf(bio_err," -quiet - No server output\n"); BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n"); +#ifndef OPENSSL_NO_PSK + BIO_printf(bio_err," -psk_hint arg - PSK identity hint to use\n"); + BIO_printf(bio_err," -psk arg - PSK in hex (without 0x)\n"); +# ifndef OPENSSL_NO_JPAKE + BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n"); +# endif +#endif BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); @@ -587,7 +674,7 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) return p->extension_error; if (ctx2) { - BIO_printf(p->biodebug,"Swiching server context.\n"); + BIO_printf(p->biodebug,"Switching server context.\n"); SSL_set_SSL_CTX(s,ctx2); } } @@ -626,7 +713,7 @@ static int cert_status_cb(SSL *s, void *arg) int use_ssl; unsigned char *rspder = NULL; int rspderlen; - STACK *aia = NULL; + STACK_OF(OPENSSL_STRING) *aia = NULL; X509 *x = NULL; X509_STORE_CTX inctx; X509_OBJECT obj; @@ -648,7 +735,7 @@ BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids)); aia = X509_get1_ocsp(x); if (aia) { - if (!OCSP_parse_url(sk_value(aia, 0), + if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), &host, &port, &path, &use_ssl)) { BIO_puts(err, "cert_status: can't parse AIA URL\n"); @@ -656,7 +743,7 @@ BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids)); } if (srctx->verbose) BIO_printf(err, "cert_status: AIA URL: %s\n", - sk_value(aia, 0)); + sk_OPENSSL_STRING_value(aia, 0)); } else { @@ -701,7 +788,7 @@ BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids)); if (!OCSP_REQUEST_add_ext(req, ext, -1)) goto err; } - resp = process_responder(err, req, host, path, port, use_ssl, + resp = process_responder(err, req, host, path, port, use_ssl, NULL, srctx->timeout); if (!resp) { @@ -740,6 +827,7 @@ BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids)); goto done; } #endif + int MAIN(int, char **); #ifndef OPENSSL_NO_JPAKE @@ -748,8 +836,8 @@ static char *jpake_secret = NULL; int MAIN(int argc, char *argv[]) { - X509_STORE *store = NULL; - int vflags = 0; + X509_VERIFY_PARAM *vpm = NULL; + int badarg = 0; short port=PORT; char *CApath=NULL,*CAfile=NULL; unsigned char *context = NULL; @@ -762,8 +850,8 @@ int MAIN(int argc, char *argv[]) int off=0; int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0; int state=0; - SSL_METHOD *meth=NULL; - int socket_type=SOCK_STREAM; + const SSL_METHOD *meth=NULL; + int socket_type=SOCK_STREAM; ENGINE *e=NULL; char *inrand=NULL; int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; @@ -780,7 +868,10 @@ int MAIN(int argc, char *argv[]) #ifndef OPENSSL_NO_TLSEXT tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; #endif - +#ifndef OPENSSL_NO_PSK + /* by default do not send a PSK identity hint */ + static char *psk_identity_hint=NULL; +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_server_method(); #elif !defined(OPENSSL_NO_SSL3) @@ -914,14 +1005,14 @@ int MAIN(int argc, char *argv[]) } else if (strcmp(*argv,"-no_cache") == 0) no_cache = 1; - else if (strcmp(*argv,"-crl_check") == 0) + else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { - vflags |= X509_V_FLAG_CRL_CHECK; - } - else if (strcmp(*argv,"-crl_check_all") == 0) - { - vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; + if (badarg) + goto bad; + continue; } + else if (strcmp(*argv,"-verify_return_error") == 0) + verify_return_error = 1; else if (strcmp(*argv,"-serverpref") == 0) { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } else if (strcmp(*argv,"-legacy_renegotiation") == 0) @@ -998,6 +1089,27 @@ int MAIN(int argc, char *argv[]) { no_dhe=1; } else if (strcmp(*argv,"-no_ecdhe") == 0) { no_ecdhe=1; } +#ifndef OPENSSL_NO_PSK + else if (strcmp(*argv,"-psk_hint") == 0) + { + if (--argc < 1) goto bad; + psk_identity_hint= *(++argv); + } + else if (strcmp(*argv,"-psk") == 0) + { + size_t i; + + if (--argc < 1) goto bad; + psk_key=*(++argv); + for (i=0; i 28) { SSL_set_options(con, SSL_OP_NO_QUERY_MTU); @@ -1738,10 +1902,10 @@ static int sv_body(char *hostname, int s, unsigned char *context) if (!read_from_sslcon) { FD_ZERO(&readfds); -#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) - FD_SET(fileno(stdin),&readfds); +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5) + openssl_fdset(fileno(stdin),&readfds); #endif - FD_SET(s,&readfds); + openssl_fdset(s,&readfds); /* Note: under VMS with SOCKETSHR the second parameter is * currently of type (int *) whereas under other systems * it is (void *) if you don't have a cast it will choke @@ -1760,6 +1924,17 @@ static int sv_body(char *hostname, int s, unsigned char *context) if((i < 0) || (!i && !_kbhit() ) )continue; if(_kbhit()) read_from_terminal = 1; +#elif defined(OPENSSL_SYS_BEOS_R5) + /* Under BeOS-R5 the situation is similar to DOS */ + tv.tv_sec = 1; + tv.tv_usec = 0; + (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + i=select(width,(void *)&readfds,NULL,NULL,&tv); + if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0)) + continue; + if (read(fileno(stdin), buf, 0) >= 0) + read_from_terminal = 1; + (void)fcntl(fileno(stdin), F_SETFL, 0); #else if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_get_timeout(con, &timeout)) @@ -1787,7 +1962,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) { int j, lf_num; - i=read(fileno(stdin), buf, bufsize/2); + i=raw_read_stdin(buf, bufsize/2); lf_num = 0; /* both loops are skipped when i <= 0 */ for (j = 0; j < i; j++) @@ -1806,7 +1981,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) assert(lf_num == 0); } else - i=read(fileno(stdin),buf,bufsize); + i=raw_read_stdin(buf,bufsize); if (!s_quiet) { if ((i <= 0) || (buf[0] == 'Q')) @@ -1826,6 +2001,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) ret= -11;*/ goto err; } + if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) { @@ -1922,7 +2098,7 @@ again: #ifdef CHARSET_EBCDIC ascii2ebcdic(buf,buf,i); #endif - write(fileno(stdout),buf, + raw_write_stdout(buf, (unsigned int)i); if (SSL_pending(con)) goto again; break; @@ -1946,13 +2122,16 @@ again: } } err: - BIO_printf(bio_s_out,"shutting down SSL\n"); + if (con != NULL) + { + BIO_printf(bio_s_out,"shutting down SSL\n"); #if 1 - SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); + SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); #else - SSL_shutdown(con); + SSL_shutdown(con); #endif - if (con != NULL) SSL_free(con); + SSL_free(con); + } BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); if (buf != NULL) { @@ -2076,9 +2255,8 @@ static int www_body(char *hostname, int s, unsigned char *context) char *buf=NULL; int ret=1; int i,j,k,blank,dot; - struct stat st_buf; SSL *con; - SSL_CIPHER *c; + const SSL_CIPHER *c; BIO *io,*ssl_bio,*sbio; long total_bytes; @@ -2348,14 +2526,7 @@ static int www_body(char *hostname, int s, unsigned char *context) #endif /* if a directory, do the index thang */ - if (stat(p,&st_buf) < 0) - { - BIO_puts(io,text); - BIO_printf(io,"Error accessing '%s'\r\n",p); - ERR_print_errors(io); - break; - } - if (S_ISDIR(st_buf.st_mode)) + if (app_isdir(p)>0) { #if 0 /* must check buffer size */ strcat(p,"/index.html"); diff --git a/crypto/openssl/apps/s_socket.c b/crypto/openssl/apps/s_socket.c index cf82358535..6b8713de60 100644 --- a/crypto/openssl/apps/s_socket.c +++ b/crypto/openssl/apps/s_socket.c @@ -237,13 +237,11 @@ static int ssl_sock_init(void) int init_client(int *sock, char *host, int port, int type) { unsigned char ip[4]; - short p=0; if (!host_ip(host,&(ip[0]))) { return(0); } - if (p != 0) port=p; return(init_client_ip(sock,ip,port,type)); } @@ -272,7 +270,7 @@ static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) if (s == INVALID_SOCKET) { perror("socket"); return(0); } -#ifndef OPENSSL_SYS_MPE +#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) if (type == SOCK_STREAM) { i=0; @@ -282,7 +280,7 @@ static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) #endif if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) - { close(s); perror("connect"); return(0); } + { closesocket(s); perror("connect"); return(0); } *sock=s; return(1); } @@ -291,7 +289,7 @@ int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, uns { int sock; char *name = NULL; - int accept_socket; + int accept_socket = 0; int i; if (!init_server(&accept_socket,port,type)) return(0); diff --git a/crypto/openssl/apps/s_time.c b/crypto/openssl/apps/s_time.c index 904945e1a8..b823c33c58 100644 --- a/crypto/openssl/apps/s_time.c +++ b/crypto/openssl/apps/s_time.c @@ -85,54 +85,6 @@ #include OPENSSL_UNISTD #endif -#if !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) -#define TIMES -#endif - -#ifndef _IRIX -#include -#endif -#ifdef TIMES -#include -#include -#endif - -/* Depending on the VMS version, the tms structure is perhaps defined. - The __TMS macro will show if it was. If it wasn't defined, we should - undefine TIMES, since that tells the rest of the program how things - should be handled. -- Richard Levitte */ -#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) -#undef TIMES -#endif - -#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE) -#include -#endif - -#if defined(sun) || defined(__ultrix) -#define _POSIX_SOURCE -#include -#include -#endif - -/* The following if from times(3) man page. It may need to be changed -*/ -#ifndef HZ -# ifdef _SC_CLK_TCK -# define HZ ((double)sysconf(_SC_CLK_TCK)) -# else -# ifndef CLK_TCK -# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ -# define HZ 100.0 -# else /* _BSD_CLK_TCK_ */ -# define HZ ((double)_BSD_CLK_TCK_) -# endif -# else /* CLK_TCK */ -# define HZ ((double)CLK_TCK) -# endif -# endif -#endif - #undef PROG #define PROG s_time_main @@ -177,7 +129,7 @@ static char *tm_cipher=NULL; static int tm_verify = SSL_VERIFY_NONE; static int maxTime = SECONDS; static SSL_CTX *tm_ctx=NULL; -static SSL_METHOD *s_time_meth=NULL; +static const SSL_METHOD *s_time_meth=NULL; static char *s_www_path=NULL; static long bytes_read=0; static int st_bugs=0; @@ -372,63 +324,8 @@ bad: static double tm_Time_F(int s) { - static double ret; -#ifdef TIMES - static struct tms tstart,tend; - - if(s == START) { - times(&tstart); - return(0); - } else { - times(&tend); - ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; - return((ret == 0.0)?1e-6:ret); + return app_tminterval(s,1); } -#elif defined(OPENSSL_SYS_NETWARE) - static clock_t tstart,tend; - - if (s == START) - { - tstart=clock(); - return(0); - } - else - { - tend=clock(); - ret=(double)((double)(tend)-(double)(tstart)); - return((ret < 0.001)?0.001:ret); - } -#elif defined(OPENSSL_SYS_VXWORKS) - { - static unsigned long tick_start, tick_end; - - if( s == START ) - { - tick_start = tickGet(); - return 0; - } - else - { - tick_end = tickGet(); - ret = (double)(tick_end - tick_start) / (double)sysClkRateGet(); - return((ret == 0.0)?1e-6:ret); - } - } -#else /* !times() */ - static struct timeb tstart,tend; - long i; - - if(s == START) { - ftime(&tstart); - return(0); - } else { - ftime(&tend); - i=(long)tend.millitm-(long)tstart.millitm; - ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; - return((ret == 0.0)?1e-6:ret); - } -#endif -} /*********************************************************************** * MAIN - main processing area for client @@ -704,7 +601,7 @@ static SSL *doConnection(SSL *scon) i=SSL_get_fd(serverCon); width=i+1; FD_ZERO(&readfds); - FD_SET(i,&readfds); + openssl_fdset(i,&readfds); /* Note: under VMS with SOCKETSHR the 2nd parameter * is currently of type (int *) whereas under other * systems it is (void *) if you don't have a cast it diff --git a/crypto/openssl/apps/smime.c b/crypto/openssl/apps/smime.c index 75804b8d7b..c583f8a0e1 100644 --- a/crypto/openssl/apps/smime.c +++ b/crypto/openssl/apps/smime.c @@ -73,11 +73,14 @@ static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int smime_cb(int ok, X509_STORE_CTX *ctx); #define SMIME_OP 0x10 +#define SMIME_IP 0x20 +#define SMIME_SIGNERS 0x40 #define SMIME_ENCRYPT (1 | SMIME_OP) -#define SMIME_DECRYPT 2 -#define SMIME_SIGN (3 | SMIME_OP) -#define SMIME_VERIFY 4 -#define SMIME_PK7OUT 5 +#define SMIME_DECRYPT (2 | SMIME_IP) +#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) +#define SMIME_VERIFY (4 | SMIME_IP) +#define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP) +#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) int MAIN(int, char **); @@ -90,6 +93,7 @@ int MAIN(int argc, char **argv) const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL; char *signerfile = NULL, *recipfile = NULL; + STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; const EVP_CIPHER *cipher = NULL; PKCS7 *p7 = NULL; @@ -105,6 +109,8 @@ int MAIN(int argc, char **argv) char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; + int indef = 0; + const EVP_MD *sign_md = NULL; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE @@ -135,6 +141,8 @@ int MAIN(int argc, char **argv) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; + else if (!strcmp (*args, "-resign")) + operation = SMIME_RESIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-pk7out")) @@ -193,205 +201,209 @@ int MAIN(int argc, char **argv) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; + else if (!strcmp (*args, "-stream")) + indef = 1; + else if (!strcmp (*args, "-indef")) + indef = 1; + else if (!strcmp (*args, "-noindef")) + indef = 0; else if (!strcmp (*args, "-nooldmime")) flags |= PKCS7_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= PKCS7_CRLFEOL; else if (!strcmp(*args,"-rand")) { - if (args[1]) - { - args++; - inrand = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + args++; + inrand = *args; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { - if (args[1]) - { - args++; - engine = *args; - } - else badarg = 1; + if (!args[1]) + goto argerr; + engine = *++args; } #endif else if (!strcmp(*args,"-passin")) { - if (args[1]) - { - args++; - passargin = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + passargin = *++args; } else if (!strcmp (*args, "-to")) { - if (args[1]) - { - args++; - to = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + to = *++args; } else if (!strcmp (*args, "-from")) { - if (args[1]) - { - args++; - from = *args; - } - else badarg = 1; + if (!args[1]) + goto argerr; + from = *++args; } else if (!strcmp (*args, "-subject")) { - if (args[1]) - { - args++; - subject = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + subject = *++args; } else if (!strcmp (*args, "-signer")) { - if (args[1]) + if (!args[1]) + goto argerr; + /* If previous -signer argument add signer to list */ + + if (signerfile) { - args++; - signerfile = *args; + if (!sksigners) + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); + if (!keyfile) + keyfile = signerfile; + if (!skkeys) + skkeys = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(skkeys, keyfile); + keyfile = NULL; } - else - badarg = 1; + signerfile = *++args; } else if (!strcmp (*args, "-recip")) { - if (args[1]) + if (!args[1]) + goto argerr; + recipfile = *++args; + } + else if (!strcmp (*args, "-md")) + { + if (!args[1]) + goto argerr; + sign_md = EVP_get_digestbyname(*++args); + if (sign_md == NULL) { - args++; - recipfile = *args; + BIO_printf(bio_err, "Unknown digest %s\n", + *args); + goto argerr; } - else badarg = 1; } else if (!strcmp (*args, "-inkey")) { - if (args[1]) + if (!args[1]) + goto argerr; + /* If previous -inkey arument add signer to list */ + if (keyfile) { - args++; - keyfile = *args; + if (!signerfile) + { + BIO_puts(bio_err, "Illegal -inkey without -signer\n"); + goto argerr; + } + if (!sksigners) + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); + signerfile = NULL; + if (!skkeys) + skkeys = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(skkeys, keyfile); } - else - badarg = 1; - } + keyfile = *++args; + } else if (!strcmp (*args, "-keyform")) { - if (args[1]) - { - args++; - keyform = str2fmt(*args); - } - else - badarg = 1; + if (!args[1]) + goto argerr; + keyform = str2fmt(*++args); } else if (!strcmp (*args, "-certfile")) { - if (args[1]) - { - args++; - certfile = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + certfile = *++args; } else if (!strcmp (*args, "-CAfile")) { - if (args[1]) - { - args++; - CAfile = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + CAfile = *++args; } else if (!strcmp (*args, "-CApath")) { - if (args[1]) - { - args++; - CApath = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + CApath = *++args; } else if (!strcmp (*args, "-in")) { - if (args[1]) - { - args++; - infile = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + infile = *++args; } else if (!strcmp (*args, "-inform")) { - if (args[1]) - { - args++; - informat = str2fmt(*args); - } - else - badarg = 1; + if (!args[1]) + goto argerr; + informat = str2fmt(*++args); } else if (!strcmp (*args, "-outform")) { - if (args[1]) - { - args++; - outformat = str2fmt(*args); - } - else - badarg = 1; + if (!args[1]) + goto argerr; + outformat = str2fmt(*++args); } else if (!strcmp (*args, "-out")) { - if (args[1]) - { - args++; - outfile = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + outfile = *++args; } else if (!strcmp (*args, "-content")) { - if (args[1]) - { - args++; - contfile = *args; - } - else - badarg = 1; + if (!args[1]) + goto argerr; + contfile = *++args; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; - else + else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) badarg = 1; args++; } + if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) + { + BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); + goto argerr; + } - if (operation == SMIME_SIGN) + if (operation & SMIME_SIGNERS) { - if (!signerfile) + /* Check to see if any final signer needs to be appended */ + if (keyfile && !signerfile) + { + BIO_puts(bio_err, "Illegal -inkey without -signer\n"); + goto argerr; + } + if (signerfile) + { + if (!sksigners) + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); + if (!skkeys) + skkeys = sk_OPENSSL_STRING_new_null(); + if (!keyfile) + keyfile = signerfile; + sk_OPENSSL_STRING_push(skkeys, keyfile); + } + if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } + signerfile = NULL; + keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) @@ -416,6 +428,7 @@ int MAIN(int argc, char **argv) if (badarg) { + argerr: BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); @@ -499,13 +512,11 @@ int MAIN(int argc, char **argv) ret = 2; - if (operation != SMIME_SIGN) + if (!(operation & SMIME_SIGNERS)) flags &= ~PKCS7_DETACHED; if (operation & SMIME_OP) { - if (flags & PKCS7_BINARY) - inmode = "rb"; if (outformat == FORMAT_ASN1) outmode = "wb"; } @@ -513,9 +524,18 @@ int MAIN(int argc, char **argv) { if (flags & PKCS7_BINARY) outmode = "wb"; + } + + if (operation & SMIME_IP) + { if (informat == FORMAT_ASN1) inmode = "rb"; } + else + { + if (flags & PKCS7_BINARY) + inmode = "rb"; + } if (operation == SMIME_ENCRYPT) { @@ -545,26 +565,11 @@ int MAIN(int argc, char **argv) } } - if (signerfile && (operation == SMIME_SIGN)) - { - if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL, - e, "signer certificate"))) - { -#if 0 /* An appropri message has already been printed */ - BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile); -#endif - goto end; - } - } - if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { -#if 0 /* An appropriate message has already been printed */ - BIO_printf(bio_err, "Can't read certificate file %s\n", certfile); -#endif ERR_print_errors(bio_err); goto end; } @@ -575,9 +580,6 @@ int MAIN(int argc, char **argv) if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { -#if 0 /* An appropriate message has alrady been printed */ - BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile); -#endif ERR_print_errors(bio_err); goto end; } @@ -615,6 +617,36 @@ int MAIN(int argc, char **argv) else in = BIO_new_fp(stdin, BIO_NOCLOSE); + if (operation & SMIME_IP) + { + if (informat == FORMAT_SMIME) + p7 = SMIME_read_PKCS7(in, &indata); + else if (informat == FORMAT_PEM) + p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); + else if (informat == FORMAT_ASN1) + p7 = d2i_PKCS7_bio(in, NULL); + else + { + BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); + goto end; + } + + if (!p7) + { + BIO_printf(bio_err, "Error reading S/MIME message\n"); + goto end; + } + if (contfile) + { + BIO_free(indata); + if (!(indata = BIO_new_file(contfile, "rb"))) + { + BIO_printf(bio_err, "Can't read content file %s\n", contfile); + goto end; + } + } + } + if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) @@ -639,7 +671,7 @@ int MAIN(int argc, char **argv) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; - X509_STORE_set_verify_cb_func(store, smime_cb); + X509_STORE_set_verify_cb(store, smime_cb); if (vpm) X509_STORE_set1_param(store, vpm); } @@ -648,43 +680,58 @@ int MAIN(int argc, char **argv) ret = 3; if (operation == SMIME_ENCRYPT) - p7 = PKCS7_encrypt(encerts, in, cipher, flags); - else if (operation == SMIME_SIGN) { - /* If detached data and SMIME output enable partial - * signing. - */ - if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) + if (indef) flags |= PKCS7_STREAM; - p7 = PKCS7_sign(signer, key, other, in, flags); + p7 = PKCS7_encrypt(encerts, in, cipher, flags); } - else + else if (operation & SMIME_SIGNERS) { - if (informat == FORMAT_SMIME) - p7 = SMIME_read_PKCS7(in, &indata); - else if (informat == FORMAT_PEM) - p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); - else if (informat == FORMAT_ASN1) - p7 = d2i_PKCS7_bio(in, NULL); - else + int i; + /* If detached data content we only enable streaming if + * S/MIME output format. + */ + if (operation == SMIME_SIGN) { - BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); - goto end; + if (flags & PKCS7_DETACHED) + { + if (outformat == FORMAT_SMIME) + flags |= PKCS7_STREAM; + } + else if (indef) + flags |= PKCS7_STREAM; + flags |= PKCS7_PARTIAL; + p7 = PKCS7_sign(NULL, NULL, other, in, flags); + if (!p7) + goto end; } - - if (!p7) - { - BIO_printf(bio_err, "Error reading S/MIME message\n"); - goto end; + else + flags |= PKCS7_REUSE_DIGEST; + for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) + { + signerfile = sk_OPENSSL_STRING_value(sksigners, i); + keyfile = sk_OPENSSL_STRING_value(skkeys, i); + signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL, + e, "signer certificate"); + if (!signer) + goto end; + key = load_key(bio_err, keyfile, keyform, 0, passin, e, + "signing key file"); + if (!key) + goto end; + if (!PKCS7_sign_add_signer(p7, signer, key, + sign_md, flags)) + goto end; + X509_free(signer); + signer = NULL; + EVP_PKEY_free(key); + key = NULL; } - if (contfile) + /* If not streaming or resigning finalize structure */ + if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) { - BIO_free(indata); - if (!(indata = BIO_new_file(contfile, "rb"))) - { - BIO_printf(bio_err, "Can't read content file %s\n", contfile); + if (!PKCS7_final(p7, in, flags)) goto end; - } } } @@ -734,11 +781,16 @@ int MAIN(int argc, char **argv) if (subject) BIO_printf(out, "Subject: %s\n", subject); if (outformat == FORMAT_SMIME) - SMIME_write_PKCS7(out, p7, in, flags); + { + if (operation == SMIME_RESIGN) + SMIME_write_PKCS7(out, p7, indata, flags); + else + SMIME_write_PKCS7(out, p7, in, flags); + } else if (outformat == FORMAT_PEM) - PEM_write_bio_PKCS7(out,p7); + PEM_write_bio_PKCS7_stream(out, p7, in, flags); else if (outformat == FORMAT_ASN1) - i2d_PKCS7_bio(out,p7); + i2d_PKCS7_bio_stream(out,p7, in, flags); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); @@ -754,6 +806,10 @@ end: sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); + if (sksigners) + sk_OPENSSL_STRING_free(sksigners); + if (skkeys) + sk_OPENSSL_STRING_free(skkeys); X509_STORE_free(store); X509_free(cert); X509_free(recip); diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c index 07f0ae04a6..539bfff220 100644 --- a/crypto/openssl/apps/speed.c +++ b/crypto/openssl/apps/speed.c @@ -108,53 +108,8 @@ #include #endif -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(OPENSSL_SYS_MACOSX) -# define USE_TOD -#elif !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) -# define TIMES -#endif -#if !defined(_UNICOS) && !defined(__OpenBSD__) && !defined(sgi) && !defined(__FreeBSD__) && !(defined(__bsdi) || defined(__bsdi__)) && !defined(_AIX) && !defined(OPENSSL_SYS_MPE) && !defined(__NetBSD__) && !defined(OPENSSL_SYS_VXWORKS) /* FIXME */ -# define TIMEB -#endif - -#if defined(OPENSSL_SYS_NETWARE) -#undef TIMES -#undef TIMEB -#include -#endif - -#ifndef _IRIX -# include -#endif -#ifdef TIMES -# include -# include -#endif -#ifdef USE_TOD -# include -# include -#endif - -/* Depending on the VMS version, the tms structure is perhaps defined. - The __TMS macro will show if it was. If it wasn't defined, we should - undefine TIMES, since that tells the rest of the program how things - should be handled. -- Richard Levitte */ -#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) -#undef TIMES -#endif - -#ifdef TIMEB -#include -#endif - -#if !defined(TIMES) && !defined(TIMEB) && !defined(USE_TOD) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE) -#error "It seems neither struct tms nor struct timeb is supported in this platform!" -#endif - -#if defined(sun) || defined(__ultrix) -#define _POSIX_SOURCE -#include -#include +#ifdef _WIN32 +#include #endif #include @@ -189,6 +144,9 @@ #ifndef OPENSSL_NO_RIPEMD #include #endif +#ifndef OPENSSL_NO_WHIRLPOOL +#include +#endif #ifndef OPENSSL_NO_RC4 #include #endif @@ -226,47 +184,24 @@ #include #endif -/* - * The following "HZ" timing stuff should be sync'd up with the code in - * crypto/tmdiff.[ch]. That appears to try to do the same job, though I think - * this code is more up to date than libcrypto's so there may be features to - * migrate over first. This is used in two places further down AFAICS. - * The point is that nothing in openssl actually *uses* that tmdiff stuff, so - * either speed.c should be using it or it should go because it's obviously not - * useful enough. Anyone want to do a janitorial job on this? - */ - -/* The following if from times(3) man page. It may need to be changed */ -#ifndef HZ -# if defined(_SC_CLK_TCK) \ - && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000) -# define HZ sysconf(_SC_CLK_TCK) +#ifndef HAVE_FORK +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE) +# define HAVE_FORK 0 # else -# ifndef CLK_TCK -# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ -# define HZ 100.0 -# else /* _BSD_CLK_TCK_ */ -# define HZ ((double)_BSD_CLK_TCK_) -# endif -# else /* CLK_TCK */ -# define HZ ((double)CLK_TCK) -# endif +# define HAVE_FORK 1 # endif #endif -#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE) -# define NO_FORK 1 -#elif HAVE_FORK -# undef NO_FORK +#if HAVE_FORK +#undef NO_FORK #else -# define NO_FORK 1 +#define NO_FORK #endif #undef BUFSIZE #define BUFSIZE ((long)1024*8+1) int run=0; -static char ftime_used = 0, times_used = 0, gettimeofday_used = 0, getrusage_used = 0; static int mr=0; static int usertime=1; @@ -279,7 +214,7 @@ static void print_result(int alg,int run_no,int count,double time_used); static int do_multi(int multi); #endif -#define ALGOR_NUM 28 +#define ALGOR_NUM 29 #define SIZE_NUM 5 #define RSA_NUM 4 #define DSA_NUM 3 @@ -293,7 +228,7 @@ static const char *names[ALGOR_NUM]={ "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc", "aes-128 cbc","aes-192 cbc","aes-256 cbc", "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc", - "evp","sha256","sha512", + "evp","sha256","sha512","whirlpool", "aes-128 ige","aes-192 ige","aes-256 ige"}; static double results[ALGOR_NUM][SIZE_NUM]; static int lengths[SIZE_NUM]={16,64,256,1024,8*1024}; @@ -336,141 +271,46 @@ static SIGRETTYPE sig_done(int sig) #define START 0 #define STOP 1 -#if defined(OPENSSL_SYS_NETWARE) +#if defined(_WIN32) - /* for NetWare the best we can do is use clock() which returns the - * time, in hundredths of a second, since the NLM began executing - */ -static double Time_F(int s) - { - double ret; - - static clock_t tstart,tend; - - if (s == START) - { - tstart=clock(); - return(0); - } - else - { - tend=clock(); - ret=(double)((double)(tend)-(double)(tstart)); - return((ret < 0.001)?0.001:ret); - } - } +#define SIGALRM +static unsigned int lapse,schlock; +static void alarm(unsigned int secs) { lapse = secs*1000; } -#else +static DWORD WINAPI sleepy(VOID *arg) + { + schlock = 1; + Sleep(lapse); + run = 0; + return 0; + } static double Time_F(int s) { - double ret; - -#ifdef USE_TOD - if(usertime) + if (s == START) { - static struct rusage tstart,tend; - - getrusage_used = 1; - if (s == START) + HANDLE thr; + schlock = 0; + thr = CreateThread(NULL,4096,sleepy,NULL,0,NULL); + if (thr==NULL) { - getrusage(RUSAGE_SELF,&tstart); - return(0); - } - else - { - long i; - - getrusage(RUSAGE_SELF,&tend); - i=(long)tend.ru_utime.tv_usec-(long)tstart.ru_utime.tv_usec; - ret=((double)(tend.ru_utime.tv_sec-tstart.ru_utime.tv_sec)) - +((double)i)/1000000.0; - return((ret < 0.001)?0.001:ret); - } - } - else - { - static struct timeval tstart,tend; - long i; - - gettimeofday_used = 1; - if (s == START) - { - gettimeofday(&tstart,NULL); - return(0); - } - else - { - gettimeofday(&tend,NULL); - i=(long)tend.tv_usec-(long)tstart.tv_usec; - ret=((double)(tend.tv_sec-tstart.tv_sec))+((double)i)/1000000.0; - return((ret < 0.001)?0.001:ret); - } - } -#else /* ndef USE_TOD */ - -# ifdef TIMES - if (usertime) - { - static struct tms tstart,tend; - - times_used = 1; - if (s == START) - { - times(&tstart); - return(0); - } - else - { - times(&tend); - ret = HZ; - ret=(double)(tend.tms_utime-tstart.tms_utime) / ret; - return((ret < 1e-3)?1e-3:ret); + DWORD ret=GetLastError(); + BIO_printf(bio_err,"unable to CreateThread (%d)",ret); + ExitProcess(ret); } + CloseHandle(thr); /* detach the thread */ + while (!schlock) Sleep(0); /* scheduler spinlock */ } -# endif /* times() */ -# if defined(TIMES) && defined(TIMEB) - else -# endif -# ifdef OPENSSL_SYS_VXWORKS - { - static unsigned long tick_start, tick_end; - if( s == START ) - { - tick_start = tickGet(); - return 0; - } - else - { - tick_end = tickGet(); - ret = (double)(tick_end - tick_start) / (double)sysClkRateGet(); - return((ret < 0.001)?0.001:ret); - } - } -# elif defined(TIMEB) - { - static struct timeb tstart,tend; - long i; + return app_tminterval(s,usertime); + } +#else - ftime_used = 1; - if (s == START) - { - ftime(&tstart); - return(0); - } - else - { - ftime(&tend); - i=(long)tend.millitm-(long)tstart.millitm; - ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; - return((ret < 0.001)?0.001:ret); - } - } -# endif -#endif +static double Time_F(int s) + { + return app_tminterval(s,usertime); } -#endif /* if defined(OPENSSL_SYS_NETWARE) */ +#endif #ifndef OPENSSL_NO_ECDH @@ -530,6 +370,9 @@ int MAIN(int argc, char **argv) unsigned char sha512[SHA512_DIGEST_LENGTH]; #endif #endif +#ifndef OPENSSL_NO_WHIRLPOOL + unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH]; +#endif #ifndef OPENSSL_NO_RIPEMD unsigned char rmd160[RIPEMD160_DIGEST_LENGTH]; #endif @@ -626,9 +469,10 @@ int MAIN(int argc, char **argv) #define D_EVP 22 #define D_SHA256 23 #define D_SHA512 24 -#define D_IGE_128_AES 25 -#define D_IGE_192_AES 26 -#define D_IGE_256_AES 27 +#define D_WHIRLPOOL 25 +#define D_IGE_128_AES 26 +#define D_IGE_192_AES 27 +#define D_IGE_256_AES 28 double d=0.0; long c[ALGOR_NUM][SIZE_NUM]; #define R_DSA_512 0 @@ -948,6 +792,10 @@ int MAIN(int argc, char **argv) else #endif #endif +#ifndef OPENSSL_NO_WHIRLPOOL + if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1; + else +#endif #ifndef OPENSSL_NO_RIPEMD if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1; else @@ -1159,12 +1007,16 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_SHA512 BIO_printf(bio_err,"sha512 "); #endif +#ifndef OPENSSL_NO_WHIRLPOOL + BIO_printf(bio_err,"whirlpool"); +#endif #ifndef OPENSSL_NO_RIPEMD160 BIO_printf(bio_err,"rmd160"); #endif #if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \ !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \ - !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) + !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \ + !defined(OPENSSL_NO_WHIRLPOOL) BIO_printf(bio_err,"\n"); #endif @@ -1291,17 +1143,20 @@ int MAIN(int argc, char **argv) rsa_doit[i]=1; for (i=0; i 1 ? "," : ""), - (times_used ? "times" : ""), - (ftime_used + times_used + gettimeofday_used > 1 ? "," : ""), - (gettimeofday_used ? "gettimeofday" : ""), - (ftime_used + times_used + gettimeofday_used + getrusage_used > 1 ? "," : ""), - (getrusage_used ? "getrusage" : "")); } if (pr_header) @@ -2783,6 +2630,7 @@ static int do_multi(int multi) close(fd[1]); mr=1; usertime=0; + free(fds); return 0; } printf("Forked child %d\n",n); @@ -2931,7 +2779,10 @@ static int do_multi(int multi) else fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n); } + + fclose(f); } + free(fds); return 1; } #endif diff --git a/crypto/openssl/apps/ts.c b/crypto/openssl/apps/ts.c new file mode 100644 index 0000000000..5fa9f7fda0 --- /dev/null +++ b/crypto/openssl/apps/ts.c @@ -0,0 +1,1147 @@ +/* apps/ts.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2001 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 +#include +#include +#include "apps.h" +#include +#include +#include +#include +#include +#include + +#undef PROG +#define PROG ts_main + +/* Length of the nonce of the request in bits (must be a multiple of 8). */ +#define NONCE_LENGTH 64 + +/* Macro definitions for the configuration file. */ +#define ENV_OID_FILE "oid_file" + +/* Local function declarations. */ + +static ASN1_OBJECT *txt2obj(const char *oid); +static CONF *load_config_file(const char *configfile); + +/* Query related functions. */ +static int query_command(const char *data, char *digest, + const EVP_MD *md, const char *policy, int no_nonce, + int cert, const char *in, const char *out, int text); +static BIO *BIO_open_with_default(const char *file, const char *mode, + FILE *default_fp); +static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, + const char *policy, int no_nonce, int cert); +static int create_digest(BIO *input, char *digest, + const EVP_MD *md, unsigned char **md_value); +static ASN1_INTEGER *create_nonce(int bits); + +/* Reply related functions. */ +static int reply_command(CONF *conf, char *section, char *engine, + char *queryfile, char *passin, char *inkey, + char *signer, char *chain, const char *policy, + char *in, int token_in, char *out, int token_out, + int text); +static TS_RESP *read_PKCS7(BIO *in_bio); +static TS_RESP *create_response(CONF *conf, const char *section, char *engine, + char *queryfile, char *passin, char *inkey, + char *signer, char *chain, const char *policy); +static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data); +static ASN1_INTEGER *next_serial(const char *serialfile); +static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); + +/* Verify related functions. */ +static int verify_command(char *data, char *digest, char *queryfile, + char *in, int token_in, + char *ca_path, char *ca_file, char *untrusted); +static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, + char *queryfile, + char *ca_path, char *ca_file, + char *untrusted); +static X509_STORE *create_cert_store(char *ca_path, char *ca_file); +static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx); + +/* Main function definition. */ +int MAIN(int, char **); + +int MAIN(int argc, char **argv) + { + int ret = 1; + char *configfile = NULL; + char *section = NULL; + CONF *conf = NULL; + enum mode { + CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY + } mode = CMD_NONE; + char *data = NULL; + char *digest = NULL; + const EVP_MD *md = NULL; + char *rnd = NULL; + char *policy = NULL; + int no_nonce = 0; + int cert = 0; + char *in = NULL; + char *out = NULL; + int text = 0; + char *queryfile = NULL; + char *passin = NULL; /* Password source. */ + char *password =NULL; /* Password itself. */ + char *inkey = NULL; + char *signer = NULL; + char *chain = NULL; + char *ca_path = NULL; + char *ca_file = NULL; + char *untrusted = NULL; + char *engine = NULL; + /* Input is ContentInfo instead of TimeStampResp. */ + int token_in = 0; + /* Output is ContentInfo instead of TimeStampResp. */ + int token_out = 0; + int free_bio_err = 0; + + ERR_load_crypto_strings(); + apps_startup(); + + if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL) + { + free_bio_err = 1; + BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); + } + + if (!load_config(bio_err, NULL)) + goto cleanup; + + for (argc--, argv++; argc > 0; argc--, argv++) + { + if (strcmp(*argv, "-config") == 0) + { + if (argc-- < 1) goto usage; + configfile = *++argv; + } + else if (strcmp(*argv, "-section") == 0) + { + if (argc-- < 1) goto usage; + section = *++argv; + } + else if (strcmp(*argv, "-query") == 0) + { + if (mode != CMD_NONE) goto usage; + mode = CMD_QUERY; + } + else if (strcmp(*argv, "-data") == 0) + { + if (argc-- < 1) goto usage; + data = *++argv; + } + else if (strcmp(*argv, "-digest") == 0) + { + if (argc-- < 1) goto usage; + digest = *++argv; + } + else if (strcmp(*argv, "-rand") == 0) + { + if (argc-- < 1) goto usage; + rnd = *++argv; + } + else if (strcmp(*argv, "-policy") == 0) + { + if (argc-- < 1) goto usage; + policy = *++argv; + } + else if (strcmp(*argv, "-no_nonce") == 0) + { + no_nonce = 1; + } + else if (strcmp(*argv, "-cert") == 0) + { + cert = 1; + } + else if (strcmp(*argv, "-in") == 0) + { + if (argc-- < 1) goto usage; + in = *++argv; + } + else if (strcmp(*argv, "-token_in") == 0) + { + token_in = 1; + } + else if (strcmp(*argv, "-out") == 0) + { + if (argc-- < 1) goto usage; + out = *++argv; + } + else if (strcmp(*argv, "-token_out") == 0) + { + token_out = 1; + } + else if (strcmp(*argv, "-text") == 0) + { + text = 1; + } + else if (strcmp(*argv, "-reply") == 0) + { + if (mode != CMD_NONE) goto usage; + mode = CMD_REPLY; + } + else if (strcmp(*argv, "-queryfile") == 0) + { + if (argc-- < 1) goto usage; + queryfile = *++argv; + } + else if (strcmp(*argv, "-passin") == 0) + { + if (argc-- < 1) goto usage; + passin = *++argv; + } + else if (strcmp(*argv, "-inkey") == 0) + { + if (argc-- < 1) goto usage; + inkey = *++argv; + } + else if (strcmp(*argv, "-signer") == 0) + { + if (argc-- < 1) goto usage; + signer = *++argv; + } + else if (strcmp(*argv, "-chain") == 0) + { + if (argc-- < 1) goto usage; + chain = *++argv; + } + else if (strcmp(*argv, "-verify") == 0) + { + if (mode != CMD_NONE) goto usage; + mode = CMD_VERIFY; + } + else if (strcmp(*argv, "-CApath") == 0) + { + if (argc-- < 1) goto usage; + ca_path = *++argv; + } + else if (strcmp(*argv, "-CAfile") == 0) + { + if (argc-- < 1) goto usage; + ca_file = *++argv; + } + else if (strcmp(*argv, "-untrusted") == 0) + { + if (argc-- < 1) goto usage; + untrusted = *++argv; + } + else if (strcmp(*argv, "-engine") == 0) + { + if (argc-- < 1) goto usage; + engine = *++argv; + } + else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) + { + /* empty. */ + } + else + goto usage; + } + + /* Seed the random number generator if it is going to be used. */ + if (mode == CMD_QUERY && !no_nonce) + { + if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL) + BIO_printf(bio_err, "warning, not much extra random " + "data, consider using the -rand option\n"); + if (rnd != NULL) + BIO_printf(bio_err,"%ld semi-random bytes loaded\n", + app_RAND_load_files(rnd)); + } + + /* Get the password if required. */ + if(mode == CMD_REPLY && passin && + !app_passwd(bio_err, passin, NULL, &password, NULL)) + { + BIO_printf(bio_err,"Error getting password.\n"); + goto cleanup; + } + + /* Check consistency of parameters and execute + the appropriate function. */ + switch (mode) + { + case CMD_NONE: + goto usage; + case CMD_QUERY: + /* Data file and message imprint cannot be specified + at the same time. */ + ret = data != NULL && digest != NULL; + if (ret) goto usage; + /* Load the config file for possible policy OIDs. */ + conf = load_config_file(configfile); + ret = !query_command(data, digest, md, policy, no_nonce, cert, + in, out, text); + break; + case CMD_REPLY: + conf = load_config_file(configfile); + if (in == NULL) + { + ret = !(queryfile != NULL && conf != NULL && !token_in); + if (ret) goto usage; + } + else + { + /* 'in' and 'queryfile' are exclusive. */ + ret = !(queryfile == NULL); + if (ret) goto usage; + } + + ret = !reply_command(conf, section, engine, queryfile, + password, inkey, signer, chain, policy, + in, token_in, out, token_out, text); + break; + case CMD_VERIFY: + ret = !(((queryfile && !data && !digest) + || (!queryfile && data && !digest) + || (!queryfile && !data && digest)) + && in != NULL); + if (ret) goto usage; + + ret = !verify_command(data, digest, queryfile, in, token_in, + ca_path, ca_file, untrusted); + } + + goto cleanup; + + usage: + BIO_printf(bio_err, "usage:\n" + "ts -query [-rand file%cfile%c...] [-config configfile] " + "[-data file_to_hash] [-digest digest_bytes]" + "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] " + "[-policy object_id] [-no_nonce] [-cert] " + "[-in request.tsq] [-out request.tsq] [-text]\n", + LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); + BIO_printf(bio_err, "or\n" + "ts -reply [-config configfile] [-section tsa_section] " + "[-queryfile request.tsq] [-passin password] " + "[-signer tsa_cert.pem] [-inkey private_key.pem] " + "[-chain certs_file.pem] [-policy object_id] " + "[-in response.tsr] [-token_in] " + "[-out response.tsr] [-token_out] [-text] [-engine id]\n"); + BIO_printf(bio_err, "or\n" + "ts -verify [-data file_to_hash] [-digest digest_bytes] " + "[-queryfile request.tsq] " + "-in response.tsr [-token_in] " + "-CApath ca_path -CAfile ca_file.pem " + "-untrusted cert_file.pem\n"); + cleanup: + /* Clean up. */ + app_RAND_write_file(NULL, bio_err); + NCONF_free(conf); + OPENSSL_free(password); + OBJ_cleanup(); + if (free_bio_err) + { + BIO_free_all(bio_err); + bio_err = NULL; + } + + OPENSSL_EXIT(ret); + } + +/* + * Configuration file-related function definitions. + */ + +static ASN1_OBJECT *txt2obj(const char *oid) + { + ASN1_OBJECT *oid_obj = NULL; + + if (!(oid_obj = OBJ_txt2obj(oid, 0))) + BIO_printf(bio_err, "cannot convert %s to OID\n", oid); + + return oid_obj; + } + +static CONF *load_config_file(const char *configfile) + { + CONF *conf = NULL; + long errorline = -1; + + if (!configfile) configfile = getenv("OPENSSL_CONF"); + if (!configfile) configfile = getenv("SSLEAY_CONF"); + + if (configfile && + (!(conf = NCONF_new(NULL)) || + NCONF_load(conf, configfile, &errorline) <= 0)) + { + if (errorline <= 0) + BIO_printf(bio_err, "error loading the config file " + "'%s'\n", configfile); + else + BIO_printf(bio_err, "error on line %ld of config file " + "'%s'\n", errorline, configfile); + } + + if (conf != NULL) + { + const char *p; + + BIO_printf(bio_err,"Using configuration from %s\n", configfile); + p = NCONF_get_string(conf, NULL, ENV_OID_FILE); + if (p != NULL) + { + BIO *oid_bio = BIO_new_file(p, "r"); + if (!oid_bio) + ERR_print_errors(bio_err); + else + { + OBJ_create_objects(oid_bio); + BIO_free_all(oid_bio); + } + } + else + ERR_clear_error(); + if(!add_oid_section(bio_err, conf)) + ERR_print_errors(bio_err); + } + return conf; + } + +/* + * Query-related method definitions. + */ + +static int query_command(const char *data, char *digest, const EVP_MD *md, + const char *policy, int no_nonce, + int cert, const char *in, const char *out, int text) + { + int ret = 0; + TS_REQ *query = NULL; + BIO *in_bio = NULL; + BIO *data_bio = NULL; + BIO *out_bio = NULL; + + /* Build query object either from file or from scratch. */ + if (in != NULL) + { + if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; + query = d2i_TS_REQ_bio(in_bio, NULL); + } + else + { + /* Open the file if no explicit digest bytes were specified. */ + if (!digest + && !(data_bio = BIO_open_with_default(data, "rb", stdin))) + goto end; + /* Creating the query object. */ + query = create_query(data_bio, digest, md, + policy, no_nonce, cert); + /* Saving the random number generator state. */ + } + if (query == NULL) goto end; + + /* Write query either in ASN.1 or in text format. */ + if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) + goto end; + if (text) + { + /* Text output. */ + if (!TS_REQ_print_bio(out_bio, query)) + goto end; + } + else + { + /* ASN.1 output. */ + if (!i2d_TS_REQ_bio(out_bio, query)) + goto end; + } + + ret = 1; + + end: + ERR_print_errors(bio_err); + + /* Clean up. */ + BIO_free_all(in_bio); + BIO_free_all(data_bio); + BIO_free_all(out_bio); + TS_REQ_free(query); + + return ret; + } + +static BIO *BIO_open_with_default(const char *file, const char *mode, + FILE *default_fp) + { + return file == NULL ? + BIO_new_fp(default_fp, BIO_NOCLOSE) + : BIO_new_file(file, mode); + } + +static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, + const char *policy, int no_nonce, int cert) + { + int ret = 0; + TS_REQ *ts_req = NULL; + int len; + TS_MSG_IMPRINT *msg_imprint = NULL; + X509_ALGOR *algo = NULL; + unsigned char *data = NULL; + ASN1_OBJECT *policy_obj = NULL; + ASN1_INTEGER *nonce_asn1 = NULL; + + /* Setting default message digest. */ + if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err; + + /* Creating request object. */ + if (!(ts_req = TS_REQ_new())) goto err; + + /* Setting version. */ + if (!TS_REQ_set_version(ts_req, 1)) goto err; + + /* Creating and adding MSG_IMPRINT object. */ + if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err; + + /* Adding algorithm. */ + if (!(algo = X509_ALGOR_new())) goto err; + if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err; + if (!(algo->parameter = ASN1_TYPE_new())) goto err; + algo->parameter->type = V_ASN1_NULL; + if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err; + + /* Adding message digest. */ + if ((len = create_digest(data_bio, digest, md, &data)) == 0) + goto err; + if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err; + + if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err; + + /* Setting policy if requested. */ + if (policy && !(policy_obj = txt2obj(policy))) goto err; + if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err; + + /* Setting nonce if requested. */ + if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err; + if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err; + + /* Setting certificate request flag if requested. */ + if (!TS_REQ_set_cert_req(ts_req, cert)) goto err; + + ret = 1; + err: + if (!ret) + { + TS_REQ_free(ts_req); + ts_req = NULL; + BIO_printf(bio_err, "could not create query\n"); + } + TS_MSG_IMPRINT_free(msg_imprint); + X509_ALGOR_free(algo); + OPENSSL_free(data); + ASN1_OBJECT_free(policy_obj); + ASN1_INTEGER_free(nonce_asn1); + return ts_req; + } + +static int create_digest(BIO *input, char *digest, const EVP_MD *md, + unsigned char **md_value) + { + int md_value_len; + + md_value_len = EVP_MD_size(md); + if (md_value_len < 0) + goto err; + if (input) + { + /* Digest must be computed from an input file. */ + EVP_MD_CTX md_ctx; + unsigned char buffer[4096]; + int length; + + *md_value = OPENSSL_malloc(md_value_len); + if (*md_value == 0) goto err; + + EVP_DigestInit(&md_ctx, md); + while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) + { + EVP_DigestUpdate(&md_ctx, buffer, length); + } + EVP_DigestFinal(&md_ctx, *md_value, NULL); + } + else + { + /* Digest bytes are specified with digest. */ + long digest_len; + *md_value = string_to_hex(digest, &digest_len); + if (!*md_value || md_value_len != digest_len) + { + OPENSSL_free(*md_value); + *md_value = NULL; + BIO_printf(bio_err, "bad digest, %d bytes " + "must be specified\n", md_value_len); + goto err; + } + } + + return md_value_len; + err: + return 0; + } + +static ASN1_INTEGER *create_nonce(int bits) + { + unsigned char buf[20]; + ASN1_INTEGER *nonce = NULL; + int len = (bits - 1) / 8 + 1; + int i; + + /* Generating random byte sequence. */ + if (len > (int)sizeof(buf)) goto err; + if (RAND_bytes(buf, len) <= 0) goto err; + + /* Find the first non-zero byte and creating ASN1_INTEGER object. */ + for (i = 0; i < len && !buf[i]; ++i); + if (!(nonce = ASN1_INTEGER_new())) goto err; + OPENSSL_free(nonce->data); + /* Allocate at least one byte. */ + nonce->length = len - i; + if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err; + memcpy(nonce->data, buf + i, nonce->length); + + return nonce; + err: + BIO_printf(bio_err, "could not create nonce\n"); + ASN1_INTEGER_free(nonce); + return NULL; + } +/* + * Reply-related method definitions. + */ + +static int reply_command(CONF *conf, char *section, char *engine, + char *queryfile, char *passin, char *inkey, + char *signer, char *chain, const char *policy, + char *in, int token_in, + char *out, int token_out, int text) + { + int ret = 0; + TS_RESP *response = NULL; + BIO *in_bio = NULL; + BIO *query_bio = NULL; + BIO *inkey_bio = NULL; + BIO *signer_bio = NULL; + BIO *out_bio = NULL; + + /* Build response object either from response or query. */ + if (in != NULL) + { + if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; + if (token_in) + { + /* We have a ContentInfo (PKCS7) object, add + 'granted' status info around it. */ + response = read_PKCS7(in_bio); + } + else + { + /* We have a ready-made TS_RESP object. */ + response = d2i_TS_RESP_bio(in_bio, NULL); + } + } + else + { + response = create_response(conf, section, engine, queryfile, + passin, inkey, signer, chain, + policy); + if (response) + BIO_printf(bio_err, "Response has been generated.\n"); + else + BIO_printf(bio_err, "Response is not generated.\n"); + } + if (response == NULL) goto end; + + /* Write response either in ASN.1 or text format. */ + if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) + goto end; + if (text) + { + /* Text output. */ + if (token_out) + { + TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); + if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end; + } + else + { + if (!TS_RESP_print_bio(out_bio, response)) goto end; + } + } + else + { + /* ASN.1 DER output. */ + if (token_out) + { + PKCS7 *token = TS_RESP_get_token(response); + if (!i2d_PKCS7_bio(out_bio, token)) goto end; + } + else + { + if (!i2d_TS_RESP_bio(out_bio, response)) goto end; + } + } + + ret = 1; + + end: + ERR_print_errors(bio_err); + + /* Clean up. */ + BIO_free_all(in_bio); + BIO_free_all(query_bio); + BIO_free_all(inkey_bio); + BIO_free_all(signer_bio); + BIO_free_all(out_bio); + TS_RESP_free(response); + + return ret; + } + +/* Reads a PKCS7 token and adds default 'granted' status info to it. */ +static TS_RESP *read_PKCS7(BIO *in_bio) + { + int ret = 0; + PKCS7 *token = NULL; + TS_TST_INFO *tst_info = NULL; + TS_RESP *resp = NULL; + TS_STATUS_INFO *si = NULL; + + /* Read PKCS7 object and extract the signed time stamp info. */ + if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end; + if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end; + + /* Creating response object. */ + if (!(resp = TS_RESP_new())) goto end; + + /* Create granted status info. */ + if (!(si = TS_STATUS_INFO_new())) goto end; + if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end; + if (!TS_RESP_set_status_info(resp, si)) goto end; + + /* Setting encapsulated token. */ + TS_RESP_set_tst_info(resp, token, tst_info); + token = NULL; /* Ownership is lost. */ + tst_info = NULL; /* Ownership is lost. */ + + ret = 1; + end: + PKCS7_free(token); + TS_TST_INFO_free(tst_info); + if (!ret) + { + TS_RESP_free(resp); + resp = NULL; + } + TS_STATUS_INFO_free(si); + return resp; + } + +static TS_RESP *create_response(CONF *conf, const char *section, char *engine, + char *queryfile, char *passin, char *inkey, + char *signer, char *chain, const char *policy) + { + int ret = 0; + TS_RESP *response = NULL; + BIO *query_bio = NULL; + TS_RESP_CTX *resp_ctx = NULL; + + if (!(query_bio = BIO_new_file(queryfile, "rb"))) + goto end; + + /* Getting TSA configuration section. */ + if (!(section = TS_CONF_get_tsa_section(conf, section))) + goto end; + + /* Setting up response generation context. */ + if (!(resp_ctx = TS_RESP_CTX_new())) goto end; + + /* Setting serial number provider callback. */ + if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end; +#ifndef OPENSSL_NO_ENGINE + /* Setting default OpenSSL engine. */ + if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end; +#endif + + /* Setting TSA signer certificate. */ + if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end; + + /* Setting TSA signer certificate chain. */ + if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end; + + /* Setting TSA signer private key. */ + if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx)) + goto end; + + /* Setting default policy OID. */ + if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end; + + /* Setting acceptable policy OIDs. */ + if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end; + + /* Setting the acceptable one-way hash algorithms. */ + if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end; + + /* Setting guaranteed time stamp accuracy. */ + if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end; + + /* Setting the precision of the time. */ + if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx)) + goto end; + + /* Setting the ordering flaf if requested. */ + if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end; + + /* Setting the TSA name required flag if requested. */ + if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end; + + /* Setting the ESS cert id chain flag if requested. */ + if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end; + + /* Creating the response. */ + if (!(response = TS_RESP_create_response(resp_ctx, query_bio))) + goto end; + + ret = 1; + end: + if (!ret) + { + TS_RESP_free(response); + response = NULL; + } + TS_RESP_CTX_free(resp_ctx); + BIO_free_all(query_bio); + + return response; + } + +static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data) + { + const char *serial_file = (const char *) data; + ASN1_INTEGER *serial = next_serial(serial_file); + + if (!serial) + { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Error during serial number " + "generation."); + TS_RESP_CTX_add_failure_info(ctx, + TS_INFO_ADD_INFO_NOT_AVAILABLE); + } + else + save_ts_serial(serial_file, serial); + + return serial; + } + +static ASN1_INTEGER *next_serial(const char *serialfile) + { + int ret = 0; + BIO *in = NULL; + ASN1_INTEGER *serial = NULL; + BIGNUM *bn = NULL; + + if (!(serial = ASN1_INTEGER_new())) goto err; + + if (!(in = BIO_new_file(serialfile, "r"))) + { + ERR_clear_error(); + BIO_printf(bio_err, "Warning: could not open file %s for " + "reading, using serial number: 1\n", serialfile); + if (!ASN1_INTEGER_set(serial, 1)) goto err; + } + else + { + char buf[1024]; + if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) + { + BIO_printf(bio_err, "unable to load number from %s\n", + serialfile); + goto err; + } + if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err; + ASN1_INTEGER_free(serial); + serial = NULL; + if (!BN_add_word(bn, 1)) goto err; + if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err; + } + ret = 1; + err: + if (!ret) + { + ASN1_INTEGER_free(serial); + serial = NULL; + } + BIO_free_all(in); + BN_free(bn); + return serial; + } + +static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) + { + int ret = 0; + BIO *out = NULL; + + if (!(out = BIO_new_file(serialfile, "w"))) goto err; + if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err; + if (BIO_puts(out, "\n") <= 0) goto err; + ret = 1; + err: + if (!ret) + BIO_printf(bio_err, "could not save serial number to %s\n", + serialfile); + BIO_free_all(out); + return ret; + } + +/* + * Verify-related method definitions. + */ + +static int verify_command(char *data, char *digest, char *queryfile, + char *in, int token_in, + char *ca_path, char *ca_file, char *untrusted) + { + BIO *in_bio = NULL; + PKCS7 *token = NULL; + TS_RESP *response = NULL; + TS_VERIFY_CTX *verify_ctx = NULL; + int ret = 0; + + /* Decode the token (PKCS7) or response (TS_RESP) files. */ + if (!(in_bio = BIO_new_file(in, "rb"))) goto end; + if (token_in) + { + if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end; + } + else + { + if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end; + } + + if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, + ca_path, ca_file, untrusted))) + goto end; + + /* Checking the token or response against the request. */ + ret = token_in ? + TS_RESP_verify_token(verify_ctx, token) : + TS_RESP_verify_response(verify_ctx, response); + + end: + printf("Verification: "); + if (ret) + printf("OK\n"); + else + { + printf("FAILED\n"); + /* Print errors, if there are any. */ + ERR_print_errors(bio_err); + } + + /* Clean up. */ + BIO_free_all(in_bio); + PKCS7_free(token); + TS_RESP_free(response); + TS_VERIFY_CTX_free(verify_ctx); + return ret; + } + +static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, + char *queryfile, + char *ca_path, char *ca_file, + char *untrusted) + { + TS_VERIFY_CTX *ctx = NULL; + BIO *input = NULL; + TS_REQ *request = NULL; + int ret = 0; + + if (data != NULL || digest != NULL) + { + if (!(ctx = TS_VERIFY_CTX_new())) goto err; + ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER; + if (data != NULL) + { + ctx->flags |= TS_VFY_DATA; + if (!(ctx->data = BIO_new_file(data, "rb"))) goto err; + } + else if (digest != NULL) + { + long imprint_len; + ctx->flags |= TS_VFY_IMPRINT; + if (!(ctx->imprint = string_to_hex(digest, + &imprint_len))) + { + BIO_printf(bio_err, "invalid digest string\n"); + goto err; + } + ctx->imprint_len = imprint_len; + } + + } + else if (queryfile != NULL) + { + /* The request has just to be read, decoded and converted to + a verify context object. */ + if (!(input = BIO_new_file(queryfile, "rb"))) goto err; + if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err; + if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err; + } + else + return NULL; + + /* Add the signature verification flag and arguments. */ + ctx->flags |= TS_VFY_SIGNATURE; + + /* Initialising the X509_STORE object. */ + if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err; + + /* Loading untrusted certificates. */ + if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) + goto err; + + ret = 1; + err: + if (!ret) + { + TS_VERIFY_CTX_free(ctx); + ctx = NULL; + } + BIO_free_all(input); + TS_REQ_free(request); + return ctx; + } + +static X509_STORE *create_cert_store(char *ca_path, char *ca_file) + { + X509_STORE *cert_ctx = NULL; + X509_LOOKUP *lookup = NULL; + int i; + + /* Creating the X509_STORE object. */ + cert_ctx = X509_STORE_new(); + + /* Setting the callback for certificate chain verification. */ + X509_STORE_set_verify_cb(cert_ctx, verify_cb); + + /* Adding a trusted certificate directory source. */ + if (ca_path) + { + lookup = X509_STORE_add_lookup(cert_ctx, + X509_LOOKUP_hash_dir()); + if (lookup == NULL) + { + BIO_printf(bio_err, "memory allocation failure\n"); + goto err; + } + i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM); + if (!i) + { + BIO_printf(bio_err, "Error loading directory %s\n", + ca_path); + goto err; + } + } + + /* Adding a trusted certificate file source. */ + if (ca_file) + { + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); + if (lookup == NULL) + { + BIO_printf(bio_err, "memory allocation failure\n"); + goto err; + } + i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM); + if (!i) + { + BIO_printf(bio_err, "Error loading file %s\n", ca_file); + goto err; + } + } + + return cert_ctx; + err: + X509_STORE_free(cert_ctx); + return NULL; + } + +static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx) + { + /* + char buf[256]; + + if (!ok) + { + X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), + buf, sizeof(buf)); + printf("%s\n", buf); + printf("error %d at %d depth lookup: %s\n", + ctx->error, ctx->error_depth, + X509_verify_cert_error_string(ctx->error)); + } + */ + + return ok; + } diff --git a/crypto/openssl/apps/verify.c b/crypto/openssl/apps/verify.c index 20cc9e354c..9163997e93 100644 --- a/crypto/openssl/apps/verify.c +++ b/crypto/openssl/apps/verify.c @@ -70,8 +70,9 @@ #define PROG verify_main static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx); -static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e); -static STACK_OF(X509) *load_untrusted(char *file); +static int check(X509_STORE *ctx, char *file, + STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, + STACK_OF(X509_CRL) *crls, ENGINE *e); static int v_verbose=0, vflags = 0; int MAIN(int, char **); @@ -80,10 +81,10 @@ int MAIN(int argc, char **argv) { ENGINE *e = NULL; int i,ret=1, badarg = 0; - int purpose = -1; char *CApath=NULL,*CAfile=NULL; - char *untfile = NULL, *trustfile = NULL; + char *untfile = NULL, *trustfile = NULL, *crlfile = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL; + STACK_OF(X509_CRL) *crls = NULL; X509_STORE *cert_ctx=NULL; X509_LOOKUP *lookup=NULL; X509_VERIFY_PARAM *vpm = NULL; @@ -93,7 +94,7 @@ int MAIN(int argc, char **argv) cert_ctx=X509_STORE_new(); if (cert_ctx == NULL) goto end; - X509_STORE_set_verify_cb_func(cert_ctx,cb); + X509_STORE_set_verify_cb(cert_ctx,cb); ERR_load_crypto_strings(); @@ -139,6 +140,11 @@ int MAIN(int argc, char **argv) if (argc-- < 1) goto end; trustfile= *(++argv); } + else if (strcmp(*argv,"-CRLfile") == 0) + { + if (argc-- < 1) goto end; + crlfile= *(++argv); + } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { @@ -192,26 +198,34 @@ int MAIN(int argc, char **argv) ERR_clear_error(); - if(untfile) { - if(!(untrusted = load_untrusted(untfile))) { - BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile); - ERR_print_errors(bio_err); + if(untfile) + { + untrusted = load_certs(bio_err, untfile, FORMAT_PEM, + NULL, e, "untrusted certificates"); + if(!untrusted) goto end; } - } - if(trustfile) { - if(!(trusted = load_untrusted(trustfile))) { - BIO_printf(bio_err, "Error loading untrusted file %s\n", trustfile); - ERR_print_errors(bio_err); + if(trustfile) + { + trusted = load_certs(bio_err, trustfile, FORMAT_PEM, + NULL, e, "trusted certificates"); + if(!trusted) goto end; } - } - if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, purpose, e); + if(crlfile) + { + crls = load_crls(bio_err, crlfile, FORMAT_PEM, + NULL, e, "other CRLs"); + if(!crls) + goto end; + } + + if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e); else for (i=0; i= 0) X509_STORE_CTX_set_purpose(csc, purpose); + if (crls) + X509_STORE_CTX_set0_crls(csc, crls); i=X509_verify_cert(csc); X509_STORE_CTX_free(csc); @@ -278,90 +296,53 @@ end: return(ret); } -static STACK_OF(X509) *load_untrusted(char *certfile) -{ - STACK_OF(X509_INFO) *sk=NULL; - STACK_OF(X509) *stack=NULL, *ret=NULL; - BIO *in=NULL; - X509_INFO *xi; - - if(!(stack = sk_X509_new_null())) { - BIO_printf(bio_err,"memory allocation failure\n"); - goto end; - } - - if(!(in=BIO_new_file(certfile, "r"))) { - BIO_printf(bio_err,"error opening the file, %s\n",certfile); - goto end; - } - - /* This loads from a file, a stack of x509/crl/pkey sets */ - if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) { - BIO_printf(bio_err,"error reading the file, %s\n",certfile); - goto end; - } - - /* scan over it and pull out the certs */ - while (sk_X509_INFO_num(sk)) - { - xi=sk_X509_INFO_shift(sk); - if (xi->x509 != NULL) - { - sk_X509_push(stack,xi->x509); - xi->x509=NULL; - } - X509_INFO_free(xi); - } - if(!sk_X509_num(stack)) { - BIO_printf(bio_err,"no certificates in file, %s\n",certfile); - sk_X509_free(stack); - goto end; - } - ret=stack; -end: - BIO_free(in); - sk_X509_INFO_free(sk); - return(ret); - } - static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx) { - char buf[256]; + int cert_error = X509_STORE_CTX_get_error(ctx); + X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); if (!ok) { - if (ctx->current_cert) + if (current_cert) + { + X509_NAME_print_ex_fp(stdout, + X509_get_subject_name(current_cert), + 0, XN_FLAG_ONELINE); + printf("\n"); + } + printf("%serror %d at %d depth lookup:%s\n", + X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "", + cert_error, + X509_STORE_CTX_get_error_depth(ctx), + X509_verify_cert_error_string(cert_error)); + switch(cert_error) { - X509_NAME_oneline( - X509_get_subject_name(ctx->current_cert),buf, - sizeof buf); - printf("%s\n",buf); + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(NULL, ctx); + case X509_V_ERR_CERT_HAS_EXPIRED: + + /* since we are just checking the certificates, it is + * ok if they are self signed. But we should still warn + * the user. + */ + + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + /* Continue after extension errors too */ + case X509_V_ERR_INVALID_CA: + case X509_V_ERR_INVALID_NON_CA: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_PURPOSE: + case X509_V_ERR_CRL_HAS_EXPIRED: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + ok = 1; + } - printf("error %d at %d depth lookup:%s\n",ctx->error, - ctx->error_depth, - X509_verify_cert_error_string(ctx->error)); - if (ctx->error == X509_V_ERR_CERT_HAS_EXPIRED) ok=1; - /* since we are just checking the certificates, it is - * ok if they are self signed. But we should still warn - * the user. - */ - if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1; - /* Continue after extension errors too */ - if (ctx->error == X509_V_ERR_INVALID_CA) ok=1; - if (ctx->error == X509_V_ERR_INVALID_NON_CA) ok=1; - if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1; - if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1; - if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1; - if (ctx->error == X509_V_ERR_CRL_HAS_EXPIRED) ok=1; - if (ctx->error == X509_V_ERR_CRL_NOT_YET_VALID) ok=1; - if (ctx->error == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) ok=1; - if (ctx->error == X509_V_ERR_NO_EXPLICIT_POLICY) - policies_print(NULL, ctx); return ok; } - if ((ctx->error == X509_V_OK) && (ok == 2)) + if (cert_error == X509_V_OK && ok == 2) policies_print(NULL, ctx); if (!v_verbose) ERR_clear_error(); diff --git a/crypto/openssl/apps/x509.c b/crypto/openssl/apps/x509.c index b25508aa8e..e7e46d7b63 100644 --- a/crypto/openssl/apps/x509.c +++ b/crypto/openssl/apps/x509.c @@ -99,7 +99,13 @@ static const char *x509_usage[]={ " -passin arg - private key password source\n", " -serial - print serial number value\n", " -subject_hash - print subject hash value\n", +#ifndef OPENSSL_NO_MD5 +" -subject_hash_old - print old-style (MD5) subject hash value\n", +#endif " -issuer_hash - print issuer hash value\n", +#ifndef OPENSSL_NO_MD5 +" -issuer_hash_old - print old-style (MD5) issuer hash value\n", +#endif " -hash - synonym for -subject_hash\n", " -subject - print subject DN\n", " -issuer - print issuer DN\n", @@ -179,6 +185,9 @@ int MAIN(int argc, char **argv) int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0; int next_serial=0; int subject_hash=0,issuer_hash=0,ocspid=0; +#ifndef OPENSSL_NO_MD5 + int subject_hash_old=0,issuer_hash_old=0; +#endif int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; int ocsp_uri=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; @@ -190,7 +199,7 @@ int MAIN(int argc, char **argv) X509_REQ *rq=NULL; int fingerprint=0; char buf[256]; - const EVP_MD *md_alg,*digest=EVP_sha1(); + const EVP_MD *md_alg,*digest=NULL; CONF *extconf = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; int need_rand = 0; @@ -225,7 +234,7 @@ int MAIN(int argc, char **argv) ctx=X509_STORE_new(); if (ctx == NULL) goto end; - X509_STORE_set_verify_cb_func(ctx,callb); + X509_STORE_set_verify_cb(ctx,callb); argc--; argv++; @@ -397,8 +406,16 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"-hash") == 0 || strcmp(*argv,"-subject_hash") == 0) subject_hash= ++num; +#ifndef OPENSSL_NO_MD5 + else if (strcmp(*argv,"-subject_hash_old") == 0) + subject_hash_old= ++num; +#endif else if (strcmp(*argv,"-issuer_hash") == 0) issuer_hash= ++num; +#ifndef OPENSSL_NO_MD5 + else if (strcmp(*argv,"-issuer_hash_old") == 0) + issuer_hash_old= ++num; +#endif else if (strcmp(*argv,"-subject") == 0) subject= ++num; else if (strcmp(*argv,"-issuer") == 0) @@ -626,7 +643,7 @@ bad: if (!X509_set_subject_name(x,req->req_info->subject)) goto end; X509_gmtime_adj(X509_get_notBefore(x),0); - X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); + X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL); pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x,pkey); @@ -738,13 +755,14 @@ bad: else if ((email == i) || (ocsp_uri == i)) { int j; - STACK *emlst; + STACK_OF(OPENSSL_STRING) *emlst; if (email == i) emlst = X509_get1_email(x); else emlst = X509_get1_ocsp(x); - for (j = 0; j < sk_num(emlst); j++) - BIO_printf(STDout, "%s\n", sk_value(emlst, j)); + for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) + BIO_printf(STDout, "%s\n", + sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) @@ -758,10 +776,22 @@ bad: { BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x)); } +#ifndef OPENSSL_NO_MD5 + else if (subject_hash_old == i) + { + BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x)); + } +#endif else if (issuer_hash == i) { BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x)); } +#ifndef OPENSSL_NO_MD5 + else if (issuer_hash_old == i) + { + BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x)); + } +#endif else if (pprint == i) { X509_PURPOSE *ptmp; @@ -892,14 +922,18 @@ bad: int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; + const EVP_MD *fdig = digest; + + if (!fdig) + fdig = EVP_sha1(); - if (!X509_digest(x,digest,md,&n)) + if (!X509_digest(x,fdig,md,&n)) { BIO_printf(bio_err,"out of memory\n"); goto end; } BIO_printf(STDout,"%s Fingerprint=", - OBJ_nid2sn(EVP_MD_type(digest))); + OBJ_nid2sn(EVP_MD_type(fdig))); for (j=0; j<(int)n; j++) { BIO_printf(STDout,"%02X%c",md[j], @@ -919,14 +953,6 @@ bad: passin, e, "Private key"); if (Upkey == NULL) goto end; } -#ifndef OPENSSL_NO_DSA - if (Upkey->type == EVP_PKEY_DSA) - digest=EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (Upkey->type == EVP_PKEY_EC) - digest=EVP_ecdsa(); -#endif assert(need_rand); if (!sign(x,Upkey,days,clrext,digest, @@ -943,14 +969,6 @@ bad: "CA Private Key"); if (CApkey == NULL) goto end; } -#ifndef OPENSSL_NO_DSA - if (CApkey->type == EVP_PKEY_DSA) - digest=EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (CApkey->type == EVP_PKEY_EC) - digest = EVP_ecdsa(); -#endif assert(need_rand); if (!x509_certify(ctx,CAfile,digest,x,xca, @@ -978,15 +996,6 @@ bad: BIO_printf(bio_err,"Generating certificate request\n"); -#ifndef OPENSSL_NO_DSA - if (pk->type == EVP_PKEY_DSA) - digest=EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pk->type == EVP_PKEY_EC) - digest=EVP_ecdsa(); -#endif - rq=X509_to_X509_REQ(x,pk,digest); EVP_PKEY_free(pk); if (rq == NULL) @@ -1040,16 +1049,15 @@ bad: } else if (outformat == FORMAT_NETSCAPE) { - ASN1_HEADER ah; - ASN1_OCTET_STRING os; + NETSCAPE_X509 nx; + ASN1_OCTET_STRING hdr; - os.data=(unsigned char *)NETSCAPE_CERT_HDR; - os.length=strlen(NETSCAPE_CERT_HDR); - ah.header= &os; - ah.data=(char *)x; - ah.meth=X509_asn1_meth(); + hdr.data=(unsigned char *)NETSCAPE_CERT_HDR; + hdr.length=strlen(NETSCAPE_CERT_HDR); + nx.header= &hdr; + nx.cert=x; - i=ASN1_i2d_bio_of(ASN1_HEADER,i2d_ASN1_HEADER,out,&ah); + i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); @@ -1168,7 +1176,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, goto end; /* hardwired expired */ - if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL) + if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL) goto end; if (clrext) diff --git a/crypto/openssl/crypto/aes/aes.h b/crypto/openssl/crypto/aes/aes.h index 450f2b4051..d2c99730fe 100644 --- a/crypto/openssl/crypto/aes/aes.h +++ b/crypto/openssl/crypto/aes/aes.h @@ -58,6 +58,8 @@ #error AES is disabled. #endif +#include + #define AES_ENCRYPT 1 #define AES_DECRYPT 0 @@ -66,10 +68,6 @@ #define AES_MAXNR 14 #define AES_BLOCK_SIZE 16 -#ifdef OPENSSL_FIPS -#define FIPS_AES_SIZE_T int -#endif - #ifdef __cplusplus extern "C" { #endif @@ -100,37 +98,32 @@ void AES_decrypt(const unsigned char *in, unsigned char *out, void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc); void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc); void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc); void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc); -void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, - const int nbits,const AES_KEY *key, - unsigned char *ivec,const int enc); void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num); void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); - -/* For IGE, see also http://www.links.org/files/openssl-ige.pdf */ /* NB: the IV is _two_ blocks long */ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); /* NB: the IV is _four_ blocks long */ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, const AES_KEY *key2, const unsigned char *ivec, const int enc); @@ -141,6 +134,7 @@ int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, unsigned int inlen); + #ifdef __cplusplus } #endif diff --git a/crypto/openssl/crypto/aes/aes_cbc.c b/crypto/openssl/crypto/aes/aes_cbc.c index 373864cd4b..227f75625d 100644 --- a/crypto/openssl/crypto/aes/aes_cbc.c +++ b/crypto/openssl/crypto/aes/aes_cbc.c @@ -49,85 +49,15 @@ * */ -#ifndef AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - #include -#include "aes_locl.h" +#include -#if !defined(OPENSSL_FIPS_AES_ASM) void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t len, const AES_KEY *key, unsigned char *ivec, const int enc) { - unsigned long n; - unsigned long len = length; - unsigned char tmp[AES_BLOCK_SIZE]; - const unsigned char *iv = ivec; - - assert(in && out && key && ivec); - assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); - - if (AES_ENCRYPT == enc) { - while (len >= AES_BLOCK_SIZE) { - for(n=0; n < AES_BLOCK_SIZE; ++n) - out[n] = in[n] ^ iv[n]; - AES_encrypt(out, out, key); - iv = out; - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - for(n=0; n < len; ++n) - out[n] = in[n] ^ iv[n]; - for(n=len; n < AES_BLOCK_SIZE; ++n) - out[n] = iv[n]; - AES_encrypt(out, out, key); - iv = out; - } - memcpy(ivec,iv,AES_BLOCK_SIZE); - } else if (in != out) { - while (len >= AES_BLOCK_SIZE) { - AES_decrypt(in, out, key); - for(n=0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= iv[n]; - iv = in; - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - AES_decrypt(in,tmp,key); - for(n=0; n < len; ++n) - out[n] = tmp[n] ^ iv[n]; - iv = in; - } - memcpy(ivec,iv,AES_BLOCK_SIZE); - } else { - while (len >= AES_BLOCK_SIZE) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(in, out, key); - for(n=0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= ivec[n]; - memcpy(ivec, tmp, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(tmp, out, key); - for(n=0; n < len; ++n) - out[n] ^= ivec[n]; - for(n=len; n < AES_BLOCK_SIZE; ++n) - out[n] = tmp[n]; - memcpy(ivec, tmp, AES_BLOCK_SIZE); - } - } + if (enc) + CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt); + else + CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt); } -#endif diff --git a/crypto/openssl/crypto/aes/aes_cfb.c b/crypto/openssl/crypto/aes/aes_cfb.c index 9384ba67f7..0c6d058ce7 100644 --- a/crypto/openssl/crypto/aes/aes_cfb.c +++ b/crypto/openssl/crypto/aes/aes_cfb.c @@ -1,6 +1,6 @@ /* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 2002-2006 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 @@ -48,73 +48,9 @@ * ==================================================================== * */ -/* 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 AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include #include -#include "aes_locl.h" -#include "e_os.h" +#include /* The input and output encrypted as though 128bit cfb mode is being * used. The extra state information to record how much of the @@ -122,103 +58,24 @@ */ void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc) { - unsigned int n; - unsigned long l = length; - unsigned char c; - - assert(in && out && key && ivec && num); - - n = *num; - - if (enc) { - while (l--) { - if (n == 0) { - AES_encrypt(ivec, ivec, key); - } - ivec[n] = *(out++) = *(in++) ^ ivec[n]; - n = (n+1) % AES_BLOCK_SIZE; - } - } else { - while (l--) { - if (n == 0) { - AES_encrypt(ivec, ivec, key); - } - c = *(in); - *(out++) = *(in++) ^ ivec[n]; - ivec[n] = c; - n = (n+1) % AES_BLOCK_SIZE; - } - } - - *num=n; + CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt); } -/* This expects a single block of size nbits for both in and out. Note that - it corrupts any extra bits in the last byte of out */ -void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, - const int nbits,const AES_KEY *key, - unsigned char *ivec,const int enc) - { - int n,rem,num; - unsigned char ovec[AES_BLOCK_SIZE*2]; - - if (nbits<=0 || nbits>128) return; - - /* fill in the first half of the new IV with the current IV */ - memcpy(ovec,ivec,AES_BLOCK_SIZE); - /* construct the new IV */ - AES_encrypt(ivec,ivec,key); - num = (nbits+7)/8; - if (enc) /* encrypt the input */ - for(n=0 ; n < num ; ++n) - out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n] ^ ivec[n]); - else /* decrypt the input */ - for(n=0 ; n < num ; ++n) - out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n]) ^ ivec[n]; - /* shift ovec left... */ - rem = nbits%8; - num = nbits/8; - if(rem==0) - memcpy(ivec,ovec+num,AES_BLOCK_SIZE); - else - for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - ivec[n] = ovec[n+num]<>(8-rem); - - /* it is not necessary to cleanse ovec, since the IV is not secret */ - } - /* N.B. This expects the input to be packed, MS bit first */ void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc) { - unsigned int n; - unsigned char c[1],d[1]; - - assert(in && out && key && ivec && num); - assert(*num == 0); - - for(n=0 ; n < length ; ++n) - { - c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; - AES_cfbr_encrypt_block(c,d,1,key,ivec,enc); - out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8)); - } + CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt); } void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc) { - unsigned int n; - - assert(in && out && key && ivec && num); - assert(*num == 0); - - for(n=0 ; n < length ; ++n) - AES_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc); + CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt); } diff --git a/crypto/openssl/crypto/aes/aes_core.c b/crypto/openssl/crypto/aes/aes_core.c index cffdd4daec..a7ec54f4da 100644 --- a/crypto/openssl/crypto/aes/aes_core.c +++ b/crypto/openssl/crypto/aes/aes_core.c @@ -37,12 +37,9 @@ #include #include -#ifdef OPENSSL_FIPS -#include -#endif - #include "aes_locl.h" +#ifndef AES_ASM /* Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; @@ -635,10 +632,6 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, int i = 0; u32 temp; -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif - if (!userKey || !key) return -1; if (bits != 128 && bits != 192 && bits != 256) @@ -781,7 +774,6 @@ int AES_set_decrypt_key(const unsigned char *userKey, const int bits, return 0; } -#ifndef AES_ASM /* * Encrypt a single block * in and out can overlap @@ -1164,4 +1156,203 @@ void AES_decrypt(const unsigned char *in, unsigned char *out, PUTU32(out + 12, s3); } +#else /* AES_ASM */ + +static const u8 Te4[256] = { + 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, + 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, + 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, + 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, + 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, + 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, + 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, + 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, + 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, + 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, + 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, + 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, + 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, + 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, + 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, + 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, + 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, + 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, + 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, + 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, + 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, + 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, + 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, + 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, + 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, + 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, + 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, + 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, + 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, + 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, + 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, + 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + */ +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) { + u32 *rk; + int i = 0; + u32 temp; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = key->rd_key; + + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; + + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] << 24) ^ + (Te4[(temp >> 8) & 0xff] << 16) ^ + (Te4[(temp ) & 0xff] << 8) ^ + (Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] << 24) ^ + (Te4[(temp >> 8) & 0xff] << 16) ^ + (Te4[(temp ) & 0xff] << 8) ^ + (Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] << 24) ^ + (Te4[(temp >> 8) & 0xff] << 16) ^ + (Te4[(temp ) & 0xff] << 8) ^ + (Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4[(temp >> 24) ] << 24) ^ + (Te4[(temp >> 16) & 0xff] << 16) ^ + (Te4[(temp >> 8) & 0xff] << 8) ^ + (Te4[(temp ) & 0xff]); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) { + + u32 *rk; + int i, j, status; + u32 temp; + + /* first, start with an encryption schedule */ + status = AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; + + rk = key->rd_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; + for (j = 0; j < 4; j++) { + u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; + + tp1 = rk[j]; + m = tp1 & 0x80808080; + tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp2 & 0x80808080; + tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp4 & 0x80808080; + tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + tp9 = tp8 ^ tp1; + tpb = tp9 ^ tp2; + tpd = tp9 ^ tp4; + tpe = tp8 ^ tp4 ^ tp2; +#if defined(ROTATE) + rk[j] = tpe ^ ROTATE(tpd,16) ^ + ROTATE(tp9,24) ^ ROTATE(tpb,8); +#else + rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ + (tp9 >> 8) ^ (tp9 << 24) ^ + (tpb >> 24) ^ (tpb << 8); +#endif + } + } + return 0; +} + #endif /* AES_ASM */ diff --git a/crypto/openssl/crypto/aes/aes_ctr.c b/crypto/openssl/crypto/aes/aes_ctr.c index f36982be1e..7c9d165d8a 100644 --- a/crypto/openssl/crypto/aes/aes_ctr.c +++ b/crypto/openssl/crypto/aes/aes_ctr.c @@ -49,91 +49,13 @@ * */ -#ifndef AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - #include -#include "aes_locl.h" - -/* NOTE: the IV/counter CTR mode is big-endian. The rest of the AES code - * is endian-neutral. */ - -/* increment counter (128-bit int) by 1 */ -static void AES_ctr128_inc(unsigned char *counter) { - unsigned long c; - - /* Grab bottom dword of counter and increment */ - c = GETU32(counter + 12); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 12, c); - - /* if no overflow, we're done */ - if (c) - return; - - /* Grab 1st dword of counter and increment */ - c = GETU32(counter + 8); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 8, c); - - /* if no overflow, we're done */ - if (c) - return; - - /* Grab 2nd dword of counter and increment */ - c = GETU32(counter + 4); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 4, c); - - /* if no overflow, we're done */ - if (c) - return; +#include - /* Grab top dword of counter and increment */ - c = GETU32(counter + 0); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 0, c); -} - -/* The input encrypted as though 128bit counter mode is being - * used. The extra state information to record how much of the - * 128bit block we have used is contained in *num, and the - * encrypted counter is kept in ecount_buf. Both *num and - * ecount_buf must be initialised with zeros before the first - * call to AES_ctr128_encrypt(). - * - * This algorithm assumes that the counter is in the x lower bits - * of the IV (ivec), and that the application has full control over - * overflow and the rest of the IV. This implementation takes NO - * responsability for checking that the counter doesn't overflow - * into the rest of the IV when incremented. - */ void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, - unsigned char ivec[AES_BLOCK_SIZE], - unsigned char ecount_buf[AES_BLOCK_SIZE], - unsigned int *num) { - - unsigned int n; - unsigned long l=length; - - assert(in && out && key && counter && num); - assert(*num < AES_BLOCK_SIZE); - - n = *num; - - while (l--) { - if (n == 0) { - AES_encrypt(ivec, ecount_buf, key); - AES_ctr128_inc(ivec); - } - *(out++) = *(in++) ^ ecount_buf[n]; - n = (n+1) % AES_BLOCK_SIZE; - } - - *num=n; + size_t length, const AES_KEY *key, + unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num) { + CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)AES_encrypt); } diff --git a/crypto/openssl/crypto/aes/aes_ige.c b/crypto/openssl/crypto/aes/aes_ige.c index 45d7096181..c161351e65 100644 --- a/crypto/openssl/crypto/aes/aes_ige.c +++ b/crypto/openssl/crypto/aes/aes_ige.c @@ -77,11 +77,11 @@ typedef struct { /* N.B. The IV for this mode is _twice_ the block size */ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc) { - unsigned long n; - unsigned long len; + size_t n; + size_t len = length; OPENSSL_assert(in && out && key && ivec); OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); @@ -211,12 +211,12 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, /* N.B. The IV for this mode is _four times_ the block size */ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, + size_t length, const AES_KEY *key, const AES_KEY *key2, const unsigned char *ivec, const int enc) { - unsigned long n; - unsigned long len = length; + size_t n; + size_t len = length; unsigned char tmp[AES_BLOCK_SIZE]; unsigned char tmp2[AES_BLOCK_SIZE]; unsigned char tmp3[AES_BLOCK_SIZE]; diff --git a/crypto/openssl/crypto/aes/aes_ofb.c b/crypto/openssl/crypto/aes/aes_ofb.c index f358bb39e2..50bf0b8325 100644 --- a/crypto/openssl/crypto/aes/aes_ofb.c +++ b/crypto/openssl/crypto/aes/aes_ofb.c @@ -1,6 +1,6 @@ /* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 2002-2006 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 @@ -48,95 +48,13 @@ * ==================================================================== * */ -/* 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 AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include #include -#include "aes_locl.h" +#include -/* The input and output encrypted as though 128bit ofb mode is being - * used. The extra state information to record how much of the - * 128bit block we have used is contained in *num; - */ void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, - unsigned char *ivec, int *num) { - - unsigned int n; - unsigned long l=length; - - assert(in && out && key && ivec && num); - - n = *num; - - while (l--) { - if (n == 0) { - AES_encrypt(ivec, ivec, key); - } - *(out++) = *(in++) ^ ivec[n]; - n = (n+1) % AES_BLOCK_SIZE; - } - - *num=n; + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)AES_encrypt); } diff --git a/crypto/openssl/crypto/asn1/a_bitstr.c b/crypto/openssl/crypto/asn1/a_bitstr.c index 0fb9ce0c2a..34179960b8 100644 --- a/crypto/openssl/crypto/asn1/a_bitstr.c +++ b/crypto/openssl/crypto/asn1/a_bitstr.c @@ -223,3 +223,26 @@ int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n) return((a->data[w]&v) != 0); } +/* + * Checks if the given bit string contains only bits specified by + * the flags vector. Returns 0 if there is at least one bit set in 'a' + * which is not specified in 'flags', 1 otherwise. + * 'len' is the length of 'flags'. + */ +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len) + { + int i, ok; + /* Check if there is one bit set at all. */ + if (!a || !a->data) return 1; + + /* Check each byte of the internal representation of the bit string. */ + ok = 1; + for (i = 0; i < a->length && ok; ++i) + { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + /* We are done if there is an unneeded bit set. */ + ok = (a->data[i] & mask) == 0; + } + return ok; + } diff --git a/crypto/openssl/crypto/asn1/a_dup.c b/crypto/openssl/crypto/asn1/a_dup.c index 199d50f521..d98992548a 100644 --- a/crypto/openssl/crypto/asn1/a_dup.c +++ b/crypto/openssl/crypto/asn1/a_dup.c @@ -62,7 +62,7 @@ #ifndef NO_OLD_ASN1 -void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x) +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) { unsigned char *b,*p; const unsigned char *p2; diff --git a/crypto/openssl/crypto/asn1/a_gentm.c b/crypto/openssl/crypto/asn1/a_gentm.c index def79062a5..c79c6f538c 100644 --- a/crypto/openssl/crypto/asn1/a_gentm.c +++ b/crypto/openssl/crypto/asn1/a_gentm.c @@ -117,8 +117,8 @@ err: int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) { - static int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0}; - static int max[9]={99, 99,12,31,23,59,59,12,59}; + static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0}; + static const int max[9]={99, 99,12,31,23,59,59,12,59}; char *a; int n,i,l,o; @@ -176,6 +176,11 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) o++; } } + else + { + /* Missing time zone information. */ + goto err; + } return(o == l); err: return(0); @@ -205,6 +210,12 @@ int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t) + { + return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); + } + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, long offset_sec) { char *p; struct tm *ts; @@ -220,13 +231,19 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, if (ts == NULL) return(NULL); + if (offset_day || offset_sec) + { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + p=(char *)s->data; if ((p == NULL) || ((size_t)s->length < len)) { p=OPENSSL_malloc(len); if (p == NULL) { - ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_SET, + ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); return(NULL); } diff --git a/crypto/openssl/crypto/asn1/a_hdr.c b/crypto/openssl/crypto/asn1/a_hdr.c deleted file mode 100644 index d1c2a7b9e3..0000000000 --- a/crypto/openssl/crypto/asn1/a_hdr.c +++ /dev/null @@ -1,119 +0,0 @@ -/* crypto/asn1/a_hdr.c */ -/* 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 -#include "cryptlib.h" -#include -#include - -int i2d_ASN1_HEADER(ASN1_HEADER *a, unsigned char **pp) - { - M_ASN1_I2D_vars(a); - - M_ASN1_I2D_len(a->header, i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_len(a->data, a->meth->i2d); - - M_ASN1_I2D_seq_total(); - - M_ASN1_I2D_put(a->header, i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_put(a->data, a->meth->i2d); - - M_ASN1_I2D_finish(); - } - -ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a, const unsigned char **pp, - long length) - { - M_ASN1_D2I_vars(a,ASN1_HEADER *,ASN1_HEADER_new); - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->header,d2i_ASN1_OCTET_STRING); - if (ret->meth != NULL) - { - M_ASN1_D2I_get_x(void,ret->data,ret->meth->d2i); - } - else - { - if (a != NULL) (*a)=ret; - return(ret); - } - M_ASN1_D2I_Finish(a,ASN1_HEADER_free,ASN1_F_D2I_ASN1_HEADER); - } - -ASN1_HEADER *ASN1_HEADER_new(void) - { - ASN1_HEADER *ret=NULL; - ASN1_CTX c; - - M_ASN1_New_Malloc(ret,ASN1_HEADER); - M_ASN1_New(ret->header,M_ASN1_OCTET_STRING_new); - ret->meth=NULL; - ret->data=NULL; - return(ret); - M_ASN1_New_Error(ASN1_F_ASN1_HEADER_NEW); - } - -void ASN1_HEADER_free(ASN1_HEADER *a) - { - if (a == NULL) return; - M_ASN1_OCTET_STRING_free(a->header); - if (a->meth != NULL) - a->meth->destroy(a->data); - OPENSSL_free(a); - } diff --git a/crypto/openssl/crypto/asn1/a_int.c b/crypto/openssl/crypto/asn1/a_int.c index f8d198efb1..c6fd204ae3 100644 --- a/crypto/openssl/crypto/asn1/a_int.c +++ b/crypto/openssl/crypto/asn1/a_int.c @@ -61,10 +61,10 @@ #include #include -ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) { return M_ASN1_INTEGER_dup(x);} -int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) { int neg, ret; /* Compare signs */ @@ -373,7 +373,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) return(1); } -long ASN1_INTEGER_get(ASN1_INTEGER *a) +long ASN1_INTEGER_get(const ASN1_INTEGER *a) { int neg=0,i; long r=0; @@ -402,7 +402,7 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a) return(r); } -ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai) +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) { ASN1_INTEGER *ret; int len,j; @@ -444,7 +444,7 @@ err: return(NULL); } -BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn) +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) { BIGNUM *ret; diff --git a/crypto/openssl/crypto/asn1/a_meth.c b/crypto/openssl/crypto/asn1/a_meth.c deleted file mode 100644 index 50bea917e3..0000000000 --- a/crypto/openssl/crypto/asn1/a_meth.c +++ /dev/null @@ -1,84 +0,0 @@ -/* crypto/asn1/a_meth.c */ -/* 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 -#include "cryptlib.h" -#include -#include - -static ASN1_METHOD ia5string_meth={ - (I2D_OF(void)) i2d_ASN1_IA5STRING, - (D2I_OF(void)) d2i_ASN1_IA5STRING, - (void *(*)(void))ASN1_STRING_new, - (void (*)(void *))ASN1_STRING_free}; - -static ASN1_METHOD bit_string_meth={ - (I2D_OF(void)) i2d_ASN1_BIT_STRING, - (D2I_OF(void)) d2i_ASN1_BIT_STRING, - (void *(*)(void))ASN1_STRING_new, - (void (*)(void *))ASN1_STRING_free}; - -ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void) - { - return(&ia5string_meth); - } - -ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void) - { - return(&bit_string_meth); - } diff --git a/crypto/openssl/crypto/asn1/a_object.c b/crypto/openssl/crypto/asn1/a_object.c index d169f8c147..e5fbe7cbb1 100644 --- a/crypto/openssl/crypto/asn1/a_object.c +++ b/crypto/openssl/crypto/asn1/a_object.c @@ -281,8 +281,6 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, return ret; err: ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_OBJECT_free(ret); return(NULL); } ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, @@ -290,13 +288,14 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, { ASN1_OBJECT *ret=NULL; const unsigned char *p; + unsigned char *data; int i; - /* Sanity check OID encoding: can't have 0x80 in subidentifiers, see: - * X.690 8.19.2 + /* Sanity check OID encoding: can't have leading 0x80 in + * subidentifiers, see: X.690 8.19.2 */ for (i = 0, p = *pp + 1; i < len - 1; i++, p++) { - if (*p == 0x80) + if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING); return NULL; @@ -313,15 +312,22 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, else ret=(*a); p= *pp; - if ((ret->data == NULL) || (ret->length < len)) + /* detach data from object */ + data = (unsigned char *)ret->data; + ret->data = NULL; + /* once detached we can change it */ + if ((data == NULL) || (ret->length < len)) { - if (ret->data != NULL) OPENSSL_free(ret->data); - ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); - ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; - if (ret->data == NULL) + ret->length=0; + if (data != NULL) OPENSSL_free(data); + data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); + if (data == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } + ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; } - memcpy(ret->data,p,(int)len); + memcpy(data,p,(int)len); + /* reattach data to object, after which it remains const */ + ret->data =data; ret->length=(int)len; ret->sn=NULL; ret->ln=NULL; @@ -370,7 +376,7 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a) } if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { - if (a->data != NULL) OPENSSL_free(a->data); + if (a->data != NULL) OPENSSL_free((void *)a->data); a->data=NULL; a->length=0; } diff --git a/crypto/openssl/crypto/asn1/a_octet.c b/crypto/openssl/crypto/asn1/a_octet.c index 24fd0f8e5a..e8725e44f1 100644 --- a/crypto/openssl/crypto/asn1/a_octet.c +++ b/crypto/openssl/crypto/asn1/a_octet.c @@ -60,10 +60,10 @@ #include "cryptlib.h" #include -ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *x) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) { return M_ASN1_OCTET_STRING_dup(x); } -int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b) +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b) { return M_ASN1_OCTET_STRING_cmp(a, b); } int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len) diff --git a/crypto/openssl/crypto/asn1/a_set.c b/crypto/openssl/crypto/asn1/a_set.c index 958558c204..d726c8d3a8 100644 --- a/crypto/openssl/crypto/asn1/a_set.c +++ b/crypto/openssl/crypto/asn1/a_set.c @@ -85,8 +85,9 @@ static int SetBlobCmp(const void *elem1, const void *elem2 ) } /* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */ -int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, - int ex_class, int is_set) +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, + int is_set) { int ret=0,r; int i; @@ -96,8 +97,8 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, int totSize; if (a == NULL) return(0); - for (i=sk_num(a)-1; i>=0; i--) - ret+=i2d(sk_value(a,i),NULL); + for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--) + ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL); r=ASN1_object_size(1,ret,ex_tag); if (pp == NULL) return(r); @@ -108,10 +109,10 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, /* And then again by Ben */ /* And again by Steve */ - if(!is_set || (sk_num(a) < 2)) + if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) { - for (i=0; i #include #include +#include "asn1_locl.h" #ifndef NO_ASN1_OLD @@ -218,45 +219,47 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, { EVP_MD_CTX ctx; unsigned char *buf_in=NULL,*buf_out=NULL; - int i,inl=0,outl=0,outll=0; - X509_ALGOR *a; + int inl=0,outl=0,outll=0; + int signid, paramtype; - EVP_MD_CTX_init(&ctx); - for (i=0; i<2; i++) + if (type == NULL) { - if (i == 0) - a=algor1; - else - a=algor2; - if (a == NULL) continue; - if (type->pkey_type == NID_dsaWithSHA1 || - type->pkey_type == NID_ecdsa_with_SHA1) - { - /* special case: RFC 3279 tells us to omit 'parameters' - * with id-dsa-with-sha1 and ecdsa-with-SHA1 */ - ASN1_TYPE_free(a->parameter); - a->parameter = NULL; - } - else if ((a->parameter == NULL) || - (a->parameter->type != V_ASN1_NULL)) - { - ASN1_TYPE_free(a->parameter); - if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err; - a->parameter->type=V_ASN1_NULL; - } - ASN1_OBJECT_free(a->algorithm); - a->algorithm=OBJ_nid2obj(type->pkey_type); - if (a->algorithm == NULL) - { - ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); - goto err; - } - if (a->algorithm->length == 0) + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } + + if (type == NULL) + { + ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST); + return 0; + } + + if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) + { + if (!pkey->ameth || + !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), + pkey->ameth->pkey_id)) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); - goto err; + ASN1err(ASN1_F_ASN1_ITEM_SIGN, + ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; } } + else + signid = type->pkey_type; + + if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) + paramtype = V_ASN1_NULL; + else + paramtype = V_ASN1_UNDEF; + + if (algor1) + X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); + if (algor2) + X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); + + EVP_MD_CTX_init(&ctx); inl=ASN1_item_i2d(asn,&buf_in, it); outll=outl=EVP_PKEY_size(pkey); buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); @@ -267,12 +270,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, goto err; } - if (!EVP_SignInit_ex(&ctx,type, NULL)) - { - outl=0; - ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB); - goto err; - } + EVP_SignInit_ex(&ctx,type, NULL); EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, (unsigned int *)&outl,pkey)) diff --git a/crypto/openssl/crypto/asn1/a_strnid.c b/crypto/openssl/crypto/asn1/a_strnid.c index fe515b52ba..753021a7a2 100644 --- a/crypto/openssl/crypto/asn1/a_strnid.c +++ b/crypto/openssl/crypto/asn1/a_strnid.c @@ -67,7 +67,6 @@ static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; static void st_free(ASN1_STRING_TABLE *tbl); static int sk_table_cmp(const ASN1_STRING_TABLE * const *a, const ASN1_STRING_TABLE * const *b); -static int table_cmp(const void *a, const void *b); /* This is the global mask for the mbstring functions: this is use to @@ -158,7 +157,7 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, /* This table must be kept in NID order */ -static ASN1_STRING_TABLE tbl_standard[] = { +static const ASN1_STRING_TABLE tbl_standard[] = { {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, @@ -186,22 +185,23 @@ static int sk_table_cmp(const ASN1_STRING_TABLE * const *a, return (*a)->nid - (*b)->nid; } -static int table_cmp(const void *a, const void *b) +DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); + +static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) { - const ASN1_STRING_TABLE *sa = a, *sb = b; - return sa->nid - sb->nid; + return a->nid - b->nid; } +IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); + ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) { int idx; ASN1_STRING_TABLE *ttmp; ASN1_STRING_TABLE fnd; fnd.nid = nid; - ttmp = (ASN1_STRING_TABLE *) OBJ_bsearch((char *)&fnd, - (char *)tbl_standard, - sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE), - sizeof(ASN1_STRING_TABLE), table_cmp); + ttmp = OBJ_bsearch_table(&fnd, tbl_standard, + sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE)); if(ttmp) return ttmp; if(!stable) return NULL; idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); diff --git a/crypto/openssl/crypto/asn1/a_time.c b/crypto/openssl/crypto/asn1/a_time.c index 159681fbcb..e2eb9b243e 100644 --- a/crypto/openssl/crypto/asn1/a_time.c +++ b/crypto/openssl/crypto/asn1/a_time.c @@ -100,18 +100,29 @@ int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp) ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) { + return ASN1_TIME_adj(s, t, 0, 0); + } + +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec) + { struct tm *ts; struct tm data; ts=OPENSSL_gmtime(&t,&data); if (ts == NULL) { - ASN1err(ASN1_F_ASN1_TIME_SET, ASN1_R_ERROR_GETTING_TIME); + ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); return NULL; } + if (offset_day || offset_sec) + { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } if((ts->tm_year >= 50) && (ts->tm_year < 150)) - return ASN1_UTCTIME_set(s, t); - return ASN1_GENERALIZEDTIME_set(s,t); + return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); } int ASN1_TIME_check(ASN1_TIME *t) @@ -162,3 +173,26 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZE return ret; } + +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) + { + ASN1_TIME t; + + t.length = strlen(str); + t.data = (unsigned char *)str; + t.flags = 0; + + t.type = V_ASN1_UTCTIME; + + if (!ASN1_TIME_check(&t)) + { + t.type = V_ASN1_GENERALIZEDTIME; + if (!ASN1_TIME_check(&t)) + return 0; + } + + if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) + return 0; + + return 1; + } diff --git a/crypto/openssl/crypto/asn1/a_type.c b/crypto/openssl/crypto/asn1/a_type.c index 36beceacdb..a45d2f9d12 100644 --- a/crypto/openssl/crypto/asn1/a_type.c +++ b/crypto/openssl/crypto/asn1/a_type.c @@ -77,7 +77,10 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); } a->type=type; - a->value.ptr=value; + if (type == V_ASN1_BOOLEAN) + a->value.boolean = value ? 0xff : 0; + else + a->value.ptr=value; } int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) @@ -98,7 +101,7 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) else { ASN1_STRING *sdup; - sdup = ASN1_STRING_dup((ASN1_STRING *)value); + sdup = ASN1_STRING_dup(value); if (!sdup) return 0; ASN1_TYPE_set(a, type, sdup); @@ -108,3 +111,49 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) IMPLEMENT_STACK_OF(ASN1_TYPE) IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) + +/* Returns 0 if they are equal, != 0 otherwise. */ +int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b) + { + int result = -1; + + if (!a || !b || a->type != b->type) return -1; + + switch (a->type) + { + case V_ASN1_OBJECT: + result = OBJ_cmp(a->value.object, b->value.object); + break; + case V_ASN1_NULL: + result = 0; /* They do not have content. */ + break; + case V_ASN1_INTEGER: + case V_ASN1_NEG_INTEGER: + case V_ASN1_ENUMERATED: + case V_ASN1_NEG_ENUMERATED: + case V_ASN1_BIT_STRING: + case V_ASN1_OCTET_STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + default: + result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr, + (ASN1_STRING *) b->value.ptr); + break; + } + + return result; + } diff --git a/crypto/openssl/crypto/asn1/a_utctm.c b/crypto/openssl/crypto/asn1/a_utctm.c index d31c028193..072e236592 100644 --- a/crypto/openssl/crypto/asn1/a_utctm.c +++ b/crypto/openssl/crypto/asn1/a_utctm.c @@ -114,8 +114,8 @@ err: int ASN1_UTCTIME_check(ASN1_UTCTIME *d) { - static int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0}; - static int max[8]={99,12,31,23,59,59,12,59}; + static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0}; + static const int max[8]={99,12,31,23,59,59,12,59}; char *a; int n,i,l,o; @@ -186,6 +186,12 @@ int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) { + return ASN1_UTCTIME_adj(s, t, 0, 0); + } + +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec) + { char *p; struct tm *ts; struct tm data; @@ -200,13 +206,22 @@ ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) if (ts == NULL) return(NULL); + if (offset_day || offset_sec) + { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + + if((ts->tm_year < 50) || (ts->tm_year >= 150)) + return NULL; + p=(char *)s->data; if ((p == NULL) || ((size_t)s->length < len)) { p=OPENSSL_malloc(len); if (p == NULL) { - ASN1err(ASN1_F_ASN1_UTCTIME_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE); return(NULL); } if (s->data != NULL) diff --git a/crypto/openssl/crypto/asn1/a_verify.c b/crypto/openssl/crypto/asn1/a_verify.c index da3efaaf8d..cecdb13c70 100644 --- a/crypto/openssl/crypto/asn1/a_verify.c +++ b/crypto/openssl/crypto/asn1/a_verify.c @@ -60,6 +60,7 @@ #include #include "cryptlib.h" +#include "asn1_locl.h" #ifndef NO_SYS_TYPES_H # include @@ -100,12 +101,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, p=buf_in; i2d(data,&p); - if (!EVP_VerifyInit_ex(&ctx,type, NULL)) - { - ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB); - ret=0; - goto err; - } + EVP_VerifyInit_ex(&ctx,type, NULL); EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl); OPENSSL_cleanse(buf_in,(unsigned int)inl); @@ -134,19 +130,34 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat void *asn, EVP_PKEY *pkey) { EVP_MD_CTX ctx; - const EVP_MD *type; + const EVP_MD *type = NULL; unsigned char *buf_in=NULL; - int ret= -1,i,inl; + int ret= -1,inl; + + int mdnid, pknid; EVP_MD_CTX_init(&ctx); - i=OBJ_obj2nid(a->algorithm); - type=EVP_get_digestbyname(OBJ_nid2sn(i)); + + /* Convert signature OID into digest and public key OIDs */ + if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) + { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + type=EVP_get_digestbynid(mdnid); if (type == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } + /* Check public key OID matches public key type */ + if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) + { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + if (!EVP_VerifyInit_ex(&ctx,type, NULL)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); diff --git a/crypto/openssl/crypto/asn1/ameth_lib.c b/crypto/openssl/crypto/asn1/ameth_lib.c new file mode 100644 index 0000000000..9a8b6cc222 --- /dev/null +++ b/crypto/openssl/crypto/asn1/ameth_lib.c @@ -0,0 +1,450 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include "asn1_locl.h" + +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; + +/* Keep this sorted in type order !! */ +static const EVP_PKEY_ASN1_METHOD *standard_methods[] = + { +#ifndef OPENSSL_NO_RSA + &rsa_asn1_meths[0], + &rsa_asn1_meths[1], +#endif +#ifndef OPENSSL_NO_DH + &dh_asn1_meth, +#endif +#ifndef OPENSSL_NO_DSA + &dsa_asn1_meths[0], + &dsa_asn1_meths[1], + &dsa_asn1_meths[2], + &dsa_asn1_meths[3], + &dsa_asn1_meths[4], +#endif +#ifndef OPENSSL_NO_EC + &eckey_asn1_meth, +#endif + &hmac_asn1_meth + }; + +typedef int sk_cmp_fn_type(const char * const *a, const char * const *b); +DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD) +static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL; + + + +#ifdef TEST +void main() + { + int i; + for (i = 0; + i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *); + i++) + fprintf(stderr, "Number %d id=%d (%s)\n", i, + standard_methods[i]->pkey_id, + OBJ_nid2sn(standard_methods[i]->pkey_id)); + } +#endif + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + +static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a, + const EVP_PKEY_ASN1_METHOD * const *b) + { + return ((*a)->pkey_id - (*b)->pkey_id); + } + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + +int EVP_PKEY_asn1_get_count(void) + { + int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *); + if (app_methods) + num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); + return num; + } + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) + { + int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *); + if (idx < 0) + return NULL; + if (idx < num) + return standard_methods[idx]; + idx -= num; + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); + } + +static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) + { + EVP_PKEY_ASN1_METHOD tmp; + const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; + if (app_methods) + { + int idx; + idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); + } + ret = OBJ_bsearch_ameth(&t, standard_methods, + sizeof(standard_methods) + /sizeof(EVP_PKEY_ASN1_METHOD *)); + if (!ret || !*ret) + return NULL; + return *ret; + } + +/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL + * also search through engines and set *pe to a functional reference + * to the engine implementing 'type' or NULL if no engine implements + * it. + */ + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type) + { + const EVP_PKEY_ASN1_METHOD *t; + ENGINE *e; + + for (;;) + { + t = pkey_asn1_find(type); + if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) + break; + type = t->pkey_base_id; + } + if (pe) + { +#ifndef OPENSSL_NO_ENGINE + /* type will contain the final unaliased type */ + e = ENGINE_get_pkey_asn1_meth_engine(type); + if (e) + { + *pe = e; + return ENGINE_get_pkey_asn1_meth(e, type); + } +#endif + *pe = NULL; + } + return t; + } + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len) + { + int i; + const EVP_PKEY_ASN1_METHOD *ameth; + if (len == -1) + len = strlen(str); + if (pe) + { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + ameth = ENGINE_pkey_asn1_find_str(&e, str, len); + if (ameth) + { + /* Convert structural into + * functional reference + */ + if (!ENGINE_init(e)) + ameth = NULL; + ENGINE_free(e); + *pe = e; + return ameth; + } +#endif + *pe = NULL; + } + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) + { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_flags & ASN1_PKEY_ALIAS) + continue; + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; + } + +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) + { + if (app_methods == NULL) + { + app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); + if (!app_methods) + return 0; + } + if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) + return 0; + sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); + return 1; + } + +int EVP_PKEY_asn1_add_alias(int to, int from) + { + EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); + if (!ameth) + return 0; + ameth->pkey_base_id = to; + return EVP_PKEY_asn1_add0(ameth); + } + +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth) + { + if (!ameth) + return 0; + if (ppkey_id) + *ppkey_id = ameth->pkey_id; + if (ppkey_base_id) + *ppkey_base_id = ameth->pkey_base_id; + if (ppkey_flags) + *ppkey_flags = ameth->pkey_flags; + if (pinfo) + *pinfo = ameth->info; + if (ppem_str) + *ppem_str = ameth->pem_str; + return 1; + } + +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey) + { + return pkey->ameth; + } + +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, const char *info) + { + EVP_PKEY_ASN1_METHOD *ameth; + ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD)); + if (!ameth) + return NULL; + + ameth->pkey_id = id; + ameth->pkey_base_id = id; + ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; + + if (info) + { + ameth->info = BUF_strdup(info); + if (!ameth->info) + goto err; + } + else + ameth->info = NULL; + + if (pem_str) + { + ameth->pem_str = BUF_strdup(pem_str); + if (!ameth->pem_str) + goto err; + } + else + ameth->pem_str = NULL; + + ameth->pub_decode = 0; + ameth->pub_encode = 0; + ameth->pub_cmp = 0; + ameth->pub_print = 0; + + ameth->priv_decode = 0; + ameth->priv_encode = 0; + ameth->priv_print = 0; + + ameth->old_priv_encode = 0; + ameth->old_priv_decode = 0; + + ameth->pkey_size = 0; + ameth->pkey_bits = 0; + + ameth->param_decode = 0; + ameth->param_encode = 0; + ameth->param_missing = 0; + ameth->param_copy = 0; + ameth->param_cmp = 0; + ameth->param_print = 0; + + ameth->pkey_free = 0; + ameth->pkey_ctrl = 0; + + return ameth; + + err: + + EVP_PKEY_asn1_free(ameth); + return NULL; + + } + +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src) + { + + dst->pub_decode = src->pub_decode; + dst->pub_encode = src->pub_encode; + dst->pub_cmp = src->pub_cmp; + dst->pub_print = src->pub_print; + + dst->priv_decode = src->priv_decode; + dst->priv_encode = src->priv_encode; + dst->priv_print = src->priv_print; + + dst->old_priv_encode = src->old_priv_encode; + dst->old_priv_decode = src->old_priv_decode; + + dst->pkey_size = src->pkey_size; + dst->pkey_bits = src->pkey_bits; + + dst->param_decode = src->param_decode; + dst->param_encode = src->param_encode; + dst->param_missing = src->param_missing; + dst->param_copy = src->param_copy; + dst->param_cmp = src->param_cmp; + dst->param_print = src->param_print; + + dst->pkey_free = src->pkey_free; + dst->pkey_ctrl = src->pkey_ctrl; + + } + +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) + { + if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) + { + if (ameth->pem_str) + OPENSSL_free(ameth->pem_str); + if (ameth->info) + OPENSSL_free(ameth->info); + OPENSSL_free(ameth); + } + } + +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub), + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk), + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx), + int (*pkey_size)(const EVP_PKEY *pk), + int (*pkey_bits)(const EVP_PKEY *pk)) + { + ameth->pub_decode = pub_decode; + ameth->pub_encode = pub_encode; + ameth->pub_cmp = pub_cmp; + ameth->pub_print = pub_print; + ameth->pkey_size = pkey_size; + ameth->pkey_bits = pkey_bits; + } + +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf), + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk), + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)) + { + ameth->priv_decode = priv_decode; + ameth->priv_encode = priv_encode; + ameth->priv_print = priv_print; + } + +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode)(EVP_PKEY *pkey, + const unsigned char **pder, int derlen), + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **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), + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)) + { + ameth->param_decode = param_decode; + ameth->param_encode = param_encode; + ameth->param_missing = param_missing; + ameth->param_copy = param_copy; + ameth->param_cmp = param_cmp; + ameth->param_print = param_print; + } + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free)(EVP_PKEY *pkey)) + { + ameth->pkey_free = pkey_free; + } + +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, + long arg1, void *arg2)) + { + ameth->pkey_ctrl = pkey_ctrl; + } diff --git a/crypto/openssl/crypto/asn1/asn1.h b/crypto/openssl/crypto/asn1/asn1.h index 1958298f74..f7718b5a94 100644 --- a/crypto/openssl/crypto/asn1/asn1.h +++ b/crypto/openssl/crypto/asn1/asn1.h @@ -213,7 +213,7 @@ typedef struct asn1_object_st const char *sn,*ln; int nid; int length; - unsigned char *data; + const unsigned char *data; /* data remains const after init */ int flags; /* Should we free this one */ } ASN1_OBJECT; @@ -228,8 +228,12 @@ typedef struct asn1_object_st * complete and is a place holder for content when it had all been * accessed. The flag will be reset when content has been written to it. */ -#define ASN1_STRING_FLAG_CONT 0x020 +#define ASN1_STRING_FLAG_CONT 0x020 +/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +#define ASN1_STRING_FLAG_MSTRING 0x040 /* This is the base type that holds just about everything :-) */ typedef struct asn1_string_st { @@ -330,6 +334,13 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; type *name##_new(void); \ void name##_free(type *a); +#define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + #define D2I_OF(type) type *(*)(type **,const unsigned char **,long) #define I2D_OF(type) int (*)(type *,unsigned char **) #define I2D_OF_const(type) int (*)(const type *,unsigned char **) @@ -344,8 +355,6 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; ((void*) (1 ? p : (type*)0)) #define CHECKED_PPTR_OF(type, p) \ ((void**) (1 ? p : (type**)0)) -#define CHECKED_PTR_OF_TO_CHAR(type, p) \ - ((char*) (1 ? p : (type*)0)) #define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) #define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) @@ -536,28 +545,23 @@ typedef struct asn1_type_st * contain the set or sequence bytes */ ASN1_STRING * set; ASN1_STRING * sequence; - ASN1_VALUE * asn1_value; + ASN1_VALUE * asn1_value; } value; } ASN1_TYPE; DECLARE_STACK_OF(ASN1_TYPE) DECLARE_ASN1_SET_OF(ASN1_TYPE) -typedef struct asn1_method_st - { - i2d_of_void *i2d; - d2i_of_void *d2i; - void *(*create)(void); - void (*destroy)(void *); - } ASN1_METHOD; - -/* This is used when parsing some Netscape objects */ -typedef struct asn1_header_st +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +typedef struct NETSCAPE_X509_st { ASN1_OCTET_STRING *header; - void *data; - ASN1_METHOD *meth; - } ASN1_HEADER; + X509 *cert; + } NETSCAPE_X509; /* This is used to contain a list of bit names */ typedef struct BIT_STRING_BITNAME_st { @@ -577,32 +581,34 @@ typedef struct BIT_STRING_BITNAME_st { ASN1_STRING_type_new(V_ASN1_BIT_STRING) #define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) #define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ - ASN1_STRING_dup((ASN1_STRING *)a) + ASN1_STRING_dup((const ASN1_STRING *)a) #define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ - (ASN1_STRING *)a,(ASN1_STRING *)b) + (const ASN1_STRING *)a,(const ASN1_STRING *)b) #define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) #define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ ASN1_STRING_type_new(V_ASN1_INTEGER) #define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) -#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a) +#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) #define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ - (ASN1_STRING *)a,(ASN1_STRING *)b) + (const ASN1_STRING *)a,(const ASN1_STRING *)b) #define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ ASN1_STRING_type_new(V_ASN1_ENUMERATED) #define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) -#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a) +#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) #define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ - (ASN1_STRING *)a,(ASN1_STRING *)b) + (const ASN1_STRING *)a,(const ASN1_STRING *)b) #define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ ASN1_STRING_type_new(V_ASN1_OCTET_STRING) #define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) #define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ - ASN1_STRING_dup((ASN1_STRING *)a) + ASN1_STRING_dup((const ASN1_STRING *)a) #define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ - (ASN1_STRING *)a,(ASN1_STRING *)b) + (const ASN1_STRING *)a,(const ASN1_STRING *)b) #define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) #define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) #define M_i2d_ASN1_OCTET_STRING(a,pp) \ @@ -686,7 +692,7 @@ typedef struct BIT_STRING_BITNAME_st { ASN1_STRING_type_new(V_ASN1_IA5STRING) #define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) #define M_ASN1_IA5STRING_dup(a) \ - (ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a) + (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) #define M_i2d_ASN1_IA5STRING(a,pp) \ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ V_ASN1_UNIVERSAL) @@ -697,18 +703,20 @@ typedef struct BIT_STRING_BITNAME_st { #define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ ASN1_STRING_type_new(V_ASN1_UTCTIME) #define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) -#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a) +#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) #define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) #define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) #define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ - (ASN1_STRING *)a) + (const ASN1_STRING *)a) #define M_ASN1_TIME_new() (ASN1_TIME *)\ ASN1_STRING_type_new(V_ASN1_UTCTIME) #define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) -#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a) +#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) #define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ ASN1_STRING_type_new(V_ASN1_GENERALSTRING) @@ -769,6 +777,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) int ASN1_TYPE_get(ASN1_TYPE *a); void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b); ASN1_OBJECT * ASN1_OBJECT_new(void ); void ASN1_OBJECT_free(ASN1_OBJECT *a); @@ -785,14 +794,15 @@ DECLARE_ASN1_SET_OF(ASN1_OBJECT) ASN1_STRING * ASN1_STRING_new(void); void ASN1_STRING_free(ASN1_STRING *a); -ASN1_STRING * ASN1_STRING_dup(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a); ASN1_STRING * ASN1_STRING_type_new(int type ); -int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); /* Since this is used to store all sorts of things, via macros, for now, make its data void * */ int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); -int ASN1_STRING_length(ASN1_STRING *x); +int ASN1_STRING_length(const ASN1_STRING *x); void ASN1_STRING_length_set(ASN1_STRING *x, int n); int ASN1_STRING_type(ASN1_STRING *x); unsigned char * ASN1_STRING_data(ASN1_STRING *x); @@ -805,6 +815,8 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len); #ifndef OPENSSL_NO_BIO int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, @@ -823,13 +835,15 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); -ASN1_INTEGER * ASN1_INTEGER_dup(ASN1_INTEGER *x); -int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y); +ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) int ASN1_UTCTIME_check(ASN1_UTCTIME *a); ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); #if 0 @@ -838,11 +852,13 @@ time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a); ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, long offset_sec); int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) -ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a); -int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b); +ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b); int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len); DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) @@ -869,14 +885,20 @@ DECLARE_ASN1_FUNCTIONS(ASN1_TIME) DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t, + int offset_day, long offset_sec); int ASN1_TIME_check(ASN1_TIME *t); ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); -int i2d_ASN1_SET(STACK *a, unsigned char **pp, - i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); -STACK * d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length, - d2i_of_void *d2i, void (*free_func)(void *), - int ex_tag, int ex_class); +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, + int is_set); +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func)(OPENSSL_BLOCK), int ex_tag, + int ex_class); #ifndef OPENSSL_NO_BIO int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); @@ -894,9 +916,9 @@ ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len, const char *sn, const char *ln); int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); -long ASN1_INTEGER_get(ASN1_INTEGER *a); -ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai); -BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn); int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); @@ -930,17 +952,17 @@ int ASN1_put_eoc(unsigned char **pp); int ASN1_object_size(int constructed, int length, int tag); /* Used to implement other functions */ -void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); #define ASN1_dup_of(type,i2d,d2i,x) \ ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ CHECKED_D2I_OF(type, d2i), \ - CHECKED_PTR_OF_TO_CHAR(type, x))) + CHECKED_PTR_OF(type, x))) #define ASN1_dup_of_const(type,i2d,d2i,x) \ ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ CHECKED_D2I_OF(type, d2i), \ - CHECKED_PTR_OF_TO_CHAR(const type, x))) + CHECKED_PTR_OF(const type, x))) void *ASN1_item_dup(const ASN1_ITEM *it, void *x); @@ -1001,29 +1023,23 @@ int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x); CHECKED_PTR_OF(const type, x))) int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); -int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a); -int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a); -int ASN1_TIME_print(BIO *fp,ASN1_TIME *a); -int ASN1_STRING_print(BIO *bp,ASN1_STRING *v); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent); int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump); #endif const char *ASN1_tag2str(int tag); -/* Used to load and write netscape format cert/key */ -int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp); -ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length); -ASN1_HEADER *ASN1_HEADER_new(void ); -void ASN1_HEADER_free(ASN1_HEADER *a); +/* Used to load and write netscape format cert */ -int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) -/* Not used that much at this point, except for the first two */ -ASN1_METHOD *X509_asn1_meth(void); -ASN1_METHOD *RSAPrivateKey_asn1_meth(void); -ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void); -ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void); +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); @@ -1034,9 +1050,9 @@ int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num, unsigned char *data, int max_len); -STACK *ASN1_seq_unpack(const unsigned char *buf, int len, - d2i_of_void *d2i, void (*free_func)(void *)); -unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d, +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK)); +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, unsigned char **buf, int *len ); void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); @@ -1079,15 +1095,58 @@ void ASN1_add_oid_module(void); ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); -typedef int asn1_output_data_fn(BIO *out, BIO *data, ASN1_VALUE *val, int flags, - const ASN1_ITEM *it); - -int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, + const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, int ctype_nid, int econt_nid, STACK_OF(X509_ALGOR) *mdalgs, - asn1_output_data_fn *data_fn, const ASN1_ITEM *it); ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -1118,6 +1177,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_ASN1_ENUMERATED_TO_BN 113 #define ASN1_F_ASN1_EX_C2I 204 #define ASN1_F_ASN1_FIND_END 190 +#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 #define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 #define ASN1_F_ASN1_GENERATE_V3 178 #define ASN1_F_ASN1_GET_OBJECT 114 @@ -1138,7 +1198,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_ASN1_ITEM_VERIFY 197 #define ASN1_F_ASN1_MBSTRING_NCOPY 122 #define ASN1_F_ASN1_OBJECT_NEW 123 -#define ASN1_F_ASN1_OUTPUT_DATA 207 +#define ASN1_F_ASN1_OUTPUT_DATA 214 #define ASN1_F_ASN1_PACK_STRING 124 #define ASN1_F_ASN1_PCTX_NEW 205 #define ASN1_F_ASN1_PKCS5_PBE_SET 125 @@ -1152,14 +1212,17 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 #define ASN1_F_ASN1_TEMPLATE_NEW 133 #define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +#define ASN1_F_ASN1_TIME_ADJ 217 #define ASN1_F_ASN1_TIME_SET 175 #define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 #define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 #define ASN1_F_ASN1_UNPACK_STRING 136 +#define ASN1_F_ASN1_UTCTIME_ADJ 218 #define ASN1_F_ASN1_UTCTIME_SET 187 #define ASN1_F_ASN1_VERIFY 137 -#define ASN1_F_B64_READ_ASN1 208 -#define ASN1_F_B64_WRITE_ASN1 209 +#define ASN1_F_B64_READ_ASN1 209 +#define ASN1_F_B64_WRITE_ASN1 210 +#define ASN1_F_BIO_NEW_NDEF 208 #define ASN1_F_BITSTR_CB 180 #define ASN1_F_BN_TO_ASN1_ENUMERATED 138 #define ASN1_F_BN_TO_ASN1_INTEGER 139 @@ -1178,6 +1241,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_D2I_ASN1_TYPE_BYTES 149 #define ASN1_F_D2I_ASN1_UINTEGER 150 #define ASN1_F_D2I_ASN1_UTCTIME 151 +#define ASN1_F_D2I_AUTOPRIVATEKEY 207 #define ASN1_F_D2I_NETSCAPE_RSA 152 #define ASN1_F_D2I_NETSCAPE_RSA_2 153 #define ASN1_F_D2I_PRIVATEKEY 154 @@ -1187,6 +1251,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_D2I_X509 156 #define ASN1_F_D2I_X509_CINF 157 #define ASN1_F_D2I_X509_PKEY 159 +#define ASN1_F_I2D_ASN1_BIO_STREAM 211 #define ASN1_F_I2D_ASN1_SET 188 #define ASN1_F_I2D_ASN1_TIME 160 #define ASN1_F_I2D_DSA_PUBKEY 161 @@ -1198,10 +1263,11 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_LONG_C2I 166 #define ASN1_F_OID_MODULE_INIT 174 #define ASN1_F_PARSE_TAGGING 182 -#define ASN1_F_PKCS5_PBE2_SET 167 +#define ASN1_F_PKCS5_PBE2_SET_IV 167 #define ASN1_F_PKCS5_PBE_SET 202 -#define ASN1_F_SMIME_READ_ASN1 210 -#define ASN1_F_SMIME_TEXT 211 +#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +#define ASN1_F_SMIME_READ_ASN1 212 +#define ASN1_F_SMIME_TEXT 213 #define ASN1_F_X509_CINF_NEW 168 #define ASN1_F_X509_CRL_ADD0_REVOKED 169 #define ASN1_F_X509_INFO_NEW 170 @@ -1213,14 +1279,14 @@ void ERR_load_ASN1_strings(void); /* Reason codes. */ #define ASN1_R_ADDING_OBJECT 171 -#define ASN1_R_ASN1_PARSE_ERROR 198 -#define ASN1_R_ASN1_SIG_PARSE_ERROR 199 +#define ASN1_R_ASN1_PARSE_ERROR 203 +#define ASN1_R_ASN1_SIG_PARSE_ERROR 204 #define ASN1_R_AUX_ERROR 100 #define ASN1_R_BAD_CLASS 101 #define ASN1_R_BAD_OBJECT_HEADER 102 #define ASN1_R_BAD_PASSWORD_READ 103 #define ASN1_R_BAD_TAG 104 -#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 210 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 #define ASN1_R_BN_LIB 105 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 #define ASN1_R_BUFFER_TOO_SMALL 107 @@ -1229,6 +1295,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_DECODE_ERROR 110 #define ASN1_R_DECODING_ERROR 111 #define ASN1_R_DEPTH_EXCEEDED 174 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 #define ASN1_R_ENCODE_ERROR 112 #define ASN1_R_ERROR_GETTING_TIME 173 #define ASN1_R_ERROR_LOADING_SECTION 172 @@ -1262,10 +1329,10 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 #define ASN1_R_INVALID_BMPSTRING_LENGTH 129 #define ASN1_R_INVALID_DIGIT 130 -#define ASN1_R_INVALID_MIME_TYPE 200 +#define ASN1_R_INVALID_MIME_TYPE 205 #define ASN1_R_INVALID_MODIFIER 186 #define ASN1_R_INVALID_NUMBER 187 -#define ASN1_R_INVALID_OBJECT_ENCODING 212 +#define ASN1_R_INVALID_OBJECT_ENCODING 216 #define ASN1_R_INVALID_SEPARATOR 131 #define ASN1_R_INVALID_TIME_FORMAT 132 #define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 @@ -1273,9 +1340,9 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_IV_TOO_LARGE 135 #define ASN1_R_LENGTH_ERROR 136 #define ASN1_R_LIST_ERROR 188 -#define ASN1_R_MIME_NO_CONTENT_TYPE 201 -#define ASN1_R_MIME_PARSE_ERROR 202 -#define ASN1_R_MIME_SIG_PARSE_ERROR 203 +#define ASN1_R_MIME_NO_CONTENT_TYPE 206 +#define ASN1_R_MIME_PARSE_ERROR 207 +#define ASN1_R_MIME_SIG_PARSE_ERROR 208 #define ASN1_R_MISSING_EOC 137 #define ASN1_R_MISSING_SECOND_NUMBER 138 #define ASN1_R_MISSING_VALUE 189 @@ -1285,11 +1352,12 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_NON_HEX_CHARACTERS 141 #define ASN1_R_NOT_ASCII_FORMAT 190 #define ASN1_R_NOT_ENOUGH_DATA 142 -#define ASN1_R_NO_CONTENT_TYPE 204 +#define ASN1_R_NO_CONTENT_TYPE 209 +#define ASN1_R_NO_DEFAULT_DIGEST 201 #define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 -#define ASN1_R_NO_MULTIPART_BODY_FAILURE 205 -#define ASN1_R_NO_MULTIPART_BOUNDARY 206 -#define ASN1_R_NO_SIG_CONTENT_TYPE 207 +#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +#define ASN1_R_NO_MULTIPART_BOUNDARY 211 +#define ASN1_R_NO_SIG_CONTENT_TYPE 212 #define ASN1_R_NULL_IS_WRONG_LENGTH 144 #define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 #define ASN1_R_ODD_NUMBER_OF_CHARS 145 @@ -1299,8 +1367,8 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 #define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 #define ASN1_R_SHORT_LINE 150 -#define ASN1_R_SIG_INVALID_MIME_TYPE 208 -#define ASN1_R_STREAMING_NOT_SUPPORTED 209 +#define ASN1_R_SIG_INVALID_MIME_TYPE 213 +#define ASN1_R_STREAMING_NOT_SUPPORTED 202 #define ASN1_R_STRING_TOO_LONG 151 #define ASN1_R_STRING_TOO_SHORT 152 #define ASN1_R_TAG_VALUE_TOO_HIGH 153 @@ -1311,11 +1379,12 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 #define ASN1_R_UNEXPECTED_EOC 159 -#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 211 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 #define ASN1_R_UNKNOWN_FORMAT 160 #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 #define ASN1_R_UNKNOWN_OBJECT_TYPE 162 #define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 #define ASN1_R_UNKNOWN_TAG 194 #define ASN1_R_UNKOWN_FORMAT 195 #define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 @@ -1323,6 +1392,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 #define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 #define ASN1_R_UNSUPPORTED_TYPE 196 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 #define ASN1_R_WRONG_TAG 168 #define ASN1_R_WRONG_TYPE 169 diff --git a/crypto/openssl/crypto/asn1/asn1_err.c b/crypto/openssl/crypto/asn1/asn1_err.c index ba88eb318b..6e04d08f31 100644 --- a/crypto/openssl/crypto/asn1/asn1_err.c +++ b/crypto/openssl/crypto/asn1/asn1_err.c @@ -1,6 +1,6 @@ /* crypto/asn1/asn1_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -90,10 +90,11 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, {ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"}, {ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, +{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"}, {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"}, {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, -{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_new"}, +{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"}, {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"}, {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"}, {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"}, @@ -112,7 +113,7 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"}, {ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, -{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"}, +{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"}, {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, @@ -124,14 +125,17 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"}, {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"}, {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"}, +{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"}, {ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"}, {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"}, {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"}, {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"}, +{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"}, {ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"}, {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"}, {ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"}, {ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"}, +{ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"}, {ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"}, {ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"}, {ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"}, @@ -143,13 +147,14 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"}, {ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"}, {ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"}, -{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "d2i_ASN1_HEADER"}, +{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"}, {ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"}, {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"}, {ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"}, {ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"}, {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"}, {ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"}, +{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"}, {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"}, {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"}, {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"}, @@ -159,6 +164,7 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, {ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, {ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, +{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"}, {ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, {ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"}, @@ -170,8 +176,9 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"}, {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, {ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, -{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET), "PKCS5_pbe2_set"}, +{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"}, {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, +{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"}, {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, {ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"}, @@ -204,6 +211,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"}, {ERR_REASON(ASN1_R_DEPTH_EXCEEDED) ,"depth exceeded"}, +{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"}, {ERR_REASON(ASN1_R_ENCODE_ERROR) ,"encode error"}, {ERR_REASON(ASN1_R_ERROR_GETTING_TIME) ,"error getting time"}, {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"}, @@ -261,6 +269,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"}, {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"}, {ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"}, +{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST) ,"no default digest"}, {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"}, {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, @@ -291,6 +300,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"}, {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"}, {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"}, +{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"}, {ERR_REASON(ASN1_R_UNKNOWN_TAG) ,"unknown tag"}, {ERR_REASON(ASN1_R_UNKOWN_FORMAT) ,"unkown format"}, {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"}, @@ -298,6 +308,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"}, {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"}, {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) ,"unsupported type"}, +{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"}, {ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"}, {ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"}, {0,NULL} diff --git a/crypto/openssl/crypto/asn1/asn1_gen.c b/crypto/openssl/crypto/asn1/asn1_gen.c index 213a8e986c..4fc241908f 100644 --- a/crypto/openssl/crypto/asn1/asn1_gen.c +++ b/crypto/openssl/crypto/asn1/asn1_gen.c @@ -247,8 +247,14 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) /* If IMPLICIT, output tag */ if (asn1_tags.imp_tag != -1) + { + if (asn1_tags.imp_class == V_ASN1_UNIVERSAL + && (asn1_tags.imp_tag == V_ASN1_SEQUENCE + || asn1_tags.imp_tag == V_ASN1_SET) ) + hdr_constructed = V_ASN1_CONSTRUCTED; ASN1_put_object(&p, hdr_constructed, hdr_len, asn1_tags.imp_tag, asn1_tags.imp_class); + } /* Copy across original encoding */ memcpy(p, cpy_start, cpy_len); @@ -441,12 +447,12 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) { - ASN1_TYPE *ret = NULL, *typ = NULL; + ASN1_TYPE *ret = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(CONF_VALUE) *sect = NULL; - unsigned char *der = NULL, *p; + unsigned char *der = NULL; int derlen; - int i, is_set; + int i; sk = sk_ASN1_TYPE_new_null(); if (!sk) goto bad; @@ -459,31 +465,23 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { - typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); + ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); if (!typ) goto bad; if (!sk_ASN1_TYPE_push(sk, typ)) goto bad; - typ = NULL; } } /* Now we has a STACK of the components, convert to the correct form */ if (utype == V_ASN1_SET) - is_set = 1; + derlen = i2d_ASN1_SET_ANY(sk, &der); else - is_set = 0; - + derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); - derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, - V_ASN1_UNIVERSAL, is_set); - der = OPENSSL_malloc(derlen); - if (!der) + if (derlen < 0) goto bad; - p = der; - i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, - V_ASN1_UNIVERSAL, is_set); if (!(ret = ASN1_TYPE_new())) goto bad; @@ -505,8 +503,6 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); - if (typ) - ASN1_TYPE_free(typ); if (sect) X509V3_section_free(cnf, sect); @@ -556,7 +552,7 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_cons static int asn1_str2tag(const char *tagstr, int len) { unsigned int i; - static struct tag_name_st *tntmp, tnst [] = { + static const struct tag_name_st *tntmp, tnst [] = { ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), ASN1_GEN_STR("NULL", V_ASN1_NULL), @@ -591,6 +587,8 @@ static int asn1_str2tag(const char *tagstr, int len) ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), + ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), /* Special cases */ ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), @@ -736,6 +734,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_VISIBLESTRING: case V_ASN1_UNIVERSALSTRING: case V_ASN1_GENERALSTRING: + case V_ASN1_NUMERICSTRING: if (format == ASN1_GEN_FORMAT_ASCII) format = MBSTRING_ASC; diff --git a/crypto/openssl/crypto/asn1/asn1_lib.c b/crypto/openssl/crypto/asn1/asn1_lib.c index 5af559ef8d..1bcb44aee2 100644 --- a/crypto/openssl/crypto/asn1/asn1_lib.c +++ b/crypto/openssl/crypto/asn1/asn1_lib.c @@ -340,20 +340,31 @@ int asn1_GetSequence(ASN1_const_CTX *c, long *length) return(1); } -ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str) +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) { - ASN1_STRING *ret; + if (str == NULL) + return 0; + dst->type = str->type; + if (!ASN1_STRING_set(dst,str->data,str->length)) + return 0; + dst->flags = str->flags; + return 1; + } - if (str == NULL) return(NULL); - if ((ret=ASN1_STRING_type_new(str->type)) == NULL) - return(NULL); - if (!ASN1_STRING_set(ret,str->data,str->length)) +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) + { + ASN1_STRING *ret; + if (!str) + return NULL; + ret=ASN1_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_STRING_copy(ret,str)) { ASN1_STRING_free(ret); - return(NULL); + return NULL; } - ret->flags = str->flags; - return(ret); + return ret; } int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) @@ -427,11 +438,12 @@ ASN1_STRING *ASN1_STRING_type_new(int type) void ASN1_STRING_free(ASN1_STRING *a) { if (a == NULL) return; - if (a->data != NULL) OPENSSL_free(a->data); + if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) + OPENSSL_free(a->data); OPENSSL_free(a); } -int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b) +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) { int i; @@ -457,7 +469,7 @@ void asn1_add_error(const unsigned char *address, int offset) ERR_add_error_data(4,"address=",buf1," offset=",buf2); } -int ASN1_STRING_length(ASN1_STRING *x) +int ASN1_STRING_length(const ASN1_STRING *x) { return M_ASN1_STRING_length(x); } void ASN1_STRING_length_set(ASN1_STRING *x, int len) diff --git a/crypto/openssl/crypto/x509v3/pcy_node.c b/crypto/openssl/crypto/asn1/asn1_locl.h similarity index 52% copy from crypto/openssl/crypto/x509v3/pcy_node.c copy to crypto/openssl/crypto/asn1/asn1_locl.h index 6587cb05ab..5aa65e28f5 100644 --- a/crypto/openssl/crypto/x509v3/pcy_node.c +++ b/crypto/openssl/crypto/asn1/asn1_locl.h @@ -1,9 +1,9 @@ -/* pcy_node.c */ +/* asn1t.h */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2004. + * project 2006. */ /* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -56,103 +56,79 @@ * */ -#include -#include -#include +/* Internal ASN1 structures and functions: not for application use */ -#include "pcy_int.h" +/* ASN1 print context structure */ -static int node_cmp(const X509_POLICY_NODE * const *a, - const X509_POLICY_NODE * const *b) +struct asn1_pctx_st { - return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); - } + unsigned long flags; + unsigned long nm_flags; + unsigned long cert_flags; + unsigned long oid_flags; + unsigned long str_flags; + } /* ASN1_PCTX */; -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) - { - return sk_X509_POLICY_NODE_new(node_cmp); - } +/* ASN1 public key method structure */ -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, - const ASN1_OBJECT *id) +struct evp_pkey_asn1_method_st { - X509_POLICY_DATA n; - X509_POLICY_NODE l; - int idx; - - n.valid_policy = (ASN1_OBJECT *)id; - l.data = &n; - - idx = sk_X509_POLICY_NODE_find(nodes, &l); - if (idx == -1) - return NULL; - - return sk_X509_POLICY_NODE_value(nodes, idx); - - } + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + + char *pem_str; + char *info; + + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf); + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + 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_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); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + void (*pkey_free)(EVP_PKEY *pkey); + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); + + /* Legacy functions for old PEM */ + + int (*old_priv_decode)(EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); + + } /* EVP_PKEY_ASN1_METHOD */; + +/* Method to handle CRL access. + * In general a CRL could be very large (several Mb) and can consume large + * amounts of resources if stored in memory by multiple processes. + * This method allows general CRL operations to be redirected to more + * efficient callbacks: for example a CRL entry database. + */ -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const ASN1_OBJECT *id) - { - return tree_find_sk(level->nodes, id); - } +#define X509_CRL_METHOD_DYNAMIC 1 -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree) - { - X509_POLICY_NODE *node; - node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); - if (!node) - return NULL; - node->data = data; - node->parent = parent; - node->nchild = 0; - if (level) - { - if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) - { - if (level->anyPolicy) - goto node_error; - level->anyPolicy = node; - } - else - { - - if (!level->nodes) - level->nodes = policy_node_cmp_new(); - if (!level->nodes) - goto node_error; - if (!sk_X509_POLICY_NODE_push(level->nodes, node)) - goto node_error; - } - } - - if (tree) - { - if (!tree->extra_data) - tree->extra_data = sk_X509_POLICY_DATA_new_null(); - if (!tree->extra_data) - goto node_error; - if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) - goto node_error; - } - - if (parent) - parent->nchild++; - - return node; - - node_error: - policy_node_free(node); - return 0; - - } - -void policy_node_free(X509_POLICY_NODE *node) +struct x509_crl_method_st { - OPENSSL_free(node); - } - - + int flags; + int (*crl_init)(X509_CRL *crl); + int (*crl_free)(X509_CRL *crl); + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer); + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk); + }; diff --git a/crypto/openssl/crypto/asn1/asn1_mac.h b/crypto/openssl/crypto/asn1/asn1_mac.h index d958ca60d9..87bd0e9e1d 100644 --- a/crypto/openssl/crypto/asn1/asn1_mac.h +++ b/crypto/openssl/crypto/asn1/asn1_mac.h @@ -153,6 +153,13 @@ err:\ M_ASN1_D2I_get(b,func); \ } +#define M_ASN1_D2I_get_int_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get_int(b,func); \ + } + #define M_ASN1_D2I_get_imp(b,func, type) \ M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ c.q=c.p; \ diff --git a/crypto/openssl/crypto/asn1/asn1_par.c b/crypto/openssl/crypto/asn1/asn1_par.c index cb08e15488..aaca69aebd 100644 --- a/crypto/openssl/crypto/asn1/asn1_par.c +++ b/crypto/openssl/crypto/asn1/asn1_par.c @@ -70,9 +70,8 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, int indent) { static const char fmt[]="%-18s"; - static const char fmt2[]="%2d %-15s"; char str[128]; - const char *p,*p2=NULL; + const char *p; if (constructed & V_ASN1_CONSTRUCTED) p="cons: "; @@ -93,14 +92,8 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, else p = ASN1_tag2str(tag); - if (p2 != NULL) - { - if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err; - } - else - { - if (BIO_printf(bp,fmt,p) <= 0) goto err; - } + if (BIO_printf(bp,fmt,p) <= 0) + goto err; return(1); err: return(0); @@ -424,7 +417,7 @@ end: const char *ASN1_tag2str(int tag) { - static const char *tag2str[] = { + static const char * const tag2str[] = { "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ diff --git a/crypto/openssl/crypto/asn1/asn1t.h b/crypto/openssl/crypto/asn1/asn1t.h index ac14f9415b..d230e4bf70 100644 --- a/crypto/openssl/crypto/asn1/asn1t.h +++ b/crypto/openssl/crypto/asn1/asn1t.h @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-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 @@ -218,6 +218,18 @@ extern "C" { #stname \ ASN1_ITEM_end(tname) +#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + /* This pair helps declare a CHOICE type. We can do: * @@ -651,8 +663,13 @@ typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); typedef struct ASN1_COMPAT_FUNCS_st { ASN1_new_func *asn1_new; @@ -668,6 +685,7 @@ typedef struct ASN1_EXTERN_FUNCS_st { ASN1_ex_free_func *asn1_ex_clear; ASN1_ex_d2i *asn1_ex_d2i; ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; } ASN1_EXTERN_FUNCS; typedef struct ASN1_PRIMITIVE_FUNCS_st { @@ -678,6 +696,7 @@ typedef struct ASN1_PRIMITIVE_FUNCS_st { ASN1_ex_free_func *prim_clear; ASN1_primitive_c2i *prim_c2i; ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; } ASN1_PRIMITIVE_FUNCS; /* This is the ASN1_AUX structure: it handles various @@ -697,7 +716,8 @@ typedef struct ASN1_PRIMITIVE_FUNCS_st { * then an external type is more appropriate. */ -typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it); +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); typedef struct ASN1_AUX_st { void *app_data; @@ -708,6 +728,23 @@ typedef struct ASN1_AUX_st { int enc_offset; /* Offset of ASN1_ENCODING structure */ } ASN1_AUX; +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + /* Flags in ASN1_AUX */ /* Use a reference count */ @@ -727,6 +764,12 @@ typedef struct ASN1_AUX_st { #define ASN1_OP_D2I_POST 5 #define ASN1_OP_I2D_PRE 6 #define ASN1_OP_I2D_POST 7 +#define ASN1_OP_PRINT_PRE 8 +#define ASN1_OP_PRINT_POST 9 +#define ASN1_OP_STREAM_PRE 10 +#define ASN1_OP_STREAM_POST 11 +#define ASN1_OP_DETACHED_PRE 12 +#define ASN1_OP_DETACHED_POST 13 /* Macro to implement a primitive type */ #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) @@ -782,9 +825,22 @@ typedef struct ASN1_AUX_st { #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) +#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ stname *fname##_new(void) \ { \ @@ -834,6 +890,17 @@ typedef struct ASN1_AUX_st { return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ } +#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) diff --git a/crypto/openssl/crypto/asn1/asn_mime.c b/crypto/openssl/crypto/asn1/asn_mime.c index d8d9e76cc0..c1d1b12291 100644 --- a/crypto/openssl/crypto/asn1/asn_mime.c +++ b/crypto/openssl/crypto/asn1/asn_mime.c @@ -59,6 +59,7 @@ #include #include #include +#include "asn1_locl.h" /* Generalised MIME like utilities for streaming ASN1. Although many * have a PKCS7/CMS like flavour others are more general purpose. @@ -86,6 +87,8 @@ STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */ DECLARE_STACK_OF(MIME_HEADER) IMPLEMENT_STACK_OF(MIME_HEADER) +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, + const ASN1_ITEM *it); static char * strip_ends(char *name); static char * strip_start(char *name); static char * strip_end(char *name); @@ -107,6 +110,39 @@ static void mime_hdr_free(MIME_HEADER *hdr); #define MAX_SMLEN 1024 #define mime_debug(x) /* x */ +/* Output an ASN1 structure in BER format streaming if necessary */ + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it) + { + /* If streaming create stream BIO and copy all content through it */ + if (flags & SMIME_STREAM) + { + BIO *bio, *tbio; + bio = BIO_new_NDEF(out, val, it); + if (!bio) + { + ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE); + return 0; + } + SMIME_crlf_copy(in, bio, flags); + (void)BIO_flush(bio); + /* Free up successive BIOs until we hit the old output BIO */ + do + { + tbio = BIO_pop(bio); + BIO_free(bio); + bio = tbio; + } while (bio != out); + } + /* else just write out ASN1 structure which will have all content + * stored internally + */ + else + ASN1_item_i2d_bio(it, out, val); + return 1; + } + /* Base 64 read and write of ASN1 structure */ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, @@ -123,13 +159,26 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, /* prepend the b64 BIO so all data is base64 encoded. */ out = BIO_push(b64, out); - r = ASN1_item_i2d_bio(it, out, val); + r = i2d_ASN1_bio_stream(out, val, in, flags, it); (void)BIO_flush(out); BIO_pop(out); BIO_free(b64); return r; } +/* Streaming ASN1 PEM write */ + +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, + const ASN1_ITEM *it) + { + int r; + BIO_printf(out, "-----BEGIN %s-----\n", hdr); + r = B64_write_ASN1(out, val, in, flags, it); + BIO_printf(out, "-----END %s-----\n", hdr); + return r; + } + static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) { BIO *b64; @@ -152,7 +201,8 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) { - int i, have_unknown = 0, write_comma, md_nid; + const EVP_MD *md; + int i, have_unknown = 0, write_comma, ret = 0, md_nid; have_unknown = 0; write_comma = 0; for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) @@ -161,6 +211,21 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) BIO_write(out, ",", 1); write_comma = 1; md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); + md = EVP_get_digestbynid(md_nid); + if (md && md->md_ctrl) + { + int rv; + char *micstr; + rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr); + if (rv > 0) + { + BIO_puts(out, micstr); + OPENSSL_free(micstr); + continue; + } + if (rv != -2) + goto err; + } switch(md_nid) { case NID_sha1: @@ -183,6 +248,11 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) BIO_puts(out, "sha-512"); break; + case NID_id_GostR3411_94: + BIO_puts(out, "gostr3411-94"); + goto err; + break; + default: if (have_unknown) write_comma = 0; @@ -196,16 +266,18 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) } } - return 1; + ret = 1; + err: + + return ret; } /* SMIME sender */ -int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, int ctype_nid, int econt_nid, STACK_OF(X509_ALGOR) *mdalgs, - asn1_output_data_fn *data_fn, const ASN1_ITEM *it) { char bound[33], c; @@ -243,7 +315,7 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, mime_eol, mime_eol); /* Now write out the first part */ BIO_printf(bio, "------%s%s", bound, mime_eol); - if (!data_fn(bio, data, val, flags, it)) + if (!asn1_output_data(bio, data, val, flags, it)) return 0; BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); @@ -296,8 +368,6 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, return 1; } -#if 0 - /* Handle output of ASN1 data */ @@ -350,8 +420,6 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, } -#endif - /* SMIME reader: handle multipart/signed and opaque signing. * in multipart case the content is placed in a memory BIO * pointed to by "bcont". In opaque this is set to NULL diff --git a/crypto/openssl/crypto/asn1/asn_pack.c b/crypto/openssl/crypto/asn1/asn_pack.c index f1a5a05632..ad738217d7 100644 --- a/crypto/openssl/crypto/asn1/asn_pack.c +++ b/crypto/openssl/crypto/asn1/asn_pack.c @@ -66,10 +66,10 @@ /* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ -STACK *ASN1_seq_unpack(const unsigned char *buf, int len, - d2i_of_void *d2i,void (*free_func)(void *)) +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK)) { - STACK *sk; + STACK_OF(OPENSSL_BLOCK) *sk; const unsigned char *pbuf; pbuf = buf; if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, @@ -82,7 +82,7 @@ STACK *ASN1_seq_unpack(const unsigned char *buf, int len, * OPENSSL_malloc'ed buffer */ -unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d, +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, unsigned char **buf, int *len) { int safelen; diff --git a/crypto/openssl/crypto/asn1/bio_asn1.c b/crypto/openssl/crypto/asn1/bio_asn1.c new file mode 100644 index 0000000000..dc7efd551c --- /dev/null +++ b/crypto/openssl/crypto/asn1/bio_asn1.c @@ -0,0 +1,495 @@ +/* bio_asn1.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2006 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). + * + */ + +/* Experimental ASN1 BIO. When written through the data is converted + * to an ASN1 string type: default is OCTET STRING. Additional functions + * can be provided to add prefix and suffix data. + */ + +#include +#include +#include + +/* Must be large enough for biggest tag+length */ +#define DEFAULT_ASN1_BUF_SIZE 20 + +typedef enum + { + ASN1_STATE_START, + ASN1_STATE_PRE_COPY, + ASN1_STATE_HEADER, + ASN1_STATE_HEADER_COPY, + ASN1_STATE_DATA_COPY, + ASN1_STATE_POST_COPY, + ASN1_STATE_DONE + } asn1_bio_state_t; + +typedef struct BIO_ASN1_EX_FUNCS_st + { + asn1_ps_func *ex_func; + asn1_ps_func *ex_free_func; + } BIO_ASN1_EX_FUNCS; + +typedef struct BIO_ASN1_BUF_CTX_t + { + /* Internal state */ + asn1_bio_state_t state; + /* Internal buffer */ + unsigned char *buf; + /* Size of buffer */ + int bufsize; + /* Current position in buffer */ + int bufpos; + /* Current buffer length */ + int buflen; + /* Amount of data to copy */ + int copylen; + /* Class and tag to use */ + int asn1_class, asn1_tag; + asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free; + /* Extra buffer for prefix and suffix data */ + unsigned char *ex_buf; + int ex_len; + int ex_pos; + void *ex_arg; + } BIO_ASN1_BUF_CTX; + + +static int asn1_bio_write(BIO *h, const char *buf,int num); +static int asn1_bio_read(BIO *h, char *buf, int size); +static int asn1_bio_puts(BIO *h, const char *str); +static int asn1_bio_gets(BIO *h, char *str, int size); +static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int asn1_bio_new(BIO *h); +static int asn1_bio_free(BIO *data); +static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size); +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *cleanup, asn1_bio_state_t next); +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *setup, + asn1_bio_state_t ex_state, + asn1_bio_state_t other_state); + +static BIO_METHOD methods_asn1= + { + BIO_TYPE_ASN1, + "asn1", + asn1_bio_write, + asn1_bio_read, + asn1_bio_puts, + asn1_bio_gets, + asn1_bio_ctrl, + asn1_bio_new, + asn1_bio_free, + asn1_bio_callback_ctrl, + }; + +BIO_METHOD *BIO_f_asn1(void) + { + return(&methods_asn1); + } + + +static int asn1_bio_new(BIO *b) + { + BIO_ASN1_BUF_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX)); + if (!ctx) + return 0; + if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) + return 0; + b->init = 1; + b->ptr = (char *)ctx; + b->flags = 0; + return 1; + } + +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) + { + ctx->buf = OPENSSL_malloc(size); + if (!ctx->buf) + return 0; + ctx->bufsize = size; + ctx->bufpos = 0; + ctx->buflen = 0; + ctx->copylen = 0; + ctx->asn1_class = V_ASN1_UNIVERSAL; + ctx->asn1_tag = V_ASN1_OCTET_STRING; + ctx->ex_buf = 0; + ctx->ex_pos = 0; + ctx->ex_len = 0; + ctx->state = ASN1_STATE_START; + return 1; + } + +static int asn1_bio_free(BIO *b) + { + BIO_ASN1_BUF_CTX *ctx; + ctx = (BIO_ASN1_BUF_CTX *) b->ptr; + if (ctx == NULL) + return 0; + if (ctx->buf) + OPENSSL_free(ctx->buf); + OPENSSL_free(ctx); + b->init = 0; + b->ptr = NULL; + b->flags = 0; + return 1; + } + +static int asn1_bio_write(BIO *b, const char *in , int inl) + { + BIO_ASN1_BUF_CTX *ctx; + int wrmax, wrlen, ret; + unsigned char *p; + if (!in || (inl < 0) || (b->next_bio == NULL)) + return 0; + ctx = (BIO_ASN1_BUF_CTX *) b->ptr; + if (ctx == NULL) + return 0; + + wrlen = 0; + ret = -1; + + for(;;) + { + switch (ctx->state) + { + + /* Setup prefix data, call it */ + case ASN1_STATE_START: + if (!asn1_bio_setup_ex(b, ctx, ctx->prefix, + ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER)) + return 0; + break; + + /* Copy any pre data first */ + case ASN1_STATE_PRE_COPY: + + ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free, + ASN1_STATE_HEADER); + + if (ret <= 0) + goto done; + + break; + + case ASN1_STATE_HEADER: + ctx->buflen = + ASN1_object_size(0, inl, ctx->asn1_tag) - inl; + OPENSSL_assert(ctx->buflen <= ctx->bufsize); + p = ctx->buf; + ASN1_put_object(&p, 0, inl, + ctx->asn1_tag, ctx->asn1_class); + ctx->copylen = inl; + ctx->state = ASN1_STATE_HEADER_COPY; + + break; + + case ASN1_STATE_HEADER_COPY: + ret = BIO_write(b->next_bio, + ctx->buf + ctx->bufpos, ctx->buflen); + if (ret <= 0) + goto done; + + ctx->buflen -= ret; + if (ctx->buflen) + ctx->bufpos += ret; + else + { + ctx->bufpos = 0; + ctx->state = ASN1_STATE_DATA_COPY; + } + + break; + + case ASN1_STATE_DATA_COPY: + + if (inl > ctx->copylen) + wrmax = ctx->copylen; + else + wrmax = inl; + ret = BIO_write(b->next_bio, in, wrmax); + if (ret <= 0) + break; + wrlen += ret; + ctx->copylen -= ret; + in += ret; + inl -= ret; + + if (ctx->copylen == 0) + ctx->state = ASN1_STATE_HEADER; + + if (inl == 0) + goto done; + + break; + + default: + BIO_clear_retry_flags(b); + return 0; + + } + + } + + done: + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + + return (wrlen > 0) ? wrlen : ret; + + } + +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *cleanup, asn1_bio_state_t next) + { + int ret; + if (ctx->ex_len <= 0) + return 1; + for(;;) + { + ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, + ctx->ex_len); + if (ret <= 0) + break; + ctx->ex_len -= ret; + if (ctx->ex_len > 0) + ctx->ex_pos += ret; + else + { + if(cleanup) + cleanup(b, &ctx->ex_buf, &ctx->ex_len, + &ctx->ex_arg); + ctx->state = next; + ctx->ex_pos = 0; + break; + } + } + return ret; + } + +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *setup, + asn1_bio_state_t ex_state, + asn1_bio_state_t other_state) + { + if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) + { + BIO_clear_retry_flags(b); + return 0; + } + if (ctx->ex_len > 0) + ctx->state = ex_state; + else + ctx->state = other_state; + return 1; + } + +static int asn1_bio_read(BIO *b, char *in , int inl) + { + if (!b->next_bio) + return 0; + return BIO_read(b->next_bio, in , inl); + } + +static int asn1_bio_puts(BIO *b, const char *str) + { + return asn1_bio_write(b, str, strlen(str)); + } + +static int asn1_bio_gets(BIO *b, char *str, int size) + { + if (!b->next_bio) + return 0; + return BIO_gets(b->next_bio, str , size); + } + +static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) + { + if (b->next_bio == NULL) return(0); + return BIO_callback_ctrl(b->next_bio,cmd,fp); + } + +static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2) + { + BIO_ASN1_BUF_CTX *ctx; + BIO_ASN1_EX_FUNCS *ex_func; + long ret = 1; + ctx = (BIO_ASN1_BUF_CTX *) b->ptr; + if (ctx == NULL) + return 0; + switch(cmd) + { + + case BIO_C_SET_PREFIX: + ex_func = arg2; + ctx->prefix = ex_func->ex_func; + ctx->prefix_free = ex_func->ex_free_func; + break; + + case BIO_C_GET_PREFIX: + ex_func = arg2; + ex_func->ex_func = ctx->prefix; + ex_func->ex_free_func = ctx->prefix_free; + break; + + case BIO_C_SET_SUFFIX: + ex_func = arg2; + ctx->suffix = ex_func->ex_func; + ctx->suffix_free = ex_func->ex_free_func; + break; + + case BIO_C_GET_SUFFIX: + ex_func = arg2; + ex_func->ex_func = ctx->suffix; + ex_func->ex_free_func = ctx->suffix_free; + break; + + case BIO_C_SET_EX_ARG: + ctx->ex_arg = arg2; + break; + + case BIO_C_GET_EX_ARG: + *(void **)arg2 = ctx->ex_arg; + break; + + case BIO_CTRL_FLUSH: + if (!b->next_bio) + return 0; + + /* Call post function if possible */ + if (ctx->state == ASN1_STATE_HEADER) + { + if (!asn1_bio_setup_ex(b, ctx, ctx->suffix, + ASN1_STATE_POST_COPY, ASN1_STATE_DONE)) + return 0; + } + + if (ctx->state == ASN1_STATE_POST_COPY) + { + ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free, + ASN1_STATE_DONE); + if (ret <= 0) + return ret; + } + + if (ctx->state == ASN1_STATE_DONE) + return BIO_ctrl(b->next_bio, cmd, arg1, arg2); + else + { + BIO_clear_retry_flags(b); + return 0; + } + break; + + + default: + if (!b->next_bio) + return 0; + return BIO_ctrl(b->next_bio, cmd, arg1, arg2); + + } + + return ret; + } + +static int asn1_bio_set_ex(BIO *b, int cmd, + asn1_ps_func *ex_func, asn1_ps_func *ex_free_func) + { + BIO_ASN1_EX_FUNCS extmp; + extmp.ex_func = ex_func; + extmp.ex_free_func = ex_free_func; + return BIO_ctrl(b, cmd, 0, &extmp); + } + +static int asn1_bio_get_ex(BIO *b, int cmd, + asn1_ps_func **ex_func, asn1_ps_func **ex_free_func) + { + BIO_ASN1_EX_FUNCS extmp; + int ret; + ret = BIO_ctrl(b, cmd, 0, &extmp); + if (ret > 0) + { + *ex_func = extmp.ex_func; + *ex_free_func = extmp.ex_free_func; + } + return ret; + } + +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free) + { + return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free); + } + +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free) + { + return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free); + } + +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free) + { + return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free); + } + +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free) + { + return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free); + } diff --git a/crypto/openssl/crypto/asn1/bio_ndef.c b/crypto/openssl/crypto/asn1/bio_ndef.c new file mode 100644 index 0000000000..370389b1e6 --- /dev/null +++ b/crypto/openssl/crypto/asn1/bio_ndef.c @@ -0,0 +1,246 @@ +/* bio_ndef.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 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. + * ==================================================================== + * + */ + +#include +#include +#include +#include + +#ifndef OPENSSL_SYSNAME_NETWARE +#include +#endif +#include + +/* Experimental NDEF ASN1 BIO support routines */ + +/* The usage is quite simple, initialize an ASN1 structure, + * get a BIO from it then any data written through the BIO + * will end up translated to approptiate format on the fly. + * The data is streamed out and does *not* need to be + * all held in memory at once. + * + * When the BIO is flushed the output is finalized and any + * signatures etc written out. + * + * The BIO is a 'proper' BIO and can handle non blocking I/O + * correctly. + * + * The usage is simple. The implementation is *not*... + */ + +/* BIO support data stored in the ASN1 BIO ex_arg */ + +typedef struct ndef_aux_st + { + /* ASN1 structure this BIO refers to */ + ASN1_VALUE *val; + const ASN1_ITEM *it; + /* Top of the BIO chain */ + BIO *ndef_bio; + /* Output BIO */ + BIO *out; + /* Boundary where content is inserted */ + unsigned char **boundary; + /* DER buffer start */ + unsigned char *derbuf; + } NDEF_SUPPORT; + +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) + { + NDEF_SUPPORT *ndef_aux = NULL; + BIO *asn_bio = NULL; + const ASN1_AUX *aux = it->funcs; + ASN1_STREAM_ARG sarg; + + if (!aux || !aux->asn1_cb) + { + ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); + return NULL; + } + ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT)); + asn_bio = BIO_new(BIO_f_asn1()); + + /* ASN1 bio needs to be next to output BIO */ + + out = BIO_push(asn_bio, out); + + if (!ndef_aux || !asn_bio || !out) + goto err; + + BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); + BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); + + /* Now let callback prepend any digest, cipher etc BIOs + * ASN1 structure needs. + */ + + sarg.out = out; + sarg.ndef_bio = NULL; + sarg.boundary = NULL; + + if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) + goto err; + + ndef_aux->val = val; + ndef_aux->it = it; + ndef_aux->ndef_bio = sarg.ndef_bio; + ndef_aux->boundary = sarg.boundary; + ndef_aux->out = out; + + BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); + + return sarg.ndef_bio; + + err: + if (asn_bio) + BIO_free(asn_bio); + if (ndef_aux) + OPENSSL_free(ndef_aux); + return NULL; + } + +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) + { + NDEF_SUPPORT *ndef_aux; + unsigned char *p; + int derlen; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + p = OPENSSL_malloc(derlen); + ndef_aux->derbuf = p; + *pbuf = p; + derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + + if (!*ndef_aux->boundary) + return 0; + + *plen = *ndef_aux->boundary - *pbuf; + + return 1; + } + +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg) + { + NDEF_SUPPORT *ndef_aux; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + if (ndef_aux->derbuf) + OPENSSL_free(ndef_aux->derbuf); + + ndef_aux->derbuf = NULL; + *pbuf = NULL; + *plen = 0; + return 1; + } + +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg) + { + NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg; + if (!ndef_prefix_free(b, pbuf, plen, parg)) + return 0; + OPENSSL_free(*pndef_aux); + *pndef_aux = NULL; + return 1; + } + +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) + { + NDEF_SUPPORT *ndef_aux; + unsigned char *p; + int derlen; + const ASN1_AUX *aux; + ASN1_STREAM_ARG sarg; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + aux = ndef_aux->it->funcs; + + /* Finalize structures */ + sarg.ndef_bio = ndef_aux->ndef_bio; + sarg.out = ndef_aux->out; + sarg.boundary = ndef_aux->boundary; + if (aux->asn1_cb(ASN1_OP_STREAM_POST, + &ndef_aux->val, ndef_aux->it, &sarg) <= 0) + return 0; + + derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + p = OPENSSL_malloc(derlen); + ndef_aux->derbuf = p; + *pbuf = p; + derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + + if (!*ndef_aux->boundary) + return 0; + *pbuf = *ndef_aux->boundary; + *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf); + + return 1; + } diff --git a/crypto/openssl/crypto/asn1/charmap.h b/crypto/openssl/crypto/asn1/charmap.h index bd020a9562..b55e638725 100644 --- a/crypto/openssl/crypto/asn1/charmap.h +++ b/crypto/openssl/crypto/asn1/charmap.h @@ -2,7 +2,7 @@ * Mask of various character properties */ -static unsigned char char_type[] = { +static const unsigned char char_type[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16, diff --git a/crypto/openssl/crypto/asn1/d2i_pr.c b/crypto/openssl/crypto/asn1/d2i_pr.c index 207ccda5ac..2828944777 100644 --- a/crypto/openssl/crypto/asn1/d2i_pr.c +++ b/crypto/openssl/crypto/asn1/d2i_pr.c @@ -61,16 +61,12 @@ #include #include #include -#include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_EC -#include +#ifndef OPENSSL_NO_ENGINE +#include #endif +#include +#include +#include "asn1_locl.h" EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) @@ -85,47 +81,43 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, return(NULL); } } - else ret= *a; - - ret->save_type=type; - ret->type=EVP_PKEY_type(type); - switch (ret->type) + else { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - if ((ret->pkey.rsa=d2i_RSAPrivateKey(NULL, - (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */ + ret= *a; +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) { - ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); - goto err; + ENGINE_finish(ret->engine); + ret->engine = NULL; } - break; #endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - if ((ret->pkey.dsa=d2i_DSAPrivateKey(NULL, - (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */ + } + + if (!EVP_PKEY_set_type(ret, type)) + { + ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + + if (!ret->ameth->old_priv_decode || + !ret->ameth->old_priv_decode(ret, pp, length)) + { + if (ret->ameth->priv_decode) { - ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); - goto err; - } - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - if ((ret->pkey.ec = d2i_ECPrivateKey(NULL, - (const unsigned char **)pp, length)) == NULL) + PKCS8_PRIV_KEY_INFO *p8=NULL; + p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length); + if (!p8) goto err; + EVP_PKEY_free(ret); + ret = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + + } + else { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); + ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); goto err; } - break; -#endif - default: - ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); - goto err; - /* break; */ - } + } if (a != NULL) (*a)=ret; return(ret); err: @@ -146,8 +138,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, * by analyzing it we can determine the passed structure: this * assumes the input is surrounded by an ASN1 SEQUENCE. */ - inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE, - ASN1_TYPE_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); /* Since we only need to discern "traditional format" RSA and DSA * keys we can just count the elements. */ @@ -155,6 +146,24 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, keytype = EVP_PKEY_DSA; else if (sk_ASN1_TYPE_num(inkey) == 4) keytype = EVP_PKEY_EC; + else if (sk_ASN1_TYPE_num(inkey) == 3) + { /* This seems to be PKCS8, not traditional format */ + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length); + EVP_PKEY *ret; + + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + if (!p8) + { + ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } + ret = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (a) { + *a = ret; + } + return ret; + } else keytype = EVP_PKEY_RSA; sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); return d2i_PrivateKey(keytype, a, pp, length); diff --git a/crypto/openssl/crypto/asn1/d2i_pu.c b/crypto/openssl/crypto/asn1/d2i_pu.c index 3694f51a8c..c8f39ceb03 100644 --- a/crypto/openssl/crypto/asn1/d2i_pu.c +++ b/crypto/openssl/crypto/asn1/d2i_pu.c @@ -87,9 +87,13 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, } else ret= *a; - ret->save_type=type; - ret->type=EVP_PKEY_type(type); - switch (ret->type) + if (!EVP_PKEY_set_type(ret, type)) + { + ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB); + goto err; + } + + switch (EVP_PKEY_id(ret)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: diff --git a/crypto/openssl/crypto/asn1/i2d_pr.c b/crypto/openssl/crypto/asn1/i2d_pr.c index 0be52c5b76..e398b62666 100644 --- a/crypto/openssl/crypto/asn1/i2d_pr.c +++ b/crypto/openssl/crypto/asn1/i2d_pr.c @@ -58,41 +58,22 @@ #include #include "cryptlib.h" -#include #include -#include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_EC -#include -#endif +#include +#include "asn1_locl.h" int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) { -#ifndef OPENSSL_NO_RSA - if (a->type == EVP_PKEY_RSA) + if (a->ameth && a->ameth->old_priv_encode) { - return(i2d_RSAPrivateKey(a->pkey.rsa,pp)); + return a->ameth->old_priv_encode(a, pp); } - else -#endif -#ifndef OPENSSL_NO_DSA - if (a->type == EVP_PKEY_DSA) - { - return(i2d_DSAPrivateKey(a->pkey.dsa,pp)); - } -#endif -#ifndef OPENSSL_NO_EC - if (a->type == EVP_PKEY_EC) - { - return(i2d_ECPrivateKey(a->pkey.ec, pp)); - } -#endif - + if (a->ameth && a->ameth->priv_encode) { + PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); + int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp); + PKCS8_PRIV_KEY_INFO_free(p8); + return ret; + } ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return(-1); } diff --git a/crypto/openssl/crypto/asn1/nsseq.c b/crypto/openssl/crypto/asn1/nsseq.c index e551c57d59..b8c4202230 100644 --- a/crypto/openssl/crypto/asn1/nsseq.c +++ b/crypto/openssl/crypto/asn1/nsseq.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -62,7 +62,8 @@ #include #include -static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_NEW_POST) { NETSCAPE_CERT_SEQUENCE *nsseq; diff --git a/crypto/openssl/crypto/asn1/p5_pbe.c b/crypto/openssl/crypto/asn1/p5_pbe.c index c4582f8041..94bc38b99f 100644 --- a/crypto/openssl/crypto/asn1/p5_pbe.c +++ b/crypto/openssl/crypto/asn1/p5_pbe.c @@ -71,61 +71,78 @@ ASN1_SEQUENCE(PBEPARAM) = { IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) -/* Return an algorithm identifier for a PKCS#5 PBE algorithm */ -X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, - int saltlen) -{ +/* Set an algorithm identifier for a PKCS#5 PBE algorithm */ + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen) + { PBEPARAM *pbe=NULL; - ASN1_OBJECT *al; - X509_ALGOR *algor; - ASN1_TYPE *astype=NULL; + ASN1_STRING *pbe_str=NULL; + unsigned char *sstr; - if (!(pbe = PBEPARAM_new ())) { - ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); + pbe = PBEPARAM_new(); + if (!pbe) + { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; - } - if(iter <= 0) iter = PKCS5_DEFAULT_ITER; - if (!ASN1_INTEGER_set(pbe->iter, iter)) { - ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); + } + if(iter <= 0) + iter = PKCS5_DEFAULT_ITER; + if (!ASN1_INTEGER_set(pbe->iter, iter)) + { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; - } - if (!saltlen) saltlen = PKCS5_SALT_LEN; - if (!(pbe->salt->data = OPENSSL_malloc (saltlen))) { - ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); + } + if (!saltlen) + saltlen = PKCS5_SALT_LEN; + if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) + { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; - } - pbe->salt->length = saltlen; - if (salt) memcpy (pbe->salt->data, salt, saltlen); - else if (RAND_pseudo_bytes (pbe->salt->data, saltlen) < 0) + } + sstr = ASN1_STRING_data(pbe->salt); + if (salt) + memcpy(sstr, salt, saltlen); + else if (RAND_pseudo_bytes(sstr, saltlen) < 0) goto err; - if (!(astype = ASN1_TYPE_new())) { - ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); + if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) + { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; - } + } - astype->type = V_ASN1_SEQUENCE; - if(!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM, - &astype->value.sequence)) { - ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); - goto err; - } - PBEPARAM_free (pbe); + PBEPARAM_free(pbe); pbe = NULL; - - al = OBJ_nid2obj(alg); /* never need to free al */ - if (!(algor = X509_ALGOR_new())) { - ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); - goto err; - } - ASN1_OBJECT_free(algor->algorithm); - algor->algorithm = al; - algor->parameter = astype; - return (algor); + if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) + return 1; + err: - if (pbe != NULL) PBEPARAM_free(pbe); - if (astype != NULL) ASN1_TYPE_free(astype); + if (pbe != NULL) + PBEPARAM_free(pbe); + if (pbe_str != NULL) + ASN1_STRING_free(pbe_str); + return 0; + } + +/* Return an algorithm identifier for a PKCS#5 PBE algorithm */ + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen) + { + X509_ALGOR *ret; + ret = X509_ALGOR_new(); + if (!ret) + { + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) + return ret; + + X509_ALGOR_free(ret); return NULL; -} + } diff --git a/crypto/openssl/crypto/asn1/p5_pbev2.c b/crypto/openssl/crypto/asn1/p5_pbev2.c index 2b0516afee..cb49b6651d 100644 --- a/crypto/openssl/crypto/asn1/p5_pbev2.c +++ b/crypto/openssl/crypto/asn1/p5_pbev2.c @@ -82,10 +82,13 @@ IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) /* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: * yes I know this is horrible! + * + * Extended version to allow application supplied PRF NID and IV. */ -X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen) +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid; @@ -98,7 +101,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, alg_nid = EVP_CIPHER_type(cipher); if(alg_nid == NID_undef) { - ASN1err(ASN1_F_PKCS5_PBE2_SET, + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } @@ -113,20 +116,33 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; /* Create random IV */ - if (EVP_CIPHER_iv_length(cipher) && - RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) - goto err; + if (EVP_CIPHER_iv_length(cipher)) + { + if (aiv) + memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); + else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) + goto err; + } EVP_CIPHER_CTX_init(&ctx); - /* Dummy cipherinit to just setup the IV */ + /* Dummy cipherinit to just setup the IV, and PRF */ EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0); if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { - ASN1err(ASN1_F_PKCS5_PBE2_SET, + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } + /* If prf NID unspecified see if cipher has a preference. + * An error is OK here: just means use default PRF. + */ + if ((prf_nid == -1) && + EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) + { + ERR_clear_error(); + prf_nid = NID_hmacWithSHA1; + } EVP_CIPHER_CTX_cleanup(&ctx); if(!(kdf = PBKDF2PARAM_new())) goto merr; @@ -154,7 +170,15 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, EVP_CIPHER_key_length(cipher))) goto merr; } - /* prf can stay NULL because we are using hmacWithSHA1 */ + /* prf can stay NULL if we are using hmacWithSHA1 */ + if (prf_nid != NID_hmacWithSHA1) + { + kdf->prf = X509_ALGOR_new(); + if (!kdf->prf) + goto merr; + X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), + V_ASN1_NULL, NULL); + } /* Now setup the PBE2PARAM keyfunc structure */ @@ -164,7 +188,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; - if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM, + if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM), &pbe2->keyfunc->parameter->value.sequence)) goto merr; pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; @@ -180,7 +204,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, /* Encode PBE2PARAM into parameter */ - if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM, + if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; @@ -190,7 +214,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, return ret; merr: - ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); @@ -203,3 +227,9 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, return NULL; } + +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen) + { + return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1); + } diff --git a/crypto/openssl/crypto/asn1/p8_pkey.c b/crypto/openssl/crypto/asn1/p8_pkey.c index 0a1957556e..17b68d386d 100644 --- a/crypto/openssl/crypto/asn1/p8_pkey.c +++ b/crypto/openssl/crypto/asn1/p8_pkey.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -62,7 +62,8 @@ #include /* Minor tweak to operation: zero private key data */ -static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { /* Since the structure must still be valid use ASN1_OP_FREE_PRE */ if(operation == ASN1_OP_FREE_PRE) { @@ -82,3 +83,73 @@ ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { } ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, + int ptype, void *pval, + unsigned char *penc, int penclen) + { + unsigned char **ppenc = NULL; + if (version >= 0) + { + if (!ASN1_INTEGER_set(priv->version, version)) + return 0; + } + if (penc) + { + int pmtype; + ASN1_OCTET_STRING *oct; + oct = ASN1_OCTET_STRING_new(); + if (!oct) + return 0; + oct->data = penc; + ppenc = &oct->data; + oct->length = penclen; + if (priv->broken == PKCS8_NO_OCTET) + pmtype = V_ASN1_SEQUENCE; + else + pmtype = V_ASN1_OCTET_STRING; + ASN1_TYPE_set(priv->pkey, pmtype, oct); + } + if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) + { + /* If call fails do not swallow 'enc' */ + if (ppenc) + *ppenc = NULL; + return 0; + } + return 1; + } + +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + PKCS8_PRIV_KEY_INFO *p8) + { + if (ppkalg) + *ppkalg = p8->pkeyalg->algorithm; + if(p8->pkey->type == V_ASN1_OCTET_STRING) + { + p8->broken = PKCS8_OK; + if (pk) + { + *pk = p8->pkey->value.octet_string->data; + *ppklen = p8->pkey->value.octet_string->length; + } + } + else if (p8->pkey->type == V_ASN1_SEQUENCE) + { + p8->broken = PKCS8_NO_OCTET; + if (pk) + { + *pk = p8->pkey->value.sequence->data; + *ppklen = p8->pkey->value.sequence->length; + } + } + else + return 0; + if (pa) + *pa = p8->pkeyalg; + return 1; + } + diff --git a/crypto/openssl/crypto/asn1/t_pkey.c b/crypto/openssl/crypto/asn1/t_pkey.c index afb95d6712..9dd18f6579 100644 --- a/crypto/openssl/crypto/asn1/t_pkey.c +++ b/crypto/openssl/crypto/asn1/t_pkey.c @@ -55,520 +55,15 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Binary polynomial ECC support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ #include #include "cryptlib.h" #include #include #include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_DH -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_EC -#include -#endif - -static int print(BIO *fp,const char *str, const BIGNUM *num, - unsigned char *buf,int off); -#ifndef OPENSSL_NO_EC -static int print_bin(BIO *fp, const char *str, const unsigned char *num, - size_t len, int off); -#endif -#ifndef OPENSSL_NO_RSA -#ifndef OPENSSL_NO_FP_API -int RSA_print_fp(FILE *fp, const RSA *x, int off) - { - BIO *b; - int ret; - - if ((b=BIO_new(BIO_s_file())) == NULL) - { - RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB); - return(0); - } - BIO_set_fp(b,fp,BIO_NOCLOSE); - ret=RSA_print(b,x,off); - BIO_free(b); - return(ret); - } -#endif - -int RSA_print(BIO *bp, const RSA *x, int off) - { - char str[128]; - const char *s; - unsigned char *m=NULL; - int ret=0, mod_len = 0; - size_t buf_len=0, i; - - if (x->n) - buf_len = (size_t)BN_num_bytes(x->n); - if (x->e) - if (buf_len < (i = (size_t)BN_num_bytes(x->e))) - buf_len = i; - if (x->d) - if (buf_len < (i = (size_t)BN_num_bytes(x->d))) - buf_len = i; - if (x->p) - if (buf_len < (i = (size_t)BN_num_bytes(x->p))) - buf_len = i; - if (x->q) - if (buf_len < (i = (size_t)BN_num_bytes(x->q))) - buf_len = i; - if (x->dmp1) - if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1))) - buf_len = i; - if (x->dmq1) - if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1))) - buf_len = i; - if (x->iqmp) - if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp))) - buf_len = i; - - m=(unsigned char *)OPENSSL_malloc(buf_len+10); - if (m == NULL) - { - RSAerr(RSA_F_RSA_PRINT,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (x->n != NULL) - mod_len = BN_num_bits(x->n); - - if (x->d != NULL) - { - if(!BIO_indent(bp,off,128)) - goto err; - if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len) - <= 0) goto err; - } - - if (x->d == NULL) - BIO_snprintf(str,sizeof str,"Modulus (%d bit):", mod_len); - else - BUF_strlcpy(str,"modulus:",sizeof str); - if (!print(bp,str,x->n,m,off)) goto err; - s=(x->d == NULL)?"Exponent:":"publicExponent:"; - if ((x->e != NULL) && !print(bp,s,x->e,m,off)) - goto err; - if ((x->d != NULL) && !print(bp,"privateExponent:",x->d,m,off)) - goto err; - if ((x->p != NULL) && !print(bp,"prime1:",x->p,m,off)) - goto err; - if ((x->q != NULL) && !print(bp,"prime2:",x->q,m,off)) - goto err; - if ((x->dmp1 != NULL) && !print(bp,"exponent1:",x->dmp1,m,off)) - goto err; - if ((x->dmq1 != NULL) && !print(bp,"exponent2:",x->dmq1,m,off)) - goto err; - if ((x->iqmp != NULL) && !print(bp,"coefficient:",x->iqmp,m,off)) - goto err; - ret=1; -err: - if (m != NULL) OPENSSL_free(m); - return(ret); - } -#endif /* OPENSSL_NO_RSA */ - -#ifndef OPENSSL_NO_DSA -#ifndef OPENSSL_NO_FP_API -int DSA_print_fp(FILE *fp, const DSA *x, int off) - { - BIO *b; - int ret; - - if ((b=BIO_new(BIO_s_file())) == NULL) - { - DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB); - return(0); - } - BIO_set_fp(b,fp,BIO_NOCLOSE); - ret=DSA_print(b,x,off); - BIO_free(b); - return(ret); - } -#endif - -int DSA_print(BIO *bp, const DSA *x, int off) - { - unsigned char *m=NULL; - int ret=0; - size_t buf_len=0,i; - - if (x->p) - buf_len = (size_t)BN_num_bytes(x->p); - else - { - DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS); - goto err; - } - if (x->q) - if (buf_len < (i = (size_t)BN_num_bytes(x->q))) - buf_len = i; - if (x->g) - if (buf_len < (i = (size_t)BN_num_bytes(x->g))) - buf_len = i; - if (x->priv_key) - if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key))) - buf_len = i; - if (x->pub_key) - if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key))) - buf_len = i; - - m=(unsigned char *)OPENSSL_malloc(buf_len+10); - if (m == NULL) - { - DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (x->priv_key != NULL) - { - if(!BIO_indent(bp,off,128)) - goto err; - if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->p)) - <= 0) goto err; - } - - if ((x->priv_key != NULL) && !print(bp,"priv:",x->priv_key,m,off)) - goto err; - if ((x->pub_key != NULL) && !print(bp,"pub: ",x->pub_key,m,off)) - goto err; - if ((x->p != NULL) && !print(bp,"P: ",x->p,m,off)) goto err; - if ((x->q != NULL) && !print(bp,"Q: ",x->q,m,off)) goto err; - if ((x->g != NULL) && !print(bp,"G: ",x->g,m,off)) goto err; - ret=1; -err: - if (m != NULL) OPENSSL_free(m); - return(ret); - } -#endif /* !OPENSSL_NO_DSA */ - -#ifndef OPENSSL_NO_EC -#ifndef OPENSSL_NO_FP_API -int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) - { - BIO *b; - int ret; - - if ((b=BIO_new(BIO_s_file())) == NULL) - { - ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB); - return(0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = ECPKParameters_print(b, x, off); - BIO_free(b); - return(ret); - } - -int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) - { - BIO *b; - int ret; - - if ((b=BIO_new(BIO_s_file())) == NULL) - { - ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); - return(0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = EC_KEY_print(b, x, off); - BIO_free(b); - return(ret); - } -#endif - -int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) - { - unsigned char *buffer=NULL; - size_t buf_len=0, i; - int ret=0, reason=ERR_R_BIO_LIB; - BN_CTX *ctx=NULL; - const EC_POINT *point=NULL; - BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL, - *order=NULL, *cofactor=NULL; - const unsigned char *seed; - size_t seed_len=0; - - static const char *gen_compressed = "Generator (compressed):"; - static const char *gen_uncompressed = "Generator (uncompressed):"; - static const char *gen_hybrid = "Generator (hybrid):"; - - if (!x) - { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - if (EC_GROUP_get_asn1_flag(x)) - { - /* the curve parameter are given by an asn1 OID */ - int nid; - - if (!BIO_indent(bp, off, 128)) - goto err; - - nid = EC_GROUP_get_curve_name(x); - if (nid == 0) - goto err; - - if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) - goto err; - if (BIO_printf(bp, "\n") <= 0) - goto err; - } - else - { - /* explicit parameters */ - int is_char_two = 0; - point_conversion_form_t form; - int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); - - if (tmp_nid == NID_X9_62_characteristic_two_field) - is_char_two = 1; - - if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || - (b = BN_new()) == NULL || (order = BN_new()) == NULL || - (cofactor = BN_new()) == NULL) - { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (is_char_two) - { - if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) - { - reason = ERR_R_EC_LIB; - goto err; - } - } - else /* prime field */ - { - if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) - { - reason = ERR_R_EC_LIB; - goto err; - } - } - - if ((point = EC_GROUP_get0_generator(x)) == NULL) - { - reason = ERR_R_EC_LIB; - goto err; - } - if (!EC_GROUP_get_order(x, order, NULL) || - !EC_GROUP_get_cofactor(x, cofactor, NULL)) - { - reason = ERR_R_EC_LIB; - goto err; - } - - form = EC_GROUP_get_point_conversion_form(x); - - if ((gen = EC_POINT_point2bn(x, point, - form, NULL, ctx)) == NULL) - { - reason = ERR_R_EC_LIB; - goto err; - } - - buf_len = (size_t)BN_num_bytes(p); - if (buf_len < (i = (size_t)BN_num_bytes(a))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(b))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(gen))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(order))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) - buf_len = i; - - if ((seed = EC_GROUP_get0_seed(x)) != NULL) - seed_len = EC_GROUP_get_seed_len(x); - - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) - { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (!BIO_indent(bp, off, 128)) - goto err; - - /* print the 'short name' of the field type */ - if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) - <= 0) - goto err; - - if (is_char_two) - { - /* print the 'short name' of the base type OID */ - int basis_type = EC_GROUP_get_basis_type(x); - if (basis_type == 0) - goto err; - - if (!BIO_indent(bp, off, 128)) - goto err; - - if (BIO_printf(bp, "Basis Type: %s\n", - OBJ_nid2sn(basis_type)) <= 0) - goto err; - - /* print the polynomial */ - if ((p != NULL) && !print(bp, "Polynomial:", p, buffer, - off)) - goto err; - } - else - { - if ((p != NULL) && !print(bp, "Prime:", p, buffer,off)) - goto err; - } - if ((a != NULL) && !print(bp, "A: ", a, buffer, off)) - goto err; - if ((b != NULL) && !print(bp, "B: ", b, buffer, off)) - goto err; - if (form == POINT_CONVERSION_COMPRESSED) - { - if ((gen != NULL) && !print(bp, gen_compressed, gen, - buffer, off)) - goto err; - } - else if (form == POINT_CONVERSION_UNCOMPRESSED) - { - if ((gen != NULL) && !print(bp, gen_uncompressed, gen, - buffer, off)) - goto err; - } - else /* form == POINT_CONVERSION_HYBRID */ - { - if ((gen != NULL) && !print(bp, gen_hybrid, gen, - buffer, off)) - goto err; - } - if ((order != NULL) && !print(bp, "Order: ", order, - buffer, off)) goto err; - if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor, - buffer, off)) goto err; - if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) - goto err; - } - ret=1; -err: - if (!ret) - ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); - if (p) - BN_free(p); - if (a) - BN_free(a); - if (b) - BN_free(b); - if (gen) - BN_free(gen); - if (order) - BN_free(order); - if (cofactor) - BN_free(cofactor); - if (ctx) - BN_CTX_free(ctx); - if (buffer != NULL) - OPENSSL_free(buffer); - return(ret); - } -int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) - { - unsigned char *buffer=NULL; - size_t buf_len=0, i; - int ret=0, reason=ERR_R_BIO_LIB; - BIGNUM *pub_key=NULL, *order=NULL; - BN_CTX *ctx=NULL; - const EC_GROUP *group; - const EC_POINT *public_key; - const BIGNUM *priv_key; - - if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) - { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - public_key = EC_KEY_get0_public_key(x); - if ((pub_key = EC_POINT_point2bn(group, public_key, - EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) - { - reason = ERR_R_EC_LIB; - goto err; - } - - buf_len = (size_t)BN_num_bytes(pub_key); - priv_key = EC_KEY_get0_private_key(x); - if (priv_key != NULL) - { - if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len) - buf_len = i; - } - - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) - { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (priv_key != NULL) - { - if (!BIO_indent(bp, off, 128)) - goto err; - if ((order = BN_new()) == NULL) - goto err; - if (!EC_GROUP_get_order(group, order, NULL)) - goto err; - if (BIO_printf(bp, "Private-Key: (%d bit)\n", - BN_num_bits(order)) <= 0) goto err; - } - - if ((priv_key != NULL) && !print(bp, "priv:", priv_key, - buffer, off)) - goto err; - if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, - buffer, off)) - goto err; - if (!ECPKParameters_print(bp, group, off)) - goto err; - ret=1; -err: - if (!ret) - ECerr(EC_F_EC_KEY_PRINT, reason); - if (pub_key) - BN_free(pub_key); - if (order) - BN_free(order); - if (ctx) - BN_CTX_free(ctx); - if (buffer != NULL) - OPENSSL_free(buffer); - return(ret); - } -#endif /* OPENSSL_NO_EC */ - -static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf, - int off) +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off) { int n,i; const char *neg; @@ -617,223 +112,3 @@ static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char * } return(1); } - -#ifndef OPENSSL_NO_EC -static int print_bin(BIO *fp, const char *name, const unsigned char *buf, - size_t len, int off) - { - size_t i; - char str[128]; - - if (buf == NULL) - return 1; - if (off) - { - if (off > 128) - off=128; - memset(str,' ',off); - if (BIO_write(fp, str, off) <= 0) - return 0; - } - - if (BIO_printf(fp,"%s", name) <= 0) - return 0; - - for (i=0; ip) - buf_len = (size_t)BN_num_bytes(x->p); - else - { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - if (x->g) - if (buf_len < (i = (size_t)BN_num_bytes(x->g))) - buf_len = i; - m=(unsigned char *)OPENSSL_malloc(buf_len+10); - if (m == NULL) - { - reason=ERR_R_MALLOC_FAILURE; - goto err; - } - - if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n", - BN_num_bits(x->p)) <= 0) - goto err; - if (!print(bp,"prime:",x->p,m,4)) goto err; - if (!print(bp,"generator:",x->g,m,4)) goto err; - if (x->length != 0) - { - if (BIO_printf(bp," recommended-private-length: %d bits\n", - (int)x->length) <= 0) goto err; - } - ret=1; - if (0) - { -err: - DHerr(DH_F_DHPARAMS_PRINT,reason); - } - if (m != NULL) OPENSSL_free(m); - return(ret); - } -#endif - -#ifndef OPENSSL_NO_DSA -#ifndef OPENSSL_NO_FP_API -int DSAparams_print_fp(FILE *fp, const DSA *x) - { - BIO *b; - int ret; - - if ((b=BIO_new(BIO_s_file())) == NULL) - { - DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB); - return(0); - } - BIO_set_fp(b,fp,BIO_NOCLOSE); - ret=DSAparams_print(b, x); - BIO_free(b); - return(ret); - } -#endif - -int DSAparams_print(BIO *bp, const DSA *x) - { - unsigned char *m=NULL; - int ret=0; - size_t buf_len=0,i; - - if (x->p) - buf_len = (size_t)BN_num_bytes(x->p); - else - { - DSAerr(DSA_F_DSAPARAMS_PRINT,DSA_R_MISSING_PARAMETERS); - goto err; - } - if (x->q) - if (buf_len < (i = (size_t)BN_num_bytes(x->q))) - buf_len = i; - if (x->g) - if (buf_len < (i = (size_t)BN_num_bytes(x->g))) - buf_len = i; - m=(unsigned char *)OPENSSL_malloc(buf_len+10); - if (m == NULL) - { - DSAerr(DSA_F_DSAPARAMS_PRINT,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (BIO_printf(bp,"DSA-Parameters: (%d bit)\n", - BN_num_bits(x->p)) <= 0) - goto err; - if (!print(bp,"p:",x->p,m,4)) goto err; - if ((x->q != NULL) && !print(bp,"q:",x->q,m,4)) goto err; - if ((x->g != NULL) && !print(bp,"g:",x->g,m,4)) goto err; - ret=1; -err: - if (m != NULL) OPENSSL_free(m); - return(ret); - } - -#endif /* !OPENSSL_NO_DSA */ - -#ifndef OPENSSL_NO_EC -#ifndef OPENSSL_NO_FP_API -int ECParameters_print_fp(FILE *fp, const EC_KEY *x) - { - BIO *b; - int ret; - - if ((b=BIO_new(BIO_s_file())) == NULL) - { - ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); - return(0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = ECParameters_print(b, x); - BIO_free(b); - return(ret); - } -#endif - -int ECParameters_print(BIO *bp, const EC_KEY *x) - { - int reason=ERR_R_EC_LIB, ret=0; - BIGNUM *order=NULL; - const EC_GROUP *group; - - if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) - { - reason = ERR_R_PASSED_NULL_PARAMETER;; - goto err; - } - - if ((order = BN_new()) == NULL) - { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (!EC_GROUP_get_order(group, order, NULL)) - { - reason = ERR_R_EC_LIB; - goto err; - } - - if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n", - BN_num_bits(order)) <= 0) - goto err; - if (!ECPKParameters_print(bp, group, 4)) - goto err; - ret=1; -err: - if (order) - BN_free(order); - ECerr(EC_F_ECPARAMETERS_PRINT, reason); - return(ret); - } - -#endif diff --git a/crypto/openssl/crypto/asn1/t_req.c b/crypto/openssl/crypto/asn1/t_req.c index 5557e06584..ea1794e3e0 100644 --- a/crypto/openssl/crypto/asn1/t_req.c +++ b/crypto/openssl/crypto/asn1/t_req.c @@ -149,34 +149,10 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long ERR_print_errors(bp); } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - { - BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","", - BN_num_bits(pkey->pkey.rsa->n)); - RSA_print(bp,pkey->pkey.rsa,16); - } - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - BIO_printf(bp,"%12sDSA Public Key:\n",""); - DSA_print(bp,pkey->pkey.dsa,16); + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); } - else -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) - { - BIO_printf(bp, "%12sEC Public Key: \n",""); - EC_KEY_print(bp, pkey->pkey.ec, 16); - } - else -#endif - BIO_printf(bp,"%12sUnknown Public Key:\n",""); - - EVP_PKEY_free(pkey); } if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) diff --git a/crypto/openssl/crypto/asn1/t_spki.c b/crypto/openssl/crypto/asn1/t_spki.c index a73369b949..079c081a81 100644 --- a/crypto/openssl/crypto/asn1/t_spki.c +++ b/crypto/openssl/crypto/asn1/t_spki.c @@ -82,36 +82,11 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); pkey = X509_PUBKEY_get(spki->spkac->pubkey); if(!pkey) BIO_printf(out, " Unable to load public key\n"); - else { -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - { - BIO_printf(out," RSA Public Key: (%d bit)\n", - BN_num_bits(pkey->pkey.rsa->n)); - RSA_print(out,pkey->pkey.rsa,2); - } - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - { - BIO_printf(out," DSA Public Key:\n"); - DSA_print(out,pkey->pkey.dsa,2); - } - else -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) + else { - BIO_printf(out, " EC Public Key:\n"); - EC_KEY_print(out, pkey->pkey.ec,2); - } - else -#endif - - BIO_printf(out," Unknown Public Key:\n"); + EVP_PKEY_print_public(out, pkey, 4, NULL); EVP_PKEY_free(pkey); - } + } chal = spki->spkac->challenge; if(chal->length) BIO_printf(out, " Challenge String: %s\n", chal->data); diff --git a/crypto/openssl/crypto/asn1/t_x509.c b/crypto/openssl/crypto/asn1/t_x509.c index 6f295b4e14..e061f2ffad 100644 --- a/crypto/openssl/crypto/asn1/t_x509.c +++ b/crypto/openssl/crypto/asn1/t_x509.c @@ -111,7 +111,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) ASN1_INTEGER *bs; EVP_PKEY *pkey=NULL; const char *neg; - ASN1_STRING *str=NULL; if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; @@ -215,34 +214,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) ERR_print_errors(bp); } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - { - BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","", - BN_num_bits(pkey->pkey.rsa->n)); - RSA_print(bp,pkey->pkey.rsa,16); - } - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - { - BIO_printf(bp,"%12sDSA Public Key:\n",""); - DSA_print(bp,pkey->pkey.dsa,16); - } - else -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - BIO_printf(bp, "%12sEC Public Key:\n",""); - EC_KEY_print(bp, pkey->pkey.ec, 16); + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); } - else -#endif - BIO_printf(bp,"%12sUnknown Public Key:\n",""); - - EVP_PKEY_free(pkey); } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) @@ -259,7 +234,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) } ret=1; err: - if (str != NULL) ASN1_STRING_free(str); if (m != NULL) OPENSSL_free(m); return(ret); } @@ -329,14 +303,15 @@ int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig) return 1; } -int ASN1_STRING_print(BIO *bp, ASN1_STRING *v) +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) { int i,n; - char buf[80],*p; + char buf[80]; + const char *p; if (v == NULL) return(0); n=0; - p=(char *)v->data; + p=(const char *)v->data; for (i=0; ilength; i++) { if ((p[i] > '~') || ((p[i] < ' ') && @@ -358,7 +333,7 @@ int ASN1_STRING_print(BIO *bp, ASN1_STRING *v) return(1); } -int ASN1_TIME_print(BIO *bp, ASN1_TIME *tm) +int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) { if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm); if(tm->type == V_ASN1_GENERALIZEDTIME) @@ -373,7 +348,7 @@ static const char *mon[12]= "Jul","Aug","Sep","Oct","Nov","Dec" }; -int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm) +int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) { char *v; int gmt=0; @@ -421,15 +396,15 @@ err: return(0); } -int ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm) +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) { - char *v; + const char *v; int gmt=0; int i; int y=0,M=0,d=0,h=0,m=0,s=0; i=tm->length; - v=(char *)tm->data; + v=(const char *)tm->data; if (i < 10) goto err; if (v[i-1] == 'Z') gmt=1; diff --git a/crypto/openssl/crypto/asn1/tasn_dec.c b/crypto/openssl/crypto/asn1/tasn_dec.c index 48bc1c0d4d..3bee439968 100644 --- a/crypto/openssl/crypto/asn1/tasn_dec.c +++ b/crypto/openssl/crypto/asn1/tasn_dec.c @@ -114,6 +114,8 @@ unsigned long ASN1_tag2bit(int tag) /* Macro to initialize and invalidate the cache */ #define asn1_tlc_clear(c) if (c) (c)->valid = 0 +/* Version to avoid compiler warning about 'c' always non-NULL */ +#define asn1_tlc_clear_nc(c) (c)->valid = 0 /* Decode an ASN1 item, this currently behaves just * like a standard 'd2i' function. 'in' points to @@ -130,7 +132,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, ASN1_VALUE *ptmpval = NULL; if (!pval) pval = &ptmpval; - c.valid = 0; + asn1_tlc_clear_nc(&c); if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) return *pval; return NULL; @@ -140,7 +142,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt) { ASN1_TLC c; - c.valid = 0; + asn1_tlc_clear_nc(&c); return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); } @@ -306,7 +308,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, case ASN1_ITYPE_CHOICE: - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; /* Allocate structure */ @@ -356,7 +358,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, asn1_set_choice_selector(pval, i, it); *in = p; - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) goto auxerr; return 1; @@ -403,7 +405,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, goto err; } - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; /* Get each field entry */ @@ -505,7 +507,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, if (!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr; *in = p; - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) goto auxerr; return 1; @@ -665,11 +667,12 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, else { /* We've got a valid STACK: free up any items present */ - STACK *sktmp = (STACK *)*val; + STACK_OF(ASN1_VALUE) *sktmp + = (STACK_OF(ASN1_VALUE) *)*val; ASN1_VALUE *vtmp; - while(sk_num(sktmp) > 0) + while(sk_ASN1_VALUE_num(sktmp) > 0) { - vtmp = (ASN1_VALUE *)sk_pop(sktmp); + vtmp = sk_ASN1_VALUE_pop(sktmp); ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); } @@ -710,7 +713,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, goto err; } len -= p - q; - if (!sk_push((STACK *)*val, (char *)skfield)) + if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, + skfield)) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); diff --git a/crypto/openssl/crypto/asn1/tasn_enc.c b/crypto/openssl/crypto/asn1/tasn_enc.c index 2721f904a6..936ad1f767 100644 --- a/crypto/openssl/crypto/asn1/tasn_enc.c +++ b/crypto/openssl/crypto/asn1/tasn_enc.c @@ -158,7 +158,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); case ASN1_ITYPE_CHOICE: - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) return 0; i = asn1_get_choice_selector(pval, it); if ((i >= 0) && (i < it->tcount)) @@ -171,7 +171,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, -1, aclass); } /* Fixme: error condition if selector out of range */ - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) return 0; break; @@ -216,7 +216,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) | V_ASN1_UNIVERSAL; } - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) return 0; /* First work out sequence content length */ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) @@ -250,7 +250,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, } if (ndef == 2) ASN1_put_eoc(out); - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) return 0; return seqlen; @@ -569,7 +569,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, ASN1_STRING *strtmp; ASN1_OBJECT *otmp; int utype; - unsigned char *cont, c; + const unsigned char *cont; + unsigned char c; int len; const ASN1_PRIMITIVE_FUNCS *pf; pf = it->funcs; diff --git a/crypto/openssl/crypto/asn1/tasn_fre.c b/crypto/openssl/crypto/asn1/tasn_fre.c index d7c017fa1d..77d3092d31 100644 --- a/crypto/openssl/crypto/asn1/tasn_fre.c +++ b/crypto/openssl/crypto/asn1/tasn_fre.c @@ -110,7 +110,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c case ASN1_ITYPE_CHOICE: if (asn1_cb) { - i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); if (i == 2) return; } @@ -123,7 +123,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c ASN1_template_free(pchval, tt); } if (asn1_cb) - asn1_cb(ASN1_OP_FREE_POST, pval, it); + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); if (!combine) { OPENSSL_free(*pval); @@ -149,7 +149,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c return; if (asn1_cb) { - i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); if (i == 2) return; } @@ -170,7 +170,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c ASN1_template_free(pseqval, seqtt); } if (asn1_cb) - asn1_cb(ASN1_OP_FREE_POST, pval, it); + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); if (!combine) { OPENSSL_free(*pval); diff --git a/crypto/openssl/crypto/asn1/tasn_new.c b/crypto/openssl/crypto/asn1/tasn_new.c index 5c6a2ebd4d..0d9e78cc7c 100644 --- a/crypto/openssl/crypto/asn1/tasn_new.c +++ b/crypto/openssl/crypto/asn1/tasn_new.c @@ -68,7 +68,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) { @@ -146,7 +146,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, case ASN1_ITYPE_CHOICE: if (asn1_cb) { - i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); if (!i) goto auxerr; if (i==2) @@ -166,7 +166,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, memset(*pval, 0, it->size); } asn1_set_choice_selector(pval, -1, it); - if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) goto auxerr; break; @@ -174,7 +174,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, case ASN1_ITYPE_SEQUENCE: if (asn1_cb) { - i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); if (!i) goto auxerr; if (i==2) @@ -201,7 +201,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, if (!ASN1_template_new(pseqval, tt)) goto memerr; } - if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) goto auxerr; break; } @@ -325,6 +325,7 @@ static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { ASN1_TYPE *typ; + ASN1_STRING *str; int utype; if (it && it->funcs) @@ -345,10 +346,7 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) return 1; case V_ASN1_BOOLEAN: - if (it) - *(ASN1_BOOLEAN *)pval = it->size; - else - *(ASN1_BOOLEAN *)pval = -1; + *(ASN1_BOOLEAN *)pval = it->size; return 1; case V_ASN1_NULL: @@ -365,7 +363,10 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) break; default: - *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); + str = ASN1_STRING_type_new(utype); + if (it->itype == ASN1_ITYPE_MSTRING && str) + str->flags |= ASN1_STRING_FLAG_MSTRING; + *pval = (ASN1_VALUE *)str; break; } if (*pval) @@ -373,7 +374,7 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) return 0; } -void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) { int utype; if (it && it->funcs) diff --git a/crypto/openssl/crypto/asn1/tasn_prn.c b/crypto/openssl/crypto/asn1/tasn_prn.c new file mode 100644 index 0000000000..453698012d --- /dev/null +++ b/crypto/openssl/crypto/asn1/tasn_prn.c @@ -0,0 +1,627 @@ +/* tasn_prn.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000,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 + * 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "asn1_locl.h" + +/* Print routines. + */ + +/* ASN1_PCTX routines */ + +ASN1_PCTX default_pctx = + { + ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ + 0, /* nm_flags */ + 0, /* cert_flags */ + 0, /* oid_flags */ + 0 /* str_flags */ + }; + + +ASN1_PCTX *ASN1_PCTX_new(void) + { + ASN1_PCTX *ret; + ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); + if (ret == NULL) + { + ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->flags = 0; + ret->nm_flags = 0; + ret->cert_flags = 0; + ret->oid_flags = 0; + ret->str_flags = 0; + return ret; + } + +void ASN1_PCTX_free(ASN1_PCTX *p) + { + OPENSSL_free(p); + } + +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) + { + return p->flags; + } + +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) + { + p->flags = flags; + } + +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) + { + return p->nm_flags; + } + +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) + { + p->nm_flags = flags; + } + +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) + { + return p->cert_flags; + } + +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) + { + p->cert_flags = flags; + } + +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) + { + return p->oid_flags; + } + +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) + { + p->oid_flags = flags; + } + +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) + { + return p->str_flags; + } + +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) + { + p->str_flags = flags; + } + +/* Main print routines */ + +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_ITEM *it, + const char *fname, const char *sname, + int nohdr, const ASN1_PCTX *pctx); + +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); + +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, + const ASN1_ITEM *it, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx); + +static int asn1_print_fsname(BIO *out, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx); + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx) + { + const char *sname; + if (pctx == NULL) + pctx = &default_pctx; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) + sname = NULL; + else + sname = it->sname; + return asn1_item_print_ctx(out, &ifld, indent, it, + NULL, sname, 0, pctx); + } + +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_ITEM *it, + const char *fname, const char *sname, + int nohdr, const ASN1_PCTX *pctx) + { + const ASN1_TEMPLATE *tt; + const ASN1_EXTERN_FUNCS *ef; + ASN1_VALUE **tmpfld; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + ASN1_PRINT_ARG parg; + int i; + if (aux && aux->asn1_cb) + { + parg.out = out; + parg.indent = indent; + parg.pctx = pctx; + asn1_cb = aux->asn1_cb; + } + else asn1_cb = 0; + + if(*fld == NULL) + { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) + { + if (!nohdr && !asn1_print_fsname(out, indent, + fname, sname, pctx)) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + return 1; + } + + switch(it->itype) + { + case ASN1_ITYPE_PRIMITIVE: + if(it->templates) + { + if (!asn1_template_print_ctx(out, fld, indent, + it->templates, pctx)) + return 0; + } + /* fall thru */ + case ASN1_ITYPE_MSTRING: + if (!asn1_primitive_print(out, fld, it, + indent, fname, sname,pctx)) + return 0; + break; + + case ASN1_ITYPE_EXTERN: + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + /* Use new style print routine if possible */ + ef = it->funcs; + if (ef && ef->asn1_ex_print) + { + i = ef->asn1_ex_print(out, fld, indent, "", pctx); + if (!i) + return 0; + if ((i == 2) && (BIO_puts(out, "\n") <= 0)) + return 0; + return 1; + } + else if (sname && + BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) + return 0; + break; + + case ASN1_ITYPE_CHOICE: +#if 0 + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; +#endif + /* CHOICE type, get selector */ + i = asn1_get_choice_selector(fld, it); + /* This should never happen... */ + if((i < 0) || (i >= it->tcount)) + { + if (BIO_printf(out, + "ERROR: selector [%d] invalid\n", i) <= 0) + return 0; + return 1; + } + tt = it->templates + i; + tmpfld = asn1_get_field_ptr(fld, tt); + if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) + return 0; + break; + + case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_NDEF_SEQUENCE: + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (fname || sname) + { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) + { + if (BIO_puts(out, " {\n") <= 0) + return 0; + } + else + { + if (BIO_puts(out, "\n") <= 0) + return 0; + } + } + + if (asn1_cb) + { + i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); + if (i == 0) + return 0; + if (i == 2) + return 1; + } + + /* Print each field entry */ + for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) + { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(fld, tt, 1); + tmpfld = asn1_get_field_ptr(fld, seqtt); + if (!asn1_template_print_ctx(out, tmpfld, + indent + 2, seqtt, pctx)) + return 0; + } + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) + { + if (BIO_printf(out, "%*s}\n", indent, "") < 0) + return 0; + } + + if (asn1_cb) + { + i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); + if (i == 0) + return 0; + } + break; + + default: + BIO_printf(out, "Unprocessed type %d\n", it->itype); + return 0; + } + + return 1; + } + +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) + { + int i, flags; + const char *sname, *fname; + flags = tt->flags; + if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) + sname = ASN1_ITEM_ptr(tt->item)->sname; + else + sname = NULL; + if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) + fname = NULL; + else + fname = tt->field_name; + if(flags & ASN1_TFLG_SK_MASK) + { + char *tname; + ASN1_VALUE *skitem; + STACK_OF(ASN1_VALUE) *stack; + + /* SET OF, SEQUENCE OF */ + if (fname) + { + if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) + { + if(flags & ASN1_TFLG_SET_OF) + tname = "SET"; + else + tname = "SEQUENCE"; + if (BIO_printf(out, "%*s%s OF %s {\n", + indent, "", tname, tt->field_name) <= 0) + return 0; + } + else if (BIO_printf(out, "%*s%s:\n", indent, "", + fname) <= 0) + return 0; + } + stack = (STACK_OF(ASN1_VALUE) *)*fld; + for(i = 0; i < sk_ASN1_VALUE_num(stack); i++) + { + if ((i > 0) && (BIO_puts(out, "\n") <= 0)) + return 0; + + skitem = sk_ASN1_VALUE_value(stack, i); + if (!asn1_item_print_ctx(out, &skitem, indent + 2, + ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx)) + return 0; + } + if (!i && BIO_printf(out, "%*s\n", indent + 2, "") <= 0) + return 0; + if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) + { + if (BIO_printf(out, "%*s}\n", indent, "") <= 0) + return 0; + } + return 1; + } + return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), + fname, sname, 0, pctx); + } + +static int asn1_print_fsname(BIO *out, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx) + { + static char spaces[] = " "; + const int nspaces = sizeof(spaces) - 1; + +#if 0 + if (!sname && !fname) + return 1; +#endif + + while (indent > nspaces) + { + if (BIO_write(out, spaces, nspaces) != nspaces) + return 0; + indent -= nspaces; + } + if (BIO_write(out, spaces, indent) != indent) + return 0; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) + sname = NULL; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) + fname = NULL; + if (!sname && !fname) + return 1; + if (fname) + { + if (BIO_puts(out, fname) <= 0) + return 0; + } + if (sname) + { + if (fname) + { + if (BIO_printf(out, " (%s)", sname) <= 0) + return 0; + } + else + { + if (BIO_puts(out, sname) <= 0) + return 0; + } + } + if (BIO_write(out, ": ", 2) != 2) + return 0; + return 1; + } + +static int asn1_print_boolean_ctx(BIO *out, const int bool, + const ASN1_PCTX *pctx) + { + const char *str; + switch (bool) + { + case -1: + str = "BOOL ABSENT"; + break; + + case 0: + str = "FALSE"; + break; + + default: + str = "TRUE"; + break; + + } + + if (BIO_puts(out, str) <= 0) + return 0; + return 1; + + } + +static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, + const ASN1_PCTX *pctx) + { + char *s; + int ret = 1; + s = i2s_ASN1_INTEGER(NULL, str); + if (BIO_puts(out, s) <= 0) + ret = 0; + OPENSSL_free(s); + return ret; + } + +static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, + const ASN1_PCTX *pctx) + { + char objbuf[80]; + const char *ln; + ln = OBJ_nid2ln(OBJ_obj2nid(oid)); + if(!ln) + ln = ""; + OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); + if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) + return 0; + return 1; + } + +static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, + const ASN1_PCTX *pctx) + { + if (str->type == V_ASN1_BIT_STRING) + { + if (BIO_printf(out, " (%ld unused bits)\n", + str->flags & 0x7) <= 0) + return 0; + } + else if (BIO_puts(out, "\n") <= 0) + return 0; + if ((str->length > 0) + && BIO_dump_indent(out, (char *)str->data, str->length, + indent + 2) <= 0) + return 0; + return 1; + } + +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, + const ASN1_ITEM *it, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx) + { + long utype; + ASN1_STRING *str; + int ret = 1, needlf = 1; + const char *pname; + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (!asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (pf && pf->prim_print) + return pf->prim_print(out, fld, it, indent, pctx); + str = (ASN1_STRING *)*fld; + if (it->itype == ASN1_ITYPE_MSTRING) + utype = str->type & ~V_ASN1_NEG; + else + utype = it->utype; + if (utype == V_ASN1_ANY) + { + ASN1_TYPE *atype = (ASN1_TYPE *)*fld; + utype = atype->type; + fld = &atype->value.asn1_value; + str = (ASN1_STRING *)*fld; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) + pname = NULL; + else + pname = ASN1_tag2str(utype); + } + else + { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) + pname = ASN1_tag2str(utype); + else + pname = NULL; + } + + if (utype == V_ASN1_NULL) + { + if (BIO_puts(out, "NULL\n") <= 0) + return 0; + return 1; + } + + if (pname) + { + if (BIO_puts(out, pname) <= 0) + return 0; + if (BIO_puts(out, ":") <= 0) + return 0; + } + + switch (utype) + { + case V_ASN1_BOOLEAN: + { + int bool = *(int *)fld; + if (bool == -1) + bool = it->size; + ret = asn1_print_boolean_ctx(out, bool, pctx); + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + ret = asn1_print_integer_ctx(out, str, pctx); + break; + + case V_ASN1_UTCTIME: + ret = ASN1_UTCTIME_print(out, str); + break; + + case V_ASN1_GENERALIZEDTIME: + ret = ASN1_GENERALIZEDTIME_print(out, str); + break; + + case V_ASN1_OBJECT: + ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_BIT_STRING: + ret = asn1_print_obstring_ctx(out, str, indent, pctx); + needlf = 0; + break; + + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_OTHER: + if (BIO_puts(out, "\n") <= 0) + return 0; + if (ASN1_parse_dump(out, str->data, str->length, + indent, 0) <= 0) + ret = 0; + needlf = 0; + break; + + default: + ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); + + } + if (!ret) + return 0; + if (needlf && BIO_puts(out, "\n") <= 0) + return 0; + return 1; + } diff --git a/crypto/openssl/crypto/asn1/tasn_typ.c b/crypto/openssl/crypto/asn1/tasn_typ.c index 6252213d15..6fb1c372da 100644 --- a/crypto/openssl/crypto/asn1/tasn_typ.c +++ b/crypto/openssl/crypto/asn1/tasn_typ.c @@ -135,3 +135,14 @@ IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) /* Special, OCTET STRING with indefinite length constructed support */ IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) + +ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY) + +ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) diff --git a/crypto/openssl/crypto/asn1/x_crl.c b/crypto/openssl/crypto/asn1/x_crl.c index 70d56a67f2..c51c690ba9 100644 --- a/crypto/openssl/crypto/asn1/x_crl.c +++ b/crypto/openssl/crypto/asn1/x_crl.c @@ -58,11 +58,14 @@ #include #include "cryptlib.h" +#include "asn1_locl.h" #include #include +#include static int X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b); +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); ASN1_SEQUENCE(X509_REVOKED) = { ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), @@ -70,11 +73,26 @@ ASN1_SEQUENCE(X509_REVOKED) = { ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) } ASN1_SEQUENCE_END(X509_REVOKED) +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer); + +static X509_CRL_METHOD int_crl_meth = + { + 0, + 0,0, + def_crl_lookup, + def_crl_verify + }; + +static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; + /* The X509_CRL_INFO structure needs a bit of customisation. * Since we cache the original encoding the signature wont be affected by * reordering of the revoked field. */ -static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; @@ -101,7 +119,237 @@ ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) -ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = { +/* Set CRL entry issuer according to CRL certificate issuer extension. + * Check for unhandled critical CRL entry extensions. + */ + +static int crl_set_issuers(X509_CRL *crl) + { + + int i, j; + GENERAL_NAMES *gens, *gtmp; + STACK_OF(X509_REVOKED) *revoked; + + revoked = X509_CRL_get_REVOKED(crl); + + gens = NULL; + for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) + { + X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); + STACK_OF(X509_EXTENSION) *exts; + ASN1_ENUMERATED *reason; + X509_EXTENSION *ext; + gtmp = X509_REVOKED_get_ext_d2i(rev, + NID_certificate_issuer, + &j, NULL); + if (!gtmp && (j != -1)) + { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (gtmp) + { + gens = gtmp; + if (!crl->issuers) + { + crl->issuers = sk_GENERAL_NAMES_new_null(); + if (!crl->issuers) + return 0; + } + if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) + return 0; + } + rev->issuer = gens; + + reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, + &j, NULL); + if (!reason && (j != -1)) + { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (reason) + { + rev->reason = ASN1_ENUMERATED_get(reason); + ASN1_ENUMERATED_free(reason); + } + else + rev->reason = CRL_REASON_NONE; + + /* Check for critical CRL entry extensions */ + + exts = rev->extensions; + + for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) + { + ext = sk_X509_EXTENSION_value(exts, j); + if (ext->critical > 0) + { + if (OBJ_obj2nid(ext->object) == + NID_certificate_issuer) + continue; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + + } + + return 1; + + } + +/* The X509_CRL structure needs a bit of customisation. Cache some extensions + * and hash of the whole CRL. + */ +static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) + { + X509_CRL *crl = (X509_CRL *)*pval; + STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSION *ext; + int idx; + + switch(operation) + { + case ASN1_OP_NEW_POST: + crl->idp = NULL; + crl->akid = NULL; + crl->flags = 0; + crl->idp_flags = 0; + crl->idp_reasons = CRLDP_ALL_REASONS; + crl->meth = default_crl_method; + crl->meth_data = NULL; + crl->issuers = NULL; + crl->crl_number = NULL; + crl->base_crl_number = NULL; + break; + + case ASN1_OP_D2I_POST: +#ifndef OPENSSL_NO_SHA + X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); +#endif + crl->idp = X509_CRL_get_ext_d2i(crl, + NID_issuing_distribution_point, NULL, NULL); + if (crl->idp) + setup_idp(crl, crl->idp); + + crl->akid = X509_CRL_get_ext_d2i(crl, + NID_authority_key_identifier, NULL, NULL); + + crl->crl_number = X509_CRL_get_ext_d2i(crl, + NID_crl_number, NULL, NULL); + + crl->base_crl_number = X509_CRL_get_ext_d2i(crl, + NID_delta_crl, NULL, NULL); + /* Delta CRLs must have CRL number */ + if (crl->base_crl_number && !crl->crl_number) + crl->flags |= EXFLAG_INVALID; + + /* See if we have any unhandled critical CRL extensions and + * indicate this in a flag. We only currently handle IDP so + * anything else critical sets the flag. + * + * This code accesses the X509_CRL structure directly: + * applications shouldn't do this. + */ + + exts = crl->crl->extensions; + + for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) + { + int nid; + ext = sk_X509_EXTENSION_value(exts, idx); + nid = OBJ_obj2nid(ext->object); + if (nid == NID_freshest_crl) + crl->flags |= EXFLAG_FRESHEST; + if (ext->critical > 0) + { + /* We handle IDP and deltas */ + if ((nid == NID_issuing_distribution_point) + || (nid == NID_delta_crl)) + break;; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + + if (!crl_set_issuers(crl)) + return 0; + + if (crl->meth->crl_init) + { + if (crl->meth->crl_init(crl) == 0) + return 0; + } + break; + + case ASN1_OP_FREE_POST: + if (crl->meth->crl_free) + { + if (!crl->meth->crl_free(crl)) + return 0; + } + if (crl->akid) + AUTHORITY_KEYID_free(crl->akid); + if (crl->idp) + ISSUING_DIST_POINT_free(crl->idp); + ASN1_INTEGER_free(crl->crl_number); + ASN1_INTEGER_free(crl->base_crl_number); + sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); + break; + } + return 1; + } + +/* Convert IDP into a more convenient form */ + +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) + { + int idp_only = 0; + /* Set various flags according to IDP */ + crl->idp_flags |= IDP_PRESENT; + if (idp->onlyuser > 0) + { + idp_only++; + crl->idp_flags |= IDP_ONLYUSER; + } + if (idp->onlyCA > 0) + { + idp_only++; + crl->idp_flags |= IDP_ONLYCA; + } + if (idp->onlyattr > 0) + { + idp_only++; + crl->idp_flags |= IDP_ONLYATTR; + } + + if (idp_only > 1) + crl->idp_flags |= IDP_INVALID; + + if (idp->indirectCRL > 0) + crl->idp_flags |= IDP_INDIRECT; + + if (idp->onlysomereasons) + { + crl->idp_flags |= IDP_REASONS; + if (idp->onlysomereasons->length > 0) + crl->idp_reasons = idp->onlysomereasons->data[0]; + if (idp->onlysomereasons->length > 1) + crl->idp_reasons |= + (idp->onlysomereasons->data[1] << 8); + crl->idp_reasons &= CRLDP_ALL_REASONS; + } + + DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); + } + +ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = { ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) @@ -134,6 +382,145 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) return 1; } +int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) + { + if (crl->meth->crl_verify) + return crl->meth->crl_verify(crl, r); + return 0; + } + +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial) + { + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, serial, NULL); + return 0; + } + +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) + { + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, + X509_get_serialNumber(x), + X509_get_issuer_name(x)); + return 0; + } + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) + { + return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), + crl->sig_alg, crl->signature,crl->crl,r)); + } + +static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, + X509_REVOKED *rev) + { + int i; + + if (!rev->issuer) + { + if (!nm) + return 1; + if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) + return 1; + return 0; + } + + if (!nm) + nm = X509_CRL_get_issuer(crl); + + for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) + { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gen->d.directoryName)) + return 1; + } + return 0; + + } + +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer) + { + X509_REVOKED rtmp, *rev; + int idx; + rtmp.serialNumber = serial; + /* Sort revoked into serial number order if not already sorted. + * Do this under a lock to avoid race condition. + */ + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) + { + CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); + sk_X509_REVOKED_sort(crl->crl->revoked); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); + } + idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); + if(idx < 0) + return 0; + /* Need to look for matching name */ + for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) + { + rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); + if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) + return 0; + if (crl_revoked_issuer_match(crl, issuer, rev)) + { + if (ret) + *ret = rev; + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + return 1; + } + } + return 0; + } + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) + { + if (meth == NULL) + default_crl_method = &int_crl_meth; + else + default_crl_method = meth; + } + +X509_CRL_METHOD *X509_CRL_METHOD_new( + int (*crl_init)(X509_CRL *crl), + int (*crl_free)(X509_CRL *crl), + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer), + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)) + { + X509_CRL_METHOD *m; + m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); + if (!m) + return NULL; + m->crl_init = crl_init; + m->crl_free = crl_free; + m->crl_lookup = crl_lookup; + m->crl_verify = crl_verify; + m->flags = X509_CRL_METHOD_DYNAMIC; + return m; + } + +void X509_CRL_METHOD_free(X509_CRL_METHOD *m) + { + if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) + return; + OPENSSL_free(m); + } + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) + { + crl->meth_data = dat; + } + +void *X509_CRL_get_meth_data(X509_CRL *crl) + { + return crl->meth_data; + } + IMPLEMENT_STACK_OF(X509_REVOKED) IMPLEMENT_ASN1_SET_OF(X509_REVOKED) IMPLEMENT_STACK_OF(X509_CRL) diff --git a/crypto/openssl/crypto/asn1/x_long.c b/crypto/openssl/crypto/asn1/x_long.c index bf35457c1f..75317418e1 100644 --- a/crypto/openssl/crypto/asn1/x_long.c +++ b/crypto/openssl/crypto/asn1/x_long.c @@ -71,6 +71,7 @@ static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); static ASN1_PRIMITIVE_FUNCS long_pf = { NULL, 0, @@ -78,7 +79,8 @@ static ASN1_PRIMITIVE_FUNCS long_pf = { long_free, long_free, /* Clear should set to initial value */ long_c2i, - long_i2c + long_i2c, + long_print }; ASN1_ITEM_start(LONG) @@ -169,3 +171,9 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, memcpy(cp, <mp, sizeof(long)); return 1; } + +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx) + { + return BIO_printf(out, "%ld\n", *(long *)pval); + } diff --git a/crypto/openssl/crypto/asn1/x_name.c b/crypto/openssl/crypto/asn1/x_name.c index 04380abc3f..caa4409feb 100644 --- a/crypto/openssl/crypto/asn1/x_name.c +++ b/crypto/openssl/crypto/asn1/x_name.c @@ -57,18 +57,36 @@ */ #include +#include #include "cryptlib.h" #include #include +#include "asn1_locl.h" -static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; +DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); static int x509_name_encode(X509_NAME *a); +static int x509_name_canon(X509_NAME *a); +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname, + unsigned char **in); + + +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, + int indent, + const char *fname, + const ASN1_PCTX *pctx); ASN1_SEQUENCE(X509_NAME_ENTRY) = { ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), @@ -102,7 +120,8 @@ const ASN1_EXTERN_FUNCS x509_name_ff = { x509_name_ex_free, 0, /* Default clear behaviour is OK */ x509_name_ex_d2i, - x509_name_ex_i2d + x509_name_ex_i2d, + x509_name_ex_print }; IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) @@ -118,6 +137,8 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) goto memerr; if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr; + ret->canon_enc = NULL; + ret->canon_enclen = 0; ret->modified=1; *val = (ASN1_VALUE *)ret; return 1; @@ -142,25 +163,19 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) BUF_MEM_free(a->bytes); sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); + if (a->canon_enc) + OPENSSL_free(a->canon_enc); OPENSSL_free(a); *pval = NULL; } -/* Used with sk_pop_free() to free up the internal representation. - * NB: we only free the STACK and not its contents because it is - * already present in the X509_NAME structure. - */ - -static void sk_internal_free(void *a) -{ - sk_free(a); -} - -static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) { const unsigned char *p = *in, *q; - union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; + union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; } intname = {NULL}; union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; int i, j, ret; STACK_OF(X509_NAME_ENTRY) *entries; @@ -181,8 +196,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len memcpy(nm.x->bytes->data, q, p - q); /* Convert internal representation to X509_NAME structure */ - for(i = 0; i < sk_num(intname.s); i++) { - entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i); + for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { + entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { entry = sk_X509_NAME_ENTRY_value(entries, j); entry->set = i; @@ -191,7 +206,10 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len } sk_X509_NAME_ENTRY_free(entries); } - sk_free(intname.s); + sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); + ret = x509_name_canon(nm.x); + if (!ret) + goto err; nm.x->modified = 0; *val = nm.a; *in = p; @@ -206,8 +224,12 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT int ret; X509_NAME *a = (X509_NAME *)*val; if(a->modified) { - ret = x509_name_encode((X509_NAME *)a); - if(ret < 0) return ret; + ret = x509_name_encode(a); + if(ret < 0) + return ret; + ret = x509_name_canon(a); + if(ret < 0) + return ret; } ret = a->bytes->length; if(out != NULL) { @@ -217,22 +239,35 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT return ret; } +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) + { + sk_X509_NAME_ENTRY_free(ne); + } + +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) + { + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); + } + static int x509_name_encode(X509_NAME *a) { - union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; + union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; } intname = {NULL}; int len; unsigned char *p; STACK_OF(X509_NAME_ENTRY) *entries = NULL; X509_NAME_ENTRY *entry; int i, set = -1; - intname.s = sk_new_null(); + intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); if(!intname.s) goto memerr; for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { entry = sk_X509_NAME_ENTRY_value(a->entries, i); if(entry->set != set) { entries = sk_X509_NAME_ENTRY_new_null(); if(!entries) goto memerr; - if(!sk_push(intname.s, (char *)entries)) goto memerr; + if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, + entries)) + goto memerr; set = entry->set; } if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; @@ -243,15 +278,222 @@ static int x509_name_encode(X509_NAME *a) p=(unsigned char *)a->bytes->data; ASN1_item_ex_i2d(&intname.a, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - sk_pop_free(intname.s, sk_internal_free); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); a->modified = 0; return len; - memerr: - sk_pop_free(intname.s, sk_internal_free); +memerr: + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); return -1; } +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, + int indent, + const char *fname, + const ASN1_PCTX *pctx) + { + if (X509_NAME_print_ex(out, (X509_NAME *)*pval, + indent, pctx->nm_flags) <= 0) + return 0; + return 2; + } + +/* This function generates the canonical encoding of the Name structure. + * In it all strings are converted to UTF8, leading, trailing and + * multiple spaces collapsed, converted to lower case and the leading + * SEQUENCE header removed. + * + * In future we could also normalize the UTF8 too. + * + * By doing this comparison of Name structures can be rapidly + * perfomed by just using memcmp() of the canonical encoding. + * By omitting the leading SEQUENCE name constraints of type + * dirName can also be checked with a simple memcmp(). + */ + +static int x509_name_canon(X509_NAME *a) + { + unsigned char *p; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry, *tmpentry = NULL; + int i, set = -1, ret = 0; + + if (a->canon_enc) + { + OPENSSL_free(a->canon_enc); + a->canon_enc = NULL; + } + /* Special case: empty X509_NAME => null encoding */ + if (sk_X509_NAME_ENTRY_num(a->entries) == 0) + { + a->canon_enclen = 0; + return 1; + } + intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if(!intname) + goto err; + for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) + { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if(entry->set != set) + { + entries = sk_X509_NAME_ENTRY_new_null(); + if(!entries) + goto err; + if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) + goto err; + set = entry->set; + } + tmpentry = X509_NAME_ENTRY_new(); + tmpentry->object = OBJ_dup(entry->object); + if (!asn1_string_canon(tmpentry->value, entry->value)) + goto err; + if(!sk_X509_NAME_ENTRY_push(entries, tmpentry)) + goto err; + tmpentry = NULL; + } + + /* Finally generate encoding */ + + a->canon_enclen = i2d_name_canon(intname, NULL); + + p = OPENSSL_malloc(a->canon_enclen); + + if (!p) + goto err; + + a->canon_enc = p; + + i2d_name_canon(intname, &p); + + ret = 1; + + err: + + if (tmpentry) + X509_NAME_ENTRY_free(tmpentry); + if (intname) + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + return ret; + } + +/* Bitmap of all the types of string that will be canonicalized. */ + +#define ASN1_MASK_CANON \ + (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ + | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ + | B_ASN1_VISIBLESTRING) + + +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) + { + unsigned char *to, *from; + int len, i; + + /* If type not in bitmask just copy string across */ + if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) + { + out->type = in->type; + if (!ASN1_STRING_set(out, in->data, in->length)) + return 0; + return 1; + } + + out->type = V_ASN1_UTF8STRING; + out->length = ASN1_STRING_to_UTF8(&out->data, in); + if (out->length == -1) + return 0; + + to = out->data; + from = to; + + len = out->length; + + /* Convert string in place to canonical form. + * Ultimately we may need to handle a wider range of characters + * but for now ignore anything with MSB set and rely on the + * isspace() and tolower() functions. + */ + + /* Ignore leading spaces */ + while((len > 0) && !(*from & 0x80) && isspace(*from)) + { + from++; + len--; + } + + to = from + len - 1; + + /* Ignore trailing spaces */ + while ((len > 0) && !(*to & 0x80) && isspace(*to)) + { + to--; + len--; + } + + to = out->data; + + i = 0; + while(i < len) + { + /* If MSB set just copy across */ + if (*from & 0x80) + { + *to++ = *from++; + i++; + } + /* Collapse multiple spaces */ + else if (isspace(*from)) + { + /* Copy one space across */ + *to++ = ' '; + /* Ignore subsequent spaces. Note: don't need to + * check len here because we know the last + * character is a non-space so we can't overflow. + */ + do + { + from++; + i++; + } + while(!(*from & 0x80) && isspace(*from)); + } + else + { + *to++ = tolower(*from++); + i++; + } + } + + out->length = to - out->data; + + return 1; + + } + +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, + unsigned char **in) + { + int i, len, ltmp; + ASN1_VALUE *v; + STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; + + len = 0; + for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) + { + v = sk_ASN1_VALUE_value(intname, i); + ltmp = ASN1_item_ex_i2d(&v, in, + ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); + if (ltmp < 0) + return ltmp; + len += ltmp; + } + return len; + } int X509_NAME_set(X509_NAME **xn, X509_NAME *name) { diff --git a/crypto/openssl/crypto/pem/pem_x509.c b/crypto/openssl/crypto/asn1/x_nx509.c similarity index 86% copy from crypto/openssl/crypto/pem/pem_x509.c copy to crypto/openssl/crypto/asn1/x_nx509.c index 3f709f13e6..fbd9a22db3 100644 --- a/crypto/openssl/crypto/pem/pem_x509.c +++ b/crypto/openssl/crypto/asn1/x_nx509.c @@ -1,9 +1,9 @@ -/* pem_x509.c */ +/* x_nx509.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. + * project 2005. */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 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 @@ -56,14 +56,17 @@ * */ -#include -#undef SSLEAY_MACROS -#include "cryptlib.h" -#include -#include +#include #include -#include -#include +#include +#include -IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) +/* Old netscape certificate wrapper format */ + +ASN1_SEQUENCE(NETSCAPE_X509) = { + ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING), + ASN1_OPT(NETSCAPE_X509, cert, X509) +} ASN1_SEQUENCE_END(NETSCAPE_X509) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509) diff --git a/crypto/openssl/crypto/asn1/x_pubkey.c b/crypto/openssl/crypto/asn1/x_pubkey.c index 91c2756116..d42b6a2c54 100644 --- a/crypto/openssl/crypto/asn1/x_pubkey.c +++ b/crypto/openssl/crypto/asn1/x_pubkey.c @@ -60,6 +60,7 @@ #include "cryptlib.h" #include #include +#include "asn1_locl.h" #ifndef OPENSSL_NO_RSA #include #endif @@ -68,7 +69,8 @@ #endif /* Minor tweak to operation: free up EVP_PKEY */ -static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if (operation == ASN1_OP_FREE_POST) { @@ -88,169 +90,42 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { X509_PUBKEY *pk=NULL; - X509_ALGOR *a; - ASN1_OBJECT *o; - unsigned char *s,*p = NULL; - int i; if (x == NULL) return(0); - if ((pk=X509_PUBKEY_new()) == NULL) goto err; - a=pk->algor; + if ((pk=X509_PUBKEY_new()) == NULL) goto error; - /* set the algorithm id */ - if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err; - ASN1_OBJECT_free(a->algorithm); - a->algorithm=o; - - /* Set the parameter list */ - if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA)) + if (pkey->ameth) { - if ((a->parameter == NULL) || - (a->parameter->type != V_ASN1_NULL)) + if (pkey->ameth->pub_encode) { - ASN1_TYPE_free(a->parameter); - if (!(a->parameter=ASN1_TYPE_new())) + if (!pkey->ameth->pub_encode(pk, pkey)) { - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; + X509err(X509_F_X509_PUBKEY_SET, + X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; } - a->parameter->type=V_ASN1_NULL; - } - } -#ifndef OPENSSL_NO_DSA - else if (pkey->type == EVP_PKEY_DSA) - { - unsigned char *pp; - DSA *dsa; - - dsa=pkey->pkey.dsa; - dsa->write_params=0; - ASN1_TYPE_free(a->parameter); - if ((i=i2d_DSAparams(dsa,NULL)) <= 0) - goto err; - if (!(p=(unsigned char *)OPENSSL_malloc(i))) - { - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; - } - pp=p; - i2d_DSAparams(dsa,&pp); - if (!(a->parameter=ASN1_TYPE_new())) - { - OPENSSL_free(p); - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; - } - a->parameter->type=V_ASN1_SEQUENCE; - if (!(a->parameter->value.sequence=ASN1_STRING_new())) - { - OPENSSL_free(p); - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; } - if (!ASN1_STRING_set(a->parameter->value.sequence,p,i)) + else { - OPENSSL_free(p); - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; + X509err(X509_F_X509_PUBKEY_SET, + X509_R_METHOD_NOT_SUPPORTED); + goto error; } - OPENSSL_free(p); } -#endif -#ifndef OPENSSL_NO_EC - else if (pkey->type == EVP_PKEY_EC) - { - int nid=0; - unsigned char *pp; - EC_KEY *ec_key; - const EC_GROUP *group; - - ec_key = pkey->pkey.ec; - ASN1_TYPE_free(a->parameter); - - if ((a->parameter = ASN1_TYPE_new()) == NULL) - { - X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); - goto err; - } - - group = EC_KEY_get0_group(ec_key); - if (EC_GROUP_get_asn1_flag(group) - && (nid = EC_GROUP_get_curve_name(group))) - { - /* just set the OID */ - a->parameter->type = V_ASN1_OBJECT; - a->parameter->value.object = OBJ_nid2obj(nid); - } - else /* explicit parameters */ - { - if ((i = i2d_ECParameters(ec_key, NULL)) == 0) - { - X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); - goto err; - } - if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) - { - X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE); - goto err; - } - pp = p; - if (!i2d_ECParameters(ec_key, &pp)) - { - X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); - OPENSSL_free(p); - goto err; - } - a->parameter->type = V_ASN1_SEQUENCE; - if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL) - { - X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); - OPENSSL_free(p); - goto err; - } - ASN1_STRING_set(a->parameter->value.sequence, p, i); - OPENSSL_free(p); - } - } -#endif - else if (1) + else { X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); - goto err; + goto error; } - if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err; - if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL) - { - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; - } - p=s; - i2d_PublicKey(pkey,&p); - if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) - { - X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); - goto err; - } - /* Set number of unused bits to zero */ - pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); - pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; - - OPENSSL_free(s); - -#if 0 - CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); - pk->pkey=pkey; -#endif - if (*x != NULL) X509_PUBKEY_free(*x); *x=pk; return 1; -err: +error: if (pk != NULL) X509_PUBKEY_free(pk); return 0; } @@ -258,119 +133,50 @@ err: EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) { EVP_PKEY *ret=NULL; - long j; - int type; - const unsigned char *p; -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) - const unsigned char *cp; - X509_ALGOR *a; -#endif - if (key == NULL) goto err; + if (key == NULL) goto error; if (key->pkey != NULL) { CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - return(key->pkey); + return key->pkey; } - if (key->public_key == NULL) goto err; + if (key->public_key == NULL) goto error; - type=OBJ_obj2nid(key->algor->algorithm); if ((ret = EVP_PKEY_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); - goto err; + goto error; } - ret->type = EVP_PKEY_type(type); - - /* the parameters must be extracted before the public key (ECDSA!) */ - -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) - a=key->algor; -#endif - if (0) - ; -#ifndef OPENSSL_NO_DSA - else if (ret->type == EVP_PKEY_DSA) + if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) { - if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) - { - if ((ret->pkey.dsa = DSA_new()) == NULL) - { - X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->pkey.dsa->write_params=0; - cp=p=a->parameter->value.sequence->data; - j=a->parameter->value.sequence->length; - if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j)) - goto err; - } - ret->save_parameters=1; + X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM); + goto error; } -#endif -#ifndef OPENSSL_NO_EC - else if (ret->type == EVP_PKEY_EC) + + if (ret->ameth->pub_decode) { - if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) + if (!ret->ameth->pub_decode(ret, key)) { - /* type == V_ASN1_SEQUENCE => we have explicit parameters - * (e.g. parameters in the X9_62_EC_PARAMETERS-structure ) - */ - if ((ret->pkey.ec= EC_KEY_new()) == NULL) - { - X509err(X509_F_X509_PUBKEY_GET, - ERR_R_MALLOC_FAILURE); - goto err; - } - cp = p = a->parameter->value.sequence->data; - j = a->parameter->value.sequence->length; - if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j)) - { - X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB); - goto err; - } - } - else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT)) - { - /* type == V_ASN1_OBJECT => the parameters are given - * by an asn1 OID - */ - EC_KEY *ec_key; - EC_GROUP *group; - - if (ret->pkey.ec == NULL) - ret->pkey.ec = EC_KEY_new(); - ec_key = ret->pkey.ec; - if (ec_key == NULL) - goto err; - group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); - if (group == NULL) - goto err; - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(ec_key, group) == 0) - goto err; - EC_GROUP_free(group); + X509err(X509_F_X509_PUBKEY_GET, + X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; } - /* the case implicitlyCA is currently not implemented */ - ret->save_parameters = 1; } -#endif - - p=key->public_key->data; - j=key->public_key->length; - if (!d2i_PublicKey(type, &ret, &p, (long)j)) + else { - X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); - goto err; + X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED); + goto error; } key->pkey = ret; CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); - return(ret); -err: + + return ret; + + error: if (ret != NULL) EVP_PKEY_free(ret); return(NULL); @@ -529,3 +335,39 @@ int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) return(ret); } #endif + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen) + { + if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) + return 0; + if (penc) + { + if (pub->public_key->data) + OPENSSL_free(pub->public_key->data); + pub->public_key->data = penc; + pub->public_key->length = penclen; + /* Set number of unused bits to zero */ + pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; + } + return 1; + } + +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub) + { + if (ppkalg) + *ppkalg = pub->algor->algorithm; + if (pk) + { + *pk = pub->public_key->data; + *ppklen = pub->public_key->length; + } + if (pa) + *pa = pub->algor; + return 1; + } diff --git a/crypto/openssl/crypto/asn1/x_req.c b/crypto/openssl/crypto/asn1/x_req.c index 59ca8ce329..d57555827c 100644 --- a/crypto/openssl/crypto/asn1/x_req.c +++ b/crypto/openssl/crypto/asn1/x_req.c @@ -79,7 +79,8 @@ * */ -static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; diff --git a/crypto/openssl/crypto/asn1/x_x509.c b/crypto/openssl/crypto/asn1/x_x509.c index e118696625..dafd3cc921 100644 --- a/crypto/openssl/crypto/asn1/x_x509.c +++ b/crypto/openssl/crypto/asn1/x_x509.c @@ -81,7 +81,8 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) extern void policy_cache_free(X509_POLICY_CACHE *cache); -static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { X509 *ret = (X509 *)*pval; @@ -99,6 +100,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) ret->rfc3779_asid = NULL; #endif ret->aux = NULL; + ret->crldp = NULL; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); break; @@ -112,7 +114,10 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) X509_CERT_AUX_free(ret->aux); ASN1_OCTET_STRING_free(ret->skid); AUTHORITY_KEYID_free(ret->akid); + CRL_DIST_POINTS_free(ret->crldp); policy_cache_free(ret->policy_cache); + GENERAL_NAMES_free(ret->altname); + NAME_CONSTRAINTS_free(ret->nc); #ifndef OPENSSL_NO_RFC3779 sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); ASIdentifiers_free(ret->rfc3779_asid); @@ -136,19 +141,6 @@ ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { IMPLEMENT_ASN1_FUNCTIONS(X509) IMPLEMENT_ASN1_DUP_FUNCTION(X509) -static ASN1_METHOD meth= - { - (I2D_OF(void)) i2d_X509, - (D2I_OF(void)) d2i_X509, - (void *(*)(void))X509_new, - (void (*)(void *)) X509_free - }; - -ASN1_METHOD *X509_asn1_meth(void) - { - return(&meth); - } - int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { diff --git a/crypto/openssl/crypto/bf/bf_skey.c b/crypto/openssl/crypto/bf/bf_skey.c index 6ac2aeb279..3673cdee6e 100644 --- a/crypto/openssl/crypto/bf/bf_skey.c +++ b/crypto/openssl/crypto/bf/bf_skey.c @@ -59,15 +59,10 @@ #include #include #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - #include "bf_locl.h" #include "bf_pi.h" -FIPS_NON_FIPS_VCIPHER_Init(BF) +void BF_set_key(BF_KEY *key, int len, const unsigned char *data) { int i; BF_LONG *p,ri,in[2]; diff --git a/crypto/openssl/crypto/bf/blowfish.h b/crypto/openssl/crypto/bf/blowfish.h index d24ffccb65..b97e76f9a3 100644 --- a/crypto/openssl/crypto/bf/blowfish.h +++ b/crypto/openssl/crypto/bf/blowfish.h @@ -79,7 +79,7 @@ extern "C" { * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#if defined(__LP32__) #define BF_LONG unsigned long #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) #define BF_LONG unsigned long @@ -104,9 +104,7 @@ typedef struct bf_key_st BF_LONG S[4*256]; } BF_KEY; -#ifdef OPENSSL_FIPS -void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); -#endif + void BF_set_key(BF_KEY *key, int len, const unsigned char *data); void BF_encrypt(BF_LONG *data,const BF_KEY *key); diff --git a/crypto/openssl/crypto/bio/b_print.c b/crypto/openssl/crypto/bio/b_print.c index 3a87b0ec0b..143a7cfefa 100644 --- a/crypto/openssl/crypto/bio/b_print.c +++ b/crypto/openssl/crypto/bio/b_print.c @@ -115,8 +115,8 @@ #define LDOUBLE double #endif -#if HAVE_LONG_LONG -# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) +#ifdef HAVE_LONG_LONG +# if defined(_WIN32) && !defined(__GNUC__) # define LLONG __int64 # else # define LLONG long long diff --git a/crypto/openssl/crypto/bio/b_sock.c b/crypto/openssl/crypto/bio/b_sock.c index ead477d8a2..12b0a53a81 100644 --- a/crypto/openssl/crypto/bio/b_sock.c +++ b/crypto/openssl/crypto/bio/b_sock.c @@ -72,11 +72,9 @@ NETDB_DEFINE_CONTEXT #ifndef OPENSSL_NO_SOCK -#ifdef OPENSSL_SYS_WIN16 -#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ -#else +#include + #define SOCKET_PROTOCOL IPPROTO_TCP -#endif #ifdef SO_MAXCONN #define MAX_LISTEN SO_MAXCONN @@ -90,6 +88,17 @@ NETDB_DEFINE_CONTEXT static int wsa_init_done=0; #endif +/* + * WSAAPI specifier is required to make indirect calls to run-time + * linked WinSock 2 functions used in this module, to be specific + * [get|free]addrinfo and getnameinfo. This is because WinSock uses + * uses non-C calling convention, __stdcall vs. __cdecl, on x86 + * Windows. On non-WinSock platforms WSAAPI needs to be void. + */ +#ifndef WSAAPI +#define WSAAPI +#endif + #if 0 static unsigned long BIO_ghbn_hits=0L; static unsigned long BIO_ghbn_miss=0L; @@ -226,6 +235,10 @@ int BIO_sock_error(int sock) int j,i; int size; +#if defined(OPENSSL_SYS_BEOS_R5) + return 0; +#endif + size=sizeof(int); /* Note: under Windows the third parameter is of type (char *) * whereas under other systems it is (void *) if you don't have @@ -466,7 +479,12 @@ int BIO_sock_init(void) wsa_init_done=1; memset(&wsa_state,0,sizeof(wsa_state)); - if (WSAStartup(0x0101,&wsa_state)!=0) + /* Not making wsa_state available to the rest of the + * code is formally wrong. But the structures we use + * are [beleived to be] invariable among Winsock DLLs, + * while API availability is [expected to be] probed + * at run-time with DSO_global_lookup. */ + if (WSAStartup(0x0202,&wsa_state)!=0) { err=WSAGetLastError(); SYSerr(SYS_F_WSASTARTUP,err); @@ -510,8 +528,8 @@ void BIO_sock_cleanup(void) if (wsa_init_done) { wsa_init_done=0; -#ifndef OPENSSL_SYS_WINCE - WSACancelBlockingCall(); /* Winsock 1.1 specific */ +#if 0 /* this call is claimed to be non-present in Winsock2 */ + WSACancelBlockingCall(); #endif WSACleanup(); } @@ -581,12 +599,18 @@ static int get_ip(const char *str, unsigned char ip[4]) int BIO_get_accept_socket(char *host, int bind_mode) { int ret=0; - struct sockaddr_in server,client; - int s=INVALID_SOCKET,cs; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } server,client; + int s=INVALID_SOCKET,cs,addrlen; unsigned char ip[4]; unsigned short port; char *str=NULL,*e; - const char *h,*p; + char *h,*p; unsigned long l; int err_num; @@ -600,8 +624,7 @@ int BIO_get_accept_socket(char *host, int bind_mode) { if (*e == ':') { - p= &(e[1]); - *e='\0'; + p=e; } else if (*e == '/') { @@ -609,21 +632,70 @@ int BIO_get_accept_socket(char *host, int bind_mode) break; } } - - if (p == NULL) + if (p) *p++='\0'; /* points at last ':', '::port' is special [see below] */ + else p=h,h=NULL; + +#ifdef EAI_FAMILY + do { + static union { void *p; + int (WSAAPI *f)(const char *,const char *, + const struct addrinfo *, + struct addrinfo **); + } p_getaddrinfo = {NULL}; + static union { void *p; + void (WSAAPI *f)(struct addrinfo *); + } p_freeaddrinfo = {NULL}; + struct addrinfo *res,hint; + + if (p_getaddrinfo.p==NULL) + { + if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL || + (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL) + p_getaddrinfo.p=(void*)-1; + } + if (p_getaddrinfo.p==(void *)-1) break; + + /* '::port' enforces IPv6 wildcard listener. Some OSes, + * e.g. Solaris, default to IPv6 without any hint. Also + * note that commonly IPv6 wildchard socket can service + * IPv4 connections just as well... */ + memset(&hint,0,sizeof(hint)); + if (h) { - p=h; - h="*"; + if (strchr(h,':')) + { + if (h[1]=='\0') h=NULL; +#if OPENSSL_USE_IPV6 + hint.ai_family = AF_INET6; +#else + h=NULL; +#endif + } + else if (h[0]=='*' && h[1]=='\0') + h=NULL; } + if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break; + + addrlen = res->ai_addrlen<=sizeof(server) ? + res->ai_addrlen : + sizeof(server); + memcpy(&server, res->ai_addr, addrlen); + + (*p_freeaddrinfo.f)(res); + goto again; + } while (0); +#endif + if (!BIO_get_port(p,&port)) goto err; memset((char *)&server,0,sizeof(server)); - server.sin_family=AF_INET; - server.sin_port=htons(port); + server.sa_in.sin_family=AF_INET; + server.sa_in.sin_port=htons(port); + addrlen = sizeof(server.sa_in); - if (strcmp(h,"*") == 0) - server.sin_addr.s_addr=INADDR_ANY; + if (h == NULL || strcmp(h,"*") == 0) + server.sa_in.sin_addr.s_addr=INADDR_ANY; else { if (!BIO_get_host_ip(h,&(ip[0]))) goto err; @@ -632,11 +704,11 @@ int BIO_get_accept_socket(char *host, int bind_mode) ((unsigned long)ip[1]<<16L)| ((unsigned long)ip[2]<< 8L)| ((unsigned long)ip[3]); - server.sin_addr.s_addr=htonl(l); + server.sa_in.sin_addr.s_addr=htonl(l); } again: - s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); + s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL); if (s == INVALID_SOCKET) { SYSerr(SYS_F_SOCKET,get_last_socket_error()); @@ -654,22 +726,42 @@ again: bind_mode=BIO_BIND_NORMAL; } #endif - if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) + if (bind(s,&server.sa,addrlen) == -1) { #ifdef SO_REUSEADDR err_num=get_last_socket_error(); if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && +#ifdef OPENSSL_SYS_WINDOWS + /* Some versions of Windows define EADDRINUSE to + * a dummy value. + */ + (err_num == WSAEADDRINUSE)) +#else (err_num == EADDRINUSE)) +#endif { - memcpy((char *)&client,(char *)&server,sizeof(server)); - if (strcmp(h,"*") == 0) - client.sin_addr.s_addr=htonl(0x7F000001); - cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); + client = server; + if (h == NULL || strcmp(h,"*") == 0) + { +#if OPENSSL_USE_IPV6 + if (client.sa.sa_family == AF_INET6) + { + memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr)); + client.sa_in6.sin6_addr.s6_addr[15]=1; + } + else +#endif + if (client.sa.sa_family == AF_INET) + { + client.sa_in.sin_addr.s_addr=htonl(0x7F000001); + } + else goto err; + } + cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL); if (cs != INVALID_SOCKET) { int ii; - ii=connect(cs,(struct sockaddr *)&client, - sizeof(client)); + ii=connect(cs,&client.sa,addrlen); closesocket(cs); if (ii == INVALID_SOCKET) { @@ -708,20 +800,52 @@ err: int BIO_accept(int sock, char **addr) { int ret=INVALID_SOCKET; - static struct sockaddr_in from; unsigned long l; unsigned short port; - int len; char *p; - memset((char *)&from,0,sizeof(from)); - len=sizeof(from); - /* Note: under VMS with SOCKETSHR the fourth parameter is currently - * of type (int *) whereas under other systems it is (void *) if - * you don't have a cast it will choke the compiler: if you do - * have a cast then you can either go for (int *) or (void *). + struct { + /* + * As for following union. Trouble is that there are platforms + * that have socklen_t and there are platforms that don't, on + * some platforms socklen_t is int and on some size_t. So what + * one can do? One can cook #ifdef spaghetti, which is nothing + * but masochistic. Or one can do union between int and size_t. + * One naturally does it primarily for 64-bit platforms where + * sizeof(int) != sizeof(size_t). But would it work? Note that + * if size_t member is initialized to 0, then later int member + * assignment naturally does the job on little-endian platforms + * regardless accept's expectations! What about big-endians? + * If accept expects int*, then it works, and if size_t*, then + * length value would appear as unreasonably large. But this + * won't prevent it from filling in the address structure. The + * trouble of course would be if accept returns more data than + * actual buffer can accomodate and overwrite stack... That's + * where early OPENSSL_assert comes into picture. Besides, the + * only 64-bit big-endian platform found so far that expects + * size_t* is HP-UX, where stack grows towards higher address. + * */ - ret=accept(sock,(struct sockaddr *)&from,(void *)&len); + union { size_t s; int i; } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } from; + } sa; + + sa.len.s=0; + sa.len.i=sizeof(sa.from); + memset(&sa.from,0,sizeof(sa.from)); + ret=accept(sock,&sa.from.sa,(void *)&sa.len); + if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) + { + OPENSSL_assert(sa.len.s<=sizeof(sa.from)); + sa.len.i = (int)sa.len.s; + /* use sa.len.i from this point */ + } if (ret == INVALID_SOCKET) { if(BIO_sock_should_retry(ret)) return -2; @@ -732,8 +856,46 @@ int BIO_accept(int sock, char **addr) if (addr == NULL) goto end; - l=ntohl(from.sin_addr.s_addr); - port=ntohs(from.sin_port); +#ifdef EAI_FAMILY + do { + char h[NI_MAXHOST],s[NI_MAXSERV]; + size_t nl; + static union { void *p; + int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/, + char *,size_t,char *,size_t,int); + } p_getnameinfo = {NULL}; + /* 2nd argument to getnameinfo is specified to + * be socklen_t. Unfortunately there is a number + * of environments where socklen_t is not defined. + * As it's passed by value, it's safe to pass it + * as size_t... */ + + if (p_getnameinfo.p==NULL) + { + if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL) + p_getnameinfo.p=(void*)-1; + } + if (p_getnameinfo.p==(void *)-1) break; + + if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s), + NI_NUMERICHOST|NI_NUMERICSERV)) break; + nl = strlen(h)+strlen(s)+2; + p = *addr; + if (p) { *p = '\0'; p = OPENSSL_realloc(p,nl); } + else { p = OPENSSL_malloc(nl); } + if (p==NULL) + { + BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE); + goto end; + } + *addr = p; + BIO_snprintf(*addr,nl,"%s:%s",h,s); + goto end; + } while(0); +#endif + if (sa.from.sa.sa_family != AF_INET) goto end; + l=ntohl(sa.from.sa_in.sin_addr.s_addr); + port=ntohs(sa.from.sa_in.sin_port); if (*addr == NULL) { if ((p=OPENSSL_malloc(24)) == NULL) diff --git a/crypto/openssl/crypto/bio/bio.h b/crypto/openssl/crypto/bio/bio.h index ebb42781e6..152802fbdf 100644 --- a/crypto/openssl/crypto/bio/bio.h +++ b/crypto/openssl/crypto/bio/bio.h @@ -95,6 +95,7 @@ extern "C" { #define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ #define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */ #define BIO_TYPE_DGRAM (21|0x0400|0x0100) +#define BIO_TYPE_ASN1 (22|0x0200) /* filter */ #define BIO_TYPE_COMP (23|0x0200) /* filter */ #define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ @@ -265,7 +266,6 @@ int BIO_method_type(const BIO *b); typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long); -#ifndef OPENSSL_SYS_WIN16 typedef struct bio_method_st { int type; @@ -279,21 +279,6 @@ typedef struct bio_method_st int (*destroy)(BIO *); long (*callback_ctrl)(BIO *, int, bio_info_cb *); } BIO_METHOD; -#else -typedef struct bio_method_st - { - int type; - const char *name; - int (_far *bwrite)(); - int (_far *bread)(); - int (_far *bputs)(); - int (_far *bgets)(); - long (_far *ctrl)(); - int (_far *create)(); - int (_far *destroy)(); - long (_far *callback_ctrl)(); - } BIO_METHOD; -#endif struct bio_st { @@ -334,6 +319,9 @@ typedef struct bio_f_buffer_ctx_struct int obuf_off; /* write/read offset */ } BIO_F_BUFFER_CTX; +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg); + /* connect BIO stuff */ #define BIO_CONN_S_BEFORE 1 #define BIO_CONN_S_GET_IP 2 @@ -396,6 +384,13 @@ typedef struct bio_f_buffer_ctx_struct #define BIO_C_RESET_READ_REQUEST 147 #define BIO_C_SET_MD_CTX 148 +#define BIO_C_SET_PREFIX 149 +#define BIO_C_GET_PREFIX 150 +#define BIO_C_SET_SUFFIX 151 +#define BIO_C_GET_SUFFIX 152 + +#define BIO_C_SET_EX_ARG 153 +#define BIO_C_GET_EX_ARG 154 #define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) #define BIO_get_app_data(s) BIO_get_ex_data(s,0) @@ -559,22 +554,21 @@ int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, unsigned long BIO_number_read(BIO *bio); unsigned long BIO_number_written(BIO *bio); +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + # ifndef OPENSSL_NO_FP_API -# if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL) -BIO_METHOD *BIO_s_file_internal(void); -BIO *BIO_new_file_internal(char *filename, char *mode); -BIO *BIO_new_fp_internal(FILE *stream, int close_flag); -# define BIO_s_file BIO_s_file_internal -# define BIO_new_file BIO_new_file_internal -# define BIO_new_fp BIO_new_fp_internal -# else /* FP_API */ BIO_METHOD *BIO_s_file(void ); BIO *BIO_new_file(const char *filename, const char *mode); BIO *BIO_new_fp(FILE *stream, int close_flag); -# define BIO_s_file_internal BIO_s_file -# define BIO_new_file_internal BIO_new_file -# define BIO_new_fp_internal BIO_s_file -# endif /* FP_API */ +# define BIO_s_file_internal BIO_s_file # endif BIO * BIO_new(BIO_METHOD *type); int BIO_set(BIO *a,BIO_METHOD *type); @@ -603,13 +597,8 @@ int BIO_nread(BIO *bio, char **buf, int num); int BIO_nwrite0(BIO *bio, char **buf); int BIO_nwrite(BIO *bio, char **buf, int num); -#ifndef OPENSSL_SYS_WIN16 long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, long argl,long ret); -#else -long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, - long argl,long ret); -#endif BIO_METHOD *BIO_s_mem(void); BIO *BIO_new_mem_buf(void *buf, int len); diff --git a/crypto/openssl/crypto/bio/bio_cb.c b/crypto/openssl/crypto/bio/bio_cb.c index 6f4254a114..9bcbc321d9 100644 --- a/crypto/openssl/crypto/bio/bio_cb.c +++ b/crypto/openssl/crypto/bio/bio_cb.c @@ -85,28 +85,32 @@ long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp, break; case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s fd=%d\n", - bio->num,argi,bio->method->name,bio->num); + BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s fd=%d\n", + bio->num,(unsigned long)argi, + bio->method->name,bio->num); else - BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s\n", - bio->num,argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s\n", + bio->num,(unsigned long)argi, + bio->method->name); break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s fd=%d\n", - bio->num,argi,bio->method->name,bio->num); + BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s fd=%d\n", + bio->num,(unsigned long)argi, + bio->method->name,bio->num); else - BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s\n", - bio->num,argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s\n", + bio->num,(unsigned long)argi, + bio->method->name); break; case BIO_CB_PUTS: BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name); break; case BIO_CB_GETS: - BIO_snprintf(p,p_maxlen,"gets(%d) - %s\n",argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"gets(%lu) - %s\n",(unsigned long)argi,bio->method->name); break; case BIO_CB_CTRL: - BIO_snprintf(p,p_maxlen,"ctrl(%d) - %s\n",argi,bio->method->name); + BIO_snprintf(p,p_maxlen,"ctrl(%lu) - %s\n",(unsigned long)argi,bio->method->name); break; case BIO_CB_RETURN|BIO_CB_READ: BIO_snprintf(p,p_maxlen,"read return %ld\n",ret); diff --git a/crypto/openssl/crypto/bio/bio_err.c b/crypto/openssl/crypto/bio/bio_err.c index 6603f1c74d..a224edd5a0 100644 --- a/crypto/openssl/crypto/bio/bio_err.c +++ b/crypto/openssl/crypto/bio/bio_err.c @@ -1,6 +1,6 @@ /* crypto/bio/bio_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/bio/bio_lcl.h b/crypto/openssl/crypto/bio/bio_lcl.h index dba2919d43..e7f7ec8d8b 100644 --- a/crypto/openssl/crypto/bio/bio_lcl.h +++ b/crypto/openssl/crypto/bio/bio_lcl.h @@ -18,11 +18,19 @@ #define UP_ftell ftell #define UP_fflush fflush #define UP_ferror ferror +#ifdef _WIN32 +#define UP_fileno _fileno +#define UP_open _open +#define UP_read _read +#define UP_write _write +#define UP_lseek _lseek +#define UP_close _close +#else #define UP_fileno fileno - #define UP_open open #define UP_read read #define UP_write write #define UP_lseek lseek #define UP_close close #endif +#endif diff --git a/crypto/openssl/crypto/bio/bio_lib.c b/crypto/openssl/crypto/bio/bio_lib.c index 3f52ae953c..77f4de9c32 100644 --- a/crypto/openssl/crypto/bio/bio_lib.c +++ b/crypto/openssl/crypto/bio/bio_lib.c @@ -429,7 +429,7 @@ BIO *BIO_push(BIO *b, BIO *bio) if (bio != NULL) bio->prev_bio=lb; /* called to do internal processing */ - BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL); + BIO_ctrl(b,BIO_CTRL_PUSH,0,lb); return(b); } @@ -441,7 +441,7 @@ BIO *BIO_pop(BIO *b) if (b == NULL) return(NULL); ret=b->next_bio; - BIO_ctrl(b,BIO_CTRL_POP,0,NULL); + BIO_ctrl(b,BIO_CTRL_POP,0,b); if (b->prev_bio != NULL) b->prev_bio->next_bio=b->next_bio; diff --git a/crypto/openssl/crypto/bio/bss_acpt.c b/crypto/openssl/crypto/bio/bss_acpt.c index d090b7272f..826f761143 100644 --- a/crypto/openssl/crypto/bio/bss_acpt.c +++ b/crypto/openssl/crypto/bio/bss_acpt.c @@ -100,8 +100,8 @@ static int acpt_new(BIO *h); static int acpt_free(BIO *data); static int acpt_state(BIO *b, BIO_ACCEPT *c); static void acpt_close_socket(BIO *data); -BIO_ACCEPT *BIO_ACCEPT_new(void ); -void BIO_ACCEPT_free(BIO_ACCEPT *a); +static BIO_ACCEPT *BIO_ACCEPT_new(void ); +static void BIO_ACCEPT_free(BIO_ACCEPT *a); #define ACPT_S_BEFORE 1 #define ACPT_S_GET_ACCEPT_SOCKET 2 @@ -141,7 +141,7 @@ static int acpt_new(BIO *bi) return(1); } -BIO_ACCEPT *BIO_ACCEPT_new(void) +static BIO_ACCEPT *BIO_ACCEPT_new(void) { BIO_ACCEPT *ret; @@ -154,7 +154,7 @@ BIO_ACCEPT *BIO_ACCEPT_new(void) return(ret); } -void BIO_ACCEPT_free(BIO_ACCEPT *a) +static void BIO_ACCEPT_free(BIO_ACCEPT *a) { if(a == NULL) return; diff --git a/crypto/openssl/crypto/bio/bss_dgram.c b/crypto/openssl/crypto/bio/bss_dgram.c index 14ca854b4a..eb7e365467 100644 --- a/crypto/openssl/crypto/bio/bss_dgram.c +++ b/crypto/openssl/crypto/bio/bss_dgram.c @@ -108,7 +108,13 @@ static BIO_METHOD methods_dgramp= typedef struct bio_dgram_data_st { - struct sockaddr peer; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } peer; unsigned int connected; unsigned int _errno; unsigned int mtu; @@ -274,24 +280,38 @@ static int dgram_read(BIO *b, char *out, int outl) int ret=0; bio_dgram_data *data = (bio_dgram_data *)b->ptr; - struct sockaddr peer; - int peerlen = sizeof(peer); + struct { + /* + * See commentary in b_sock.c. + */ + union { size_t s; int i; } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } peer; + } sa; + + sa.len.s=0; + sa.len.i=sizeof(sa.peer); if (out != NULL) { clear_socket_error(); - memset(&peer, 0x00, peerlen); - /* Last arg in recvfrom is signed on some platforms and - * unsigned on others. It is of type socklen_t on some - * but this is not universal. Cast to (void *) to avoid - * compiler warnings. - */ + memset(&sa.peer, 0x00, sizeof(sa.peer)); dgram_adjust_rcv_timeout(b); - ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); + ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len); + if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) + { + OPENSSL_assert(sa.len.s<=sizeof(sa.peer)); + sa.len.i = (int)sa.len.s; + } dgram_reset_rcv_timeout(b); if ( ! data->connected && ret >= 0) - BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer); + BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); BIO_clear_retry_flags(b); if (ret < 0) @@ -312,14 +332,24 @@ static int dgram_write(BIO *b, const char *in, int inl) bio_dgram_data *data = (bio_dgram_data *)b->ptr; clear_socket_error(); - if ( data->connected ) - ret=writesocket(b->num,in,inl); - else + if ( data->connected ) + ret=writesocket(b->num,in,inl); + else + { + int peerlen = sizeof(data->peer); + + if (data->peer.sa.sa_family == AF_INET) + peerlen = sizeof(data->peer.sa_in); +#if OPENSSL_USE_IVP6 + else if (data->peer.sa.sa_family == AF_INET6) + peerlen = sizeof(data->peer.sa_in6); +#endif #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) - ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); + ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); #else - ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); + ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); #endif + } BIO_clear_retry_flags(b); if (ret <= 0) @@ -351,7 +381,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) #endif #ifdef OPENSSL_SYS_LINUX socklen_t addr_len; - struct sockaddr_storage addr; + union { + struct sockaddr sa; + struct sockaddr_in s4; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 s6; +#endif + } addr; #endif data = (bio_dgram_data *)b->ptr; @@ -405,7 +441,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) else { #endif - memcpy(&(data->peer),to, sizeof(struct sockaddr)); + switch (to->sa_family) + { + case AF_INET: + memcpy(&data->peer,to,sizeof(data->peer.sa_in)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); + break; +#endif + default: + memcpy(&data->peer,to,sizeof(data->peer.sa)); + break; + } #if 0 } #endif @@ -413,15 +462,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) /* (Linux)kernel sets DF bit on outgoing IP packets */ case BIO_CTRL_DGRAM_MTU_DISCOVER: #ifdef OPENSSL_SYS_LINUX - addr_len = (socklen_t)sizeof(struct sockaddr_storage); - memset((void *)&addr, 0, sizeof(struct sockaddr_storage)); - if (getsockname(b->num, (void *)&addr, &addr_len) < 0) + addr_len = (socklen_t)sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { ret = 0; break; } sockopt_len = sizeof(sockopt_val); - switch (addr.ss_family) + switch (addr.sa.sa_family) { case AF_INET: sockopt_val = IP_PMTUDISC_DO; @@ -429,12 +478,14 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) &sockopt_val, sizeof(sockopt_val))) < 0) perror("setsockopt"); break; +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) case AF_INET6: sockopt_val = IPV6_PMTUDISC_DO; if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &sockopt_val, sizeof(sockopt_val))) < 0) perror("setsockopt"); break; +#endif default: ret = -1; break; @@ -445,15 +496,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) #endif case BIO_CTRL_DGRAM_QUERY_MTU: #ifdef OPENSSL_SYS_LINUX - addr_len = (socklen_t)sizeof(struct sockaddr_storage); - memset((void *)&addr, 0, sizeof(struct sockaddr_storage)); - if (getsockname(b->num, (void *)&addr, &addr_len) < 0) + addr_len = (socklen_t)sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { ret = 0; break; } sockopt_len = sizeof(sockopt_val); - switch (addr.ss_family) + switch (addr.sa.sa_family) { case AF_INET: if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, @@ -470,6 +521,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = data->mtu; } break; +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU) case AF_INET6: if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val, &sockopt_len)) < 0 || sockopt_val < 0) @@ -485,6 +537,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = data->mtu; } break; +#endif default: ret = 0; break; @@ -506,27 +559,65 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) if ( to != NULL) { data->connected = 1; - memcpy(&(data->peer),to, sizeof(struct sockaddr)); + switch (to->sa_family) + { + case AF_INET: + memcpy(&data->peer,to,sizeof(data->peer.sa_in)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); + break; +#endif + default: + memcpy(&data->peer,to,sizeof(data->peer.sa)); + break; + } } else { data->connected = 0; - memset(&(data->peer), 0x00, sizeof(struct sockaddr)); + memset(&(data->peer), 0x00, sizeof(data->peer)); + } + break; + case BIO_CTRL_DGRAM_GET_PEER: + switch (data->peer.sa.sa_family) + { + case AF_INET: + ret=sizeof(data->peer.sa_in); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + ret=sizeof(data->peer.sa_in6); + break; +#endif + default: + ret=sizeof(data->peer.sa); + break; + } + if (num==0 || num>ret) + num=ret; + memcpy(ptr,&data->peer,(ret=num)); + break; + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *) ptr; + switch (to->sa_family) + { + case AF_INET: + memcpy(&data->peer,to,sizeof(data->peer.sa_in)); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); + break; +#endif + default: + memcpy(&data->peer,to,sizeof(data->peer.sa)); + break; } break; - case BIO_CTRL_DGRAM_GET_PEER: - to = (struct sockaddr *) ptr; - - memcpy(to, &(data->peer), sizeof(struct sockaddr)); - ret = sizeof(struct sockaddr); - break; - case BIO_CTRL_DGRAM_SET_PEER: - to = (struct sockaddr *) ptr; - - memcpy(&(data->peer), to, sizeof(struct sockaddr)); - break; case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); break; #if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: diff --git a/crypto/openssl/crypto/bio/bss_fd.c b/crypto/openssl/crypto/bio/bss_fd.c index 4c229bf641..d1bf85aae1 100644 --- a/crypto/openssl/crypto/bio/bss_fd.c +++ b/crypto/openssl/crypto/bio/bss_fd.c @@ -60,6 +60,13 @@ #include #define USE_SOCKETS #include "cryptlib.h" + +#if defined(OPENSSL_NO_POSIX_IO) +/* + * One can argue that one should implement dummy placeholder for + * BIO_s_fd here... + */ +#else /* * As for unconditional usage of "UPLINK" interface in this module. * Trouble is that unlike Unix file descriptors [which are indexes @@ -77,6 +84,7 @@ static int fd_write(BIO *h, const char *buf, int num); static int fd_read(BIO *h, char *buf, int size); static int fd_puts(BIO *h, const char *str); +static int fd_gets(BIO *h, char *buf, int size); static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int fd_new(BIO *h); static int fd_free(BIO *data); @@ -88,7 +96,7 @@ static BIO_METHOD methods_fdp= fd_write, fd_read, fd_puts, - NULL, /* fd_gets, */ + fd_gets, fd_ctrl, fd_new, fd_free, @@ -227,6 +235,22 @@ static int fd_puts(BIO *bp, const char *str) return(ret); } +static int fd_gets(BIO *bp, char *buf, int size) + { + int ret=0; + char *ptr=buf; + char *end=buf+size-1; + + while ( (ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n') ) + ptr++; + + ptr[0]='\0'; + + if (buf[0] != '\0') + ret=strlen(buf); + return(ret); + } + int BIO_fd_should_retry(int i) { int err; @@ -292,3 +316,4 @@ int BIO_fd_non_fatal_error(int err) } return(0); } +#endif diff --git a/crypto/openssl/crypto/bio/bss_file.c b/crypto/openssl/crypto/bio/bss_file.c index 62c10731d4..8bfa0bcd97 100644 --- a/crypto/openssl/crypto/bio/bss_file.c +++ b/crypto/openssl/crypto/bio/bss_file.c @@ -118,10 +118,47 @@ static BIO_METHOD methods_filep= BIO *BIO_new_file(const char *filename, const char *mode) { - BIO *ret; - FILE *file; + BIO *ret; + FILE *file=NULL; + +#if defined(_WIN32) && defined(CP_UTF8) + int sz, len_0 = (int)strlen(filename)+1; - if ((file=fopen(filename,mode)) == NULL) + /* + * Basically there are three cases to cover: a) filename is + * pure ASCII string; b) actual UTF-8 encoded string and + * c) locale-ized string, i.e. one containing 8-bit + * characters that are meaningful in current system locale. + * If filename is pure ASCII or real UTF-8 encoded string, + * MultiByteToWideChar succeeds and _wfopen works. If + * filename is locale-ized string, chances are that + * MultiByteToWideChar fails reporting + * ERROR_NO_UNICODE_TRANSLATION, in which case we fall + * back to fopen... + */ + if ((sz=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,NULL,0))>0) + { + WCHAR wmode[8]; + WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); + + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,wfilename,sz) && + MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1, + wmode,sizeof(wmode)/sizeof(wmode[0])) && + (file=_wfopen(wfilename,wmode))==NULL && errno==ENOENT + ) /* UTF-8 decode succeeded, but no file, filename + * could still have been locale-ized... */ + file = fopen(filename,mode); + } + else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) + { + file = fopen(filename,mode); + } +#else + file=fopen(filename,mode); +#endif + if (file == NULL) { SYSerr(SYS_F_FOPEN,get_last_sys_error()); ERR_add_error_data(5,"fopen('",filename,"','",mode,"')"); @@ -131,7 +168,7 @@ BIO *BIO_new_file(const char *filename, const char *mode) BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB); return(NULL); } - if ((ret=BIO_new(BIO_s_file_internal())) == NULL) + if ((ret=BIO_new(BIO_s_file())) == NULL) { fclose(file); return(NULL); @@ -272,9 +309,9 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_clear_flags(b,BIO_FLAGS_UPLINK); #endif #endif -#ifdef UP_fsetmode +#ifdef UP_fsetmod if (b->flags&BIO_FLAGS_UPLINK) - UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b'); + UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b')); else #endif { @@ -286,8 +323,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) _setmode(fd,_O_BINARY); #elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) int fd = fileno((FILE*)ptr); - /* Under CLib there are differences in file modes - */ + /* Under CLib there are differences in file modes */ if (num & BIO_FP_TEXT) setmode(fd,O_TEXT); else @@ -308,7 +344,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) else _setmode(fd,_O_BINARY); } -#elif defined(OPENSSL_SYS_OS2) +#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) int fd = fileno((FILE*)ptr); if (num & BIO_FP_TEXT) setmode(fd, O_TEXT); diff --git a/crypto/openssl/crypto/bio/bss_log.c b/crypto/openssl/crypto/bio/bss_log.c index 6360dbc820..7ead044b37 100644 --- a/crypto/openssl/crypto/bio/bss_log.c +++ b/crypto/openssl/crypto/bio/bss_log.c @@ -70,7 +70,6 @@ #if defined(OPENSSL_SYS_WINCE) #elif defined(OPENSSL_SYS_WIN32) -# include #elif defined(OPENSSL_SYS_VMS) # include # include @@ -122,18 +121,6 @@ static int MS_CALLBACK slg_free(BIO *data); static void xopenlog(BIO* bp, char* name, int level); static void xsyslog(BIO* bp, int priority, const char* string); static void xcloselog(BIO* bp); -#ifdef OPENSSL_SYS_WIN32 -LONG (WINAPI *go_for_advapi)() = RegOpenKeyEx; -HANDLE (WINAPI *register_event_source)() = NULL; -BOOL (WINAPI *deregister_event_source)() = NULL; -BOOL (WINAPI *report_event)() = NULL; -#define DL_PROC(m,f) (GetProcAddress( m, f )) -#ifdef UNICODE -#define DL_PROC_X(m,f) DL_PROC( m, f "W" ) -#else -#define DL_PROC_X(m,f) DL_PROC( m, f "A" ) -#endif -#endif static BIO_METHOD methods_slg= { @@ -175,7 +162,7 @@ static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) char* buf; char* pp; int priority, i; - static struct + static const struct { int strl; char str[10]; @@ -249,35 +236,20 @@ static int MS_CALLBACK slg_puts(BIO *bp, const char *str) static void xopenlog(BIO* bp, char* name, int level) { - if ( !register_event_source ) - { - HANDLE advapi; - if ( !(advapi = GetModuleHandle("advapi32")) ) - return; - register_event_source = (HANDLE (WINAPI *)())DL_PROC_X(advapi, - "RegisterEventSource" ); - deregister_event_source = (BOOL (WINAPI *)())DL_PROC(advapi, - "DeregisterEventSource"); - report_event = (BOOL (WINAPI *)())DL_PROC_X(advapi, - "ReportEvent" ); - if ( !(register_event_source && deregister_event_source && - report_event) ) - { - register_event_source = NULL; - deregister_event_source = NULL; - report_event = NULL; - return; - } - } - bp->ptr= (char *)register_event_source(NULL, name); + if (GetVersion() < 0x80000000) + bp->ptr = RegisterEventSourceA(NULL,name); + else + bp->ptr = NULL; } static void xsyslog(BIO *bp, int priority, const char *string) { LPCSTR lpszStrings[2]; WORD evtype= EVENTLOG_ERROR_TYPE; - int pid = _getpid(); - char pidbuf[DECIMAL_SIZE(pid)+4]; + char pidbuf[DECIMAL_SIZE(DWORD)+4]; + + if (bp->ptr == NULL) + return; switch (priority) { @@ -301,19 +273,18 @@ static void xsyslog(BIO *bp, int priority, const char *string) break; } - sprintf(pidbuf, "[%d] ", pid); + sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); lpszStrings[0] = pidbuf; lpszStrings[1] = string; - if(report_event && bp->ptr) - report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0, + ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); } static void xcloselog(BIO* bp) { - if(deregister_event_source && bp->ptr) - deregister_event_source((HANDLE)(bp->ptr)); + if(bp->ptr) + DeregisterEventSource((HANDLE)(bp->ptr)); bp->ptr= NULL; } diff --git a/crypto/openssl/crypto/bio/bss_mem.c b/crypto/openssl/crypto/bio/bss_mem.c index e7ab9cb3a3..37d4194e4b 100644 --- a/crypto/openssl/crypto/bio/bss_mem.c +++ b/crypto/openssl/crypto/bio/bss_mem.c @@ -94,16 +94,18 @@ BIO *BIO_new_mem_buf(void *buf, int len) { BIO *ret; BUF_MEM *b; + size_t sz; + if (!buf) { BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER); return NULL; } - if(len == -1) len = strlen(buf); + sz = (len<0) ? strlen(buf) : (size_t)len; if(!(ret = BIO_new(BIO_s_mem())) ) return NULL; b = (BUF_MEM *)ret->ptr; b->data = buf; - b->length = len; - b->max = len; + b->length = sz; + b->max = sz; ret->flags |= BIO_FLAGS_MEM_RDONLY; /* Since this is static data retrying wont help */ ret->num = 0; @@ -144,22 +146,16 @@ static int mem_read(BIO *b, char *out, int outl) { int ret= -1; BUF_MEM *bm; - int i; - char *from,*to; bm=(BUF_MEM *)b->ptr; BIO_clear_retry_flags(b); - ret=(outl > bm->length)?bm->length:outl; + ret=(outl >=0 && (size_t)outl > bm->length)?(int)bm->length:outl; if ((out != NULL) && (ret > 0)) { memcpy(out,bm->data,ret); bm->length-=ret; - /* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */ if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret; else { - from=(char *)&(bm->data[ret]); - to=(char *)&(bm->data[0]); - for (i=0; ilength; i++) - to[i]=from[i]; + memmove(&(bm->data[0]),&(bm->data[ret]),bm->length); } } else if (bm->length == 0) { diff --git a/crypto/openssl/crypto/bio/bss_sock.c b/crypto/openssl/crypto/bio/bss_sock.c index 30c3ceab46..3df31938c1 100644 --- a/crypto/openssl/crypto/bio/bss_sock.c +++ b/crypto/openssl/crypto/bio/bss_sock.c @@ -172,15 +172,6 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) switch (cmd) { - case BIO_CTRL_RESET: - num=0; - case BIO_C_FILE_SEEK: - ret=0; - break; - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - ret=0; - break; case BIO_C_SET_FD: sock_free(b); b->num= *((int *)ptr); @@ -203,10 +194,6 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_SET_CLOSE: b->shutdown=(int)num; break; - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret=0; - break; case BIO_CTRL_DUP: case BIO_CTRL_FLUSH: ret=1; diff --git a/crypto/openssl/crypto/bn/bn.h b/crypto/openssl/crypto/bn/bn.h index f1719a5877..e484b7fc11 100644 --- a/crypto/openssl/crypto/bn/bn.h +++ b/crypto/openssl/crypto/bn/bn.h @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -77,6 +130,7 @@ #include /* FILE */ #endif #include +#include #ifdef __cplusplus extern "C" { @@ -94,9 +148,11 @@ extern "C" { /* #define BN_DEBUG */ /* #define BN_DEBUG_RAND */ +#ifndef OPENSSL_SMALL_FOOTPRINT #define BN_MUL_COMBA #define BN_SQR_COMBA #define BN_RECURSION +#endif /* This next option uses the C libraries (2 word)/(1 word) function. * If it is not defined, I use my C version (which is slower). @@ -137,6 +193,8 @@ extern "C" { #define BN_DEC_FMT1 "%lu" #define BN_DEC_FMT2 "%019lu" #define BN_DEC_NUM 19 +#define BN_HEX_FMT1 "%lX" +#define BN_HEX_FMT2 "%016lX" #endif /* This is where the long long data type is 64 bits, but long is 32. @@ -162,83 +220,37 @@ extern "C" { #define BN_DEC_FMT1 "%llu" #define BN_DEC_FMT2 "%019llu" #define BN_DEC_NUM 19 +#define BN_HEX_FMT1 "%llX" +#define BN_HEX_FMT2 "%016llX" #endif #ifdef THIRTY_TWO_BIT #ifdef BN_LLONG -# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) +# if defined(_WIN32) && !defined(__GNUC__) # define BN_ULLONG unsigned __int64 +# define BN_MASK (0xffffffffffffffffI64) # else # define BN_ULLONG unsigned long long +# define BN_MASK (0xffffffffffffffffLL) # endif #endif -#define BN_ULONG unsigned long -#define BN_LONG long +#define BN_ULONG unsigned int +#define BN_LONG int #define BN_BITS 64 #define BN_BYTES 4 #define BN_BITS2 32 #define BN_BITS4 16 -#ifdef OPENSSL_SYS_WIN32 -/* VC++ doesn't like the LL suffix */ -#define BN_MASK (0xffffffffffffffffL) -#else -#define BN_MASK (0xffffffffffffffffLL) -#endif #define BN_MASK2 (0xffffffffL) #define BN_MASK2l (0xffff) #define BN_MASK2h1 (0xffff8000L) #define BN_MASK2h (0xffff0000L) #define BN_TBIT (0x80000000L) #define BN_DEC_CONV (1000000000L) -#define BN_DEC_FMT1 "%lu" -#define BN_DEC_FMT2 "%09lu" -#define BN_DEC_NUM 9 -#endif - -#ifdef SIXTEEN_BIT -#ifndef BN_DIV2W -#define BN_DIV2W -#endif -#define BN_ULLONG unsigned long -#define BN_ULONG unsigned short -#define BN_LONG short -#define BN_BITS 32 -#define BN_BYTES 2 -#define BN_BITS2 16 -#define BN_BITS4 8 -#define BN_MASK (0xffffffff) -#define BN_MASK2 (0xffff) -#define BN_MASK2l (0xff) -#define BN_MASK2h1 (0xff80) -#define BN_MASK2h (0xff00) -#define BN_TBIT (0x8000) -#define BN_DEC_CONV (100000) #define BN_DEC_FMT1 "%u" -#define BN_DEC_FMT2 "%05u" -#define BN_DEC_NUM 5 -#endif - -#ifdef EIGHT_BIT -#ifndef BN_DIV2W -#define BN_DIV2W -#endif -#define BN_ULLONG unsigned short -#define BN_ULONG unsigned char -#define BN_LONG char -#define BN_BITS 16 -#define BN_BYTES 1 -#define BN_BITS2 8 -#define BN_BITS4 4 -#define BN_MASK (0xffff) -#define BN_MASK2 (0xff) -#define BN_MASK2l (0xf) -#define BN_MASK2h1 (0xf8) -#define BN_MASK2h (0xf0) -#define BN_TBIT (0x80) -#define BN_DEC_CONV (100) -#define BN_DEC_FMT1 "%u" -#define BN_DEC_FMT2 "%02u" -#define BN_DEC_NUM 2 +#define BN_DEC_FMT2 "%09u" +#define BN_DEC_NUM 9 +#define BN_HEX_FMT1 "%X" +#define BN_HEX_FMT2 "%08X" #endif #define BN_DEFAULT_BITS 1280 @@ -303,12 +315,8 @@ struct bn_mont_ctx_st BIGNUM N; /* The modulus */ BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 * (Ni is only stored for bignum algorithm) */ -#if 0 - /* OpenSSL 0.9.9 preview: */ - BN_ULONG n0[2];/* least significant word(s) of Ni */ -#else - BN_ULONG n0; /* least significant word of Ni */ -#endif + BN_ULONG n0[2];/* least significant word(s) of Ni; + (type changed with 0.9.9, was "BN_ULONG n0;" before) */ int flags; }; @@ -504,6 +512,7 @@ char * BN_bn2hex(const BIGNUM *a); char * BN_bn2dec(const BIGNUM *a); int BN_hex2bn(BIGNUM **a, const char *str); int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); int BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */ BIGNUM *BN_mod_inverse(BIGNUM *ret, @@ -531,17 +540,6 @@ int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb); int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, int do_trial_division, BN_GENCB *cb); -int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); - -int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, - const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); -int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - BIGNUM *Xp1, BIGNUM *Xp2, - const BIGNUM *Xp, - const BIGNUM *e, BN_CTX *ctx, - BN_GENCB *cb); - BN_MONT_CTX *BN_MONT_CTX_new(void ); void BN_MONT_CTX_init(BN_MONT_CTX *ctx); int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b, @@ -560,19 +558,22 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, #define BN_BLINDING_NO_UPDATE 0x00000001 #define BN_BLINDING_NO_RECREATE 0x00000002 -BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod); +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); void BN_BLINDING_free(BN_BLINDING *b); int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); +#ifndef OPENSSL_NO_DEPRECATED unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); +#endif +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, - const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx); @@ -625,24 +626,24 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, * t^p[0] + t^p[1] + ... + t^p[k] * where m = p[0] > p[1] > ... > p[k] = 0. */ -int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]); +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); /* r = a mod p */ int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */ -int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], + const int p[], BN_CTX *ctx); /* r = (a * b) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx); /* r = (a * a) mod p */ -int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[], +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], BN_CTX *ctx); /* r = (1 / b) mod p */ int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */ + const int p[], BN_CTX *ctx); /* r = (a / b) mod p */ int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */ + const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */ int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, - const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */ + const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, - const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */ -int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max); -int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a); + const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */ +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); /* faster mod functions for the 'NIST primes' * 0 <= a < p^2 */ @@ -751,10 +752,12 @@ int RAND_pseudo_bytes(unsigned char *buf,int num); #define bn_correct_top(a) \ { \ BN_ULONG *ftl; \ - if ((a)->top > 0) \ + int tmp_top = (a)->top; \ + if (tmp_top > 0) \ { \ - for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ - if (*(ftl--)) break; \ + for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ + if (*(ftl--)) break; \ + (a)->top = tmp_top; \ } \ bn_pollute(a); \ } diff --git a/crypto/openssl/crypto/bn/bn_asm.c b/crypto/openssl/crypto/bn/bn_asm.c index 99bc2de491..c43c91cc09 100644 --- a/crypto/openssl/crypto/bn/bn_asm.c +++ b/crypto/openssl/crypto/bn/bn_asm.c @@ -75,6 +75,7 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) assert(num >= 0); if (num <= 0) return(c1); +#ifndef OPENSSL_SMALL_FOOTPRINT while (num&~3) { mul_add(rp[0],ap[0],w,c1); @@ -83,11 +84,11 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) mul_add(rp[3],ap[3],w,c1); ap+=4; rp+=4; num-=4; } - if (num) +#endif + while (num) { - mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1; - mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1; - mul_add(rp[2],ap[2],w,c1); return c1; + mul_add(rp[0],ap[0],w,c1); + ap++; rp++; num--; } return(c1); @@ -100,6 +101,7 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) assert(num >= 0); if (num <= 0) return(c1); +#ifndef OPENSSL_SMALL_FOOTPRINT while (num&~3) { mul(rp[0],ap[0],w,c1); @@ -108,11 +110,11 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) mul(rp[3],ap[3],w,c1); ap+=4; rp+=4; num-=4; } - if (num) +#endif + while (num) { - mul(rp[0],ap[0],w,c1); if (--num == 0) return c1; - mul(rp[1],ap[1],w,c1); if (--num == 0) return c1; - mul(rp[2],ap[2],w,c1); + mul(rp[0],ap[0],w,c1); + ap++; rp++; num--; } return(c1); } @@ -121,6 +123,8 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) { assert(n >= 0); if (n <= 0) return; + +#ifndef OPENSSL_SMALL_FOOTPRINT while (n&~3) { sqr(r[0],r[1],a[0]); @@ -129,11 +133,11 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) sqr(r[6],r[7],a[3]); a+=4; r+=8; n-=4; } - if (n) +#endif + while (n) { - sqr(r[0],r[1],a[0]); if (--n == 0) return; - sqr(r[2],r[3],a[1]); if (--n == 0) return; - sqr(r[4],r[5],a[2]); + sqr(r[0],r[1],a[0]); + a++; r+=2; n--; } } @@ -150,18 +154,20 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) bl=LBITS(w); bh=HBITS(w); - for (;;) +#ifndef OPENSSL_SMALL_FOOTPRINT + while (num&~3) { mul_add(rp[0],ap[0],bl,bh,c); - if (--num == 0) break; mul_add(rp[1],ap[1],bl,bh,c); - if (--num == 0) break; mul_add(rp[2],ap[2],bl,bh,c); - if (--num == 0) break; mul_add(rp[3],ap[3],bl,bh,c); - if (--num == 0) break; - ap+=4; - rp+=4; + ap+=4; rp+=4; num-=4; + } +#endif + while (num) + { + mul_add(rp[0],ap[0],bl,bh,c); + ap++; rp++; num--; } return(c); } @@ -177,18 +183,20 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) bl=LBITS(w); bh=HBITS(w); - for (;;) +#ifndef OPENSSL_SMALL_FOOTPRINT + while (num&~3) { mul(rp[0],ap[0],bl,bh,carry); - if (--num == 0) break; mul(rp[1],ap[1],bl,bh,carry); - if (--num == 0) break; mul(rp[2],ap[2],bl,bh,carry); - if (--num == 0) break; mul(rp[3],ap[3],bl,bh,carry); - if (--num == 0) break; - ap+=4; - rp+=4; + ap+=4; rp+=4; num-=4; + } +#endif + while (num) + { + mul(rp[0],ap[0],bl,bh,carry); + ap++; rp++; num--; } return(carry); } @@ -197,22 +205,21 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) { assert(n >= 0); if (n <= 0) return; - for (;;) + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n&~3) { sqr64(r[0],r[1],a[0]); - if (--n == 0) break; - sqr64(r[2],r[3],a[1]); - if (--n == 0) break; - sqr64(r[4],r[5],a[2]); - if (--n == 0) break; - sqr64(r[6],r[7],a[3]); - if (--n == 0) break; - - a+=4; - r+=8; + a+=4; r+=8; n-=4; + } +#endif + while (n) + { + sqr64(r[0],r[1],a[0]); + a++; r+=2; n--; } } @@ -303,31 +310,30 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) assert(n >= 0); if (n <= 0) return((BN_ULONG)0); - for (;;) +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n&~3) { ll+=(BN_ULLONG)a[0]+b[0]; r[0]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; - if (--n <= 0) break; - ll+=(BN_ULLONG)a[1]+b[1]; r[1]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; - if (--n <= 0) break; - ll+=(BN_ULLONG)a[2]+b[2]; r[2]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; - if (--n <= 0) break; - ll+=(BN_ULLONG)a[3]+b[3]; r[3]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; - if (--n <= 0) break; - - a+=4; - b+=4; - r+=4; + a+=4; b+=4; r+=4; n-=4; + } +#endif + while (n) + { + ll+=(BN_ULLONG)a[0]+b[0]; + r[0]=(BN_ULONG)ll&BN_MASK2; + ll>>=BN_BITS2; + a++; b++; r++; n--; } return((BN_ULONG)ll); } @@ -340,7 +346,8 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) if (n <= 0) return((BN_ULONG)0); c=0; - for (;;) +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n&~3) { t=a[0]; t=(t+c)&BN_MASK2; @@ -348,35 +355,36 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) l=(t+b[0])&BN_MASK2; c+=(l < t); r[0]=l; - if (--n <= 0) break; - t=a[1]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[1])&BN_MASK2; c+=(l < t); r[1]=l; - if (--n <= 0) break; - t=a[2]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[2])&BN_MASK2; c+=(l < t); r[2]=l; - if (--n <= 0) break; - t=a[3]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[3])&BN_MASK2; c+=(l < t); r[3]=l; - if (--n <= 0) break; - - a+=4; - b+=4; - r+=4; + a+=4; b+=4; r+=4; n-=4; + } +#endif + while(n) + { + t=a[0]; + t=(t+c)&BN_MASK2; + c=(t < c); + l=(t+b[0])&BN_MASK2; + c+=(l < t); + r[0]=l; + a++; b++; r++; n--; } return((BN_ULONG)c); } @@ -390,36 +398,35 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) assert(n >= 0); if (n <= 0) return((BN_ULONG)0); - for (;;) +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n&~3) { t1=a[0]; t2=b[0]; r[0]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - t1=a[1]; t2=b[1]; r[1]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - t1=a[2]; t2=b[2]; r[2]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - t1=a[3]; t2=b[3]; r[3]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - - a+=4; - b+=4; - r+=4; + a+=4; b+=4; r+=4; n-=4; + } +#endif + while (n) + { + t1=a[0]; t2=b[0]; + r[0]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + a++; b++; r++; n--; } return(c); } -#ifdef BN_MUL_COMBA +#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT) #undef bn_mul_comba8 #undef bn_mul_comba4 @@ -820,18 +827,134 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) r[6]=c1; r[7]=c2; } + +#ifdef OPENSSL_NO_ASM +#ifdef OPENSSL_BN_ASM_MONT +#include +/* + * This is essentially reference implementation, which may or may not + * result in performance improvement. E.g. on IA-32 this routine was + * observed to give 40% faster rsa1024 private key operations and 10% + * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only + * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a + * reference implementation, one to be used as starting point for + * platform-specific assembler. Mentioned numbers apply to compiler + * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and + * can vary not only from platform to platform, but even for compiler + * versions. Assembler vs. assembler improvement coefficients can + * [and are known to] differ and are to be documented elsewhere. + */ +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num) + { + BN_ULONG c0,c1,ml,*tp,n0; +#ifdef mul64 + BN_ULONG mh; +#endif + volatile BN_ULONG *vp; + int i=0,j; + +#if 0 /* template for platform-specific implementation */ + if (ap==bp) return bn_sqr_mont(rp,ap,np,n0p,num); +#endif + vp = tp = alloca((num+2)*sizeof(BN_ULONG)); + + n0 = *n0p; + + c0 = 0; + ml = bp[0]; +#ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + for (j=0;j=np[num-1]) + { + c0 = bn_sub_words(rp,tp,np,num); + if (tp[num]!=0 || c0==0) + { + for(i=0;i +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num) + { + BN_ULONG c0,c1,*tp,n0=*n0p; + volatile BN_ULONG *vp; + int i=0,j; + + vp = tp = alloca((num+2)*sizeof(BN_ULONG)); + + for(i=0;i<=num;i++) tp[i]=0; + + for(i=0;i=np[num-1]) + { + c0 = bn_sub_words(rp,tp,np,num); + if (tp[num]!=0 || c0==0) + { + for(i=0;imod, BN_FLG_CONSTTIME); ret->counter = BN_BLINDING_COUNTER; + CRYPTO_THREADID_current(&ret->tid); return(ret); err: if (ret != NULL) BN_BLINDING_free(ret); @@ -263,6 +267,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ct return(ret); } +#ifndef OPENSSL_NO_DEPRECATED unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) { return b->thread_id; @@ -272,6 +277,12 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) { b->thread_id = n; } +#endif + +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b) + { + return &b->tid; + } unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) { @@ -284,7 +295,7 @@ void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) } BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, - const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx) diff --git a/crypto/openssl/crypto/bn/bn_ctx.c b/crypto/openssl/crypto/bn/bn_ctx.c index b3452f1a91..3f2256f675 100644 --- a/crypto/openssl/crypto/bn/bn_ctx.c +++ b/crypto/openssl/crypto/bn/bn_ctx.c @@ -161,7 +161,7 @@ static void ctxdbg(BN_CTX *ctx) fprintf(stderr,"(%08x): ", (unsigned int)ctx); while(bnidx < ctx->used) { - fprintf(stderr,"%02x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); + fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); if(!(bnidx % BN_CTX_POOL_SIZE)) item = item->next; } @@ -171,8 +171,8 @@ static void ctxdbg(BN_CTX *ctx) while(fpidx < stack->depth) { while(bnidx++ < stack->indexes[fpidx]) - fprintf(stderr," "); - fprintf(stderr,"^^ "); + fprintf(stderr," "); + fprintf(stderr,"^^^ "); bnidx++; fpidx++; } diff --git a/crypto/openssl/crypto/bn/bn_div.c b/crypto/openssl/crypto/bn/bn_div.c index 7c35545354..802a43d642 100644 --- a/crypto/openssl/crypto/bn/bn_div.c +++ b/crypto/openssl/crypto/bn/bn_div.c @@ -337,7 +337,7 @@ X) -> 0x%08X\n", t2 -= d1; } #else /* !BN_LLONG */ - BN_ULONG t2l,t2h,ql,qh; + BN_ULONG t2l,t2h; q=bn_div_words(n0,n1,d0); #ifdef BN_DEBUG_LEVITTE @@ -355,9 +355,12 @@ X) -> 0x%08X\n", t2l = d1 * q; t2h = BN_UMULT_HIGH(d1,q); #else + { + BN_ULONG ql, qh; t2l=LBITS(d1); t2h=HBITS(d1); ql =LBITS(q); qh =HBITS(q); mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ + } #endif for (;;) @@ -561,7 +564,7 @@ X) -> 0x%08X\n", t2 -= d1; } #else /* !BN_LLONG */ - BN_ULONG t2l,t2h,ql,qh; + BN_ULONG t2l,t2h; q=bn_div_words(n0,n1,d0); #ifdef BN_DEBUG_LEVITTE @@ -579,9 +582,12 @@ X) -> 0x%08X\n", t2l = d1 * q; t2h = BN_UMULT_HIGH(d1,q); #else + { + BN_ULONG ql, qh; t2l=LBITS(d1); t2h=HBITS(d1); ql =LBITS(q); qh =HBITS(q); mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ + } #endif for (;;) diff --git a/crypto/openssl/crypto/bn/bn_gf2m.c b/crypto/openssl/crypto/bn/bn_gf2m.c index ae642ccb39..527b0fa15b 100644 --- a/crypto/openssl/crypto/bn/bn_gf2m.c +++ b/crypto/openssl/crypto/bn/bn_gf2m.c @@ -121,74 +121,12 @@ static const BN_ULONG SQR_tb[16] = SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \ SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] #endif -#ifdef SIXTEEN_BIT -#define SQR1(w) \ - SQR_tb[(w) >> 12 & 0xF] << 8 | SQR_tb[(w) >> 8 & 0xF] -#define SQR0(w) \ - SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] -#endif -#ifdef EIGHT_BIT -#define SQR1(w) \ - SQR_tb[(w) >> 4 & 0xF] -#define SQR0(w) \ - SQR_tb[(w) & 15] -#endif /* Product of two polynomials a, b each with degree < BN_BITS2 - 1, * result is a polynomial r with degree < 2 * BN_BITS - 1 * The caller MUST ensure that the variables have the right amount * of space allocated. */ -#ifdef EIGHT_BIT -static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) - { - register BN_ULONG h, l, s; - BN_ULONG tab[4], top1b = a >> 7; - register BN_ULONG a1, a2; - - a1 = a & (0x7F); a2 = a1 << 1; - - tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; - - s = tab[b & 0x3]; l = s; - s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 6; - s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 4; - s = tab[b >> 6 ]; l ^= s << 6; h ^= s >> 2; - - /* compensate for the top bit of a */ - - if (top1b & 01) { l ^= b << 7; h ^= b >> 1; } - - *r1 = h; *r0 = l; - } -#endif -#ifdef SIXTEEN_BIT -static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) - { - register BN_ULONG h, l, s; - BN_ULONG tab[4], top1b = a >> 15; - register BN_ULONG a1, a2; - - a1 = a & (0x7FFF); a2 = a1 << 1; - - tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; - - s = tab[b & 0x3]; l = s; - s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 14; - s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 12; - s = tab[b >> 6 & 0x3]; l ^= s << 6; h ^= s >> 10; - s = tab[b >> 8 & 0x3]; l ^= s << 8; h ^= s >> 8; - s = tab[b >>10 & 0x3]; l ^= s << 10; h ^= s >> 6; - s = tab[b >>12 & 0x3]; l ^= s << 12; h ^= s >> 4; - s = tab[b >>14 ]; l ^= s << 14; h ^= s >> 2; - - /* compensate for the top bit of a */ - - if (top1b & 01) { l ^= b << 15; h ^= b >> 1; } - - *r1 = h; *r0 = l; - } -#endif #ifdef THIRTY_TWO_BIT static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) { @@ -321,7 +259,7 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) /* Performs modular reduction of a and store result in r. r could be a. */ -int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]) +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) { int j, k; int n, dN, d0, d1; @@ -422,11 +360,11 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]) int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) { int ret = 0; - const int max = BN_num_bits(p); - unsigned int *arr=NULL; + const int max = BN_num_bits(p) + 1; + int *arr=NULL; bn_check_top(a); bn_check_top(p); - if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { @@ -444,7 +382,7 @@ err: /* Compute the product of two polynomials a and b, reduce modulo p, and store * the result in r. r could be a or b; a could be b. */ -int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx) { int zlen, i, j, k, ret = 0; BIGNUM *s; @@ -500,12 +438,12 @@ err: int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - const int max = BN_num_bits(p); - unsigned int *arr=NULL; + const int max = BN_num_bits(p) + 1; + int *arr=NULL; bn_check_top(a); bn_check_top(b); bn_check_top(p); - if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { @@ -521,7 +459,7 @@ err: /* Square a, reduce the result mod p, and store it in a. r could be a. */ -int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx) { int i, ret = 0; BIGNUM *s; @@ -556,12 +494,12 @@ err: int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - const int max = BN_num_bits(p); - unsigned int *arr=NULL; + const int max = BN_num_bits(p) + 1; + int *arr=NULL; bn_check_top(a); bn_check_top(p); - if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { @@ -643,7 +581,7 @@ err: * function is only provided for convenience; for best performance, use the * BN_GF2m_mod_inv function. */ -int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx) { BIGNUM *field; int ret = 0; @@ -769,7 +707,7 @@ err: * function is only provided for convenience; for best performance, use the * BN_GF2m_mod_div function. */ -int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int p[], BN_CTX *ctx) { BIGNUM *field; int ret = 0; @@ -794,7 +732,7 @@ err: * the result in r. r could be a. * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363. */ -int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx) { int ret = 0, i, n; BIGNUM *u; @@ -840,12 +778,12 @@ err: int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - const int max = BN_num_bits(p); - unsigned int *arr=NULL; + const int max = BN_num_bits(p) + 1; + int *arr=NULL; bn_check_top(a); bn_check_top(b); bn_check_top(p); - if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { @@ -863,7 +801,7 @@ err: * the result in r. r could be a. * Uses exponentiation as in algorithm A.4.1 from IEEE P1363. */ -int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx) { int ret = 0; BIGNUM *u; @@ -899,11 +837,11 @@ err: int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - const int max = BN_num_bits(p); - unsigned int *arr=NULL; + const int max = BN_num_bits(p) + 1; + int *arr=NULL; bn_check_top(a); bn_check_top(p); - if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { @@ -920,10 +858,9 @@ err: /* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0. * Uses algorithms A.4.7 and A.4.6 from IEEE P1363. */ -int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p[], BN_CTX *ctx) +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CTX *ctx) { - int ret = 0, count = 0; - unsigned int j; + int ret = 0, count = 0, j; BIGNUM *a, *z, *rho, *w, *w2, *tmp; bn_check_top(a_); @@ -1018,11 +955,11 @@ err: int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - const int max = BN_num_bits(p); - unsigned int *arr=NULL; + const int max = BN_num_bits(p) + 1; + int *arr=NULL; bn_check_top(a); bn_check_top(p); - if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) @@ -1038,20 +975,17 @@ err: } /* Convert the bit-string representation of a polynomial - * ( \sum_{i=0}^n a_i * x^i , where a_0 is *not* zero) into an array - * of integers corresponding to the bits with non-zero coefficient. + * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding + * to the bits with non-zero coefficient. Array is terminated with -1. * Up to max elements of the array will be filled. Return value is total - * number of coefficients that would be extracted if array was large enough. + * number of array elements that would be filled if array was large enough. */ -int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max) +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) { int i, j, k = 0; BN_ULONG mask; - if (BN_is_zero(a) || !BN_is_bit_set(a, 0)) - /* a_0 == 0 => return error (the unsigned int array - * must be terminated by 0) - */ + if (BN_is_zero(a)) return 0; for (i = a->top - 1; i >= 0; i--) @@ -1071,24 +1005,28 @@ int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max) } } + if (k < max) { + p[k] = -1; + k++; + } + return k; } /* Convert the coefficient array representation of a polynomial to a - * bit-string. The array must be terminated by 0. + * bit-string. The array must be terminated by -1. */ -int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a) +int BN_GF2m_arr2poly(const int p[], BIGNUM *a) { int i; bn_check_top(a); BN_zero(a); - for (i = 0; p[i] != 0; i++) + for (i = 0; p[i] != -1; i++) { if (BN_set_bit(a, p[i]) == 0) return 0; } - BN_set_bit(a, 0); bn_check_top(a); return 1; diff --git a/crypto/openssl/crypto/bn/bn_lcl.h b/crypto/openssl/crypto/bn/bn_lcl.h index 27ac4397a1..8e5e98e3f2 100644 --- a/crypto/openssl/crypto/bn/bn_lcl.h +++ b/crypto/openssl/crypto/bn/bn_lcl.h @@ -255,7 +255,8 @@ extern "C" { : "r"(a), "r"(b)); \ ret; }) # endif /* compiler */ -# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) +# elif (defined(__x86_64) || defined(__x86_64__)) && \ + (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) # if defined(__GNUC__) # define BN_UMULT_HIGH(a,b) ({ \ register BN_ULONG ret,discard; \ diff --git a/crypto/openssl/crypto/bn/bn_lib.c b/crypto/openssl/crypto/bn/bn_lib.c index 32a8fbaf51..5470fbe6ef 100644 --- a/crypto/openssl/crypto/bn/bn_lib.c +++ b/crypto/openssl/crypto/bn/bn_lib.c @@ -133,15 +133,34 @@ int BN_get_params(int which) const BIGNUM *BN_value_one(void) { - static BN_ULONG data_one=1L; - static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA}; + static const BN_ULONG data_one=1L; + static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA}; return(&const_one); } +char *BN_options(void) + { + static int init=0; + static char data[16]; + + if (!init) + { + init++; +#ifdef BN_LLONG + BIO_snprintf(data,sizeof data,"bn(%d,%d)", + (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8); +#else + BIO_snprintf(data,sizeof data,"bn(%d,%d)", + (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8); +#endif + } + return(data); + } + int BN_num_bits_word(BN_ULONG l) { - static const char bits[256]={ + static const unsigned char bits[256]={ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, @@ -216,7 +235,7 @@ int BN_num_bits_word(BN_ULONG l) else #endif { -#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) if (l & 0xff00L) return(bits[(int)(l>>8)]+8); else @@ -744,7 +763,7 @@ int BN_is_bit_set(const BIGNUM *a, int n) i=n/BN_BITS2; j=n%BN_BITS2; if (a->top <= i) return 0; - return(((a->d[i])>>j)&((BN_ULONG)1)); + return (int)(((a->d[i])>>j)&((BN_ULONG)1)); } int BN_mask_bits(BIGNUM *a, int n) diff --git a/crypto/openssl/crypto/bn/bn_mont.c b/crypto/openssl/crypto/bn/bn_mont.c index 4799b152dd..7224637ab3 100644 --- a/crypto/openssl/crypto/bn/bn_mont.c +++ b/crypto/openssl/crypto/bn/bn_mont.c @@ -122,26 +122,10 @@ #define MONT_WORD /* use the faster word-based algorithm */ -#if defined(MONT_WORD) && defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) -/* This condition means we have a specific non-default build: - * In the 0.9.8 branch, OPENSSL_BN_ASM_MONT is normally not set for any - * BN_BITS2<=32 platform; an explicit "enable-montasm" is required. - * I.e., if we are here, the user intentionally deviates from the - * normal stable build to get better Montgomery performance from - * the 0.9.9-dev backport. - * - * In this case only, we also enable BN_from_montgomery_word() - * (another non-stable feature from 0.9.9-dev). - */ -#define MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD -#endif - -#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD +#ifdef MONT_WORD static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); #endif - - int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) { @@ -153,11 +137,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (num>1 && a->top==num && b->top==num) { if (bn_wexpand(r,num) == NULL) return(0); -#if 0 /* for OpenSSL 0.9.9 mont->n0 */ if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num)) -#else - if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,&mont->n0,num)) -#endif { r->neg = a->neg^b->neg; r->top = num; @@ -181,7 +161,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (!BN_mul(tmp,a,b,ctx)) goto err; } /* reduce from aRR to aR */ -#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD +#ifdef MONT_WORD if (!BN_from_montgomery_word(r,tmp,mont)) goto err; #else if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; @@ -193,7 +173,7 @@ err: return(ret); } -#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD +#ifdef MONT_WORD static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) { BIGNUM *n; @@ -217,15 +197,15 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) nrp= &(r->d[nl]); /* clear the top words of T */ +#if 1 for (i=r->top; id[i]=0; +#else + memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); +#endif r->top=max; -#if 0 /* for OpenSSL 0.9.9 mont->n0 */ n0=mont->n0[0]; -#else - n0=mont->n0; -#endif #ifdef BN_COUNT fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl); @@ -270,6 +250,8 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) } al=r->top-ri; +#define BRANCH_FREE 1 +#if BRANCH_FREE if (bn_wexpand(ret,ri) == NULL) return(0); x=0-(((al-ri)>>(sizeof(al)*8-1))&1); ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */ @@ -317,164 +299,8 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) rp[i]=nrp[i], ap[i]=0; bn_correct_top(r); bn_correct_top(ret); - bn_check_top(ret); - - return(1); - } - -int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx) - { - int retn=0; - BIGNUM *t; - - BN_CTX_start(ctx); - if ((t = BN_CTX_get(ctx)) && BN_copy(t,a)) - retn = BN_from_montgomery_word(ret,t,mont); - BN_CTX_end(ctx); - return retn; - } - -#else /* !MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */ - -int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx) - { - int retn=0; - -#ifdef MONT_WORD - BIGNUM *n,*r; - BN_ULONG *ap,*np,*rp,n0,v,*nrp; - int al,nl,max,i,x,ri; - - BN_CTX_start(ctx); - if ((r = BN_CTX_get(ctx)) == NULL) goto err; - - if (!BN_copy(r,a)) goto err; - n= &(mont->N); - - ap=a->d; - /* mont->ri is the size of mont->N in bits (rounded up - to the word size) */ - al=ri=mont->ri/BN_BITS2; - - nl=n->top; - if ((al == 0) || (nl == 0)) { r->top=0; return(1); } - - max=(nl+al+1); /* allow for overflow (no?) XXX */ - if (bn_wexpand(r,max) == NULL) goto err; - - r->neg=a->neg^n->neg; - np=n->d; - rp=r->d; - nrp= &(r->d[nl]); - - /* clear the top words of T */ -#if 1 - for (i=r->top; id[i]=0; #else - memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); -#endif - - r->top=max; - n0=mont->n0; - -#ifdef BN_COUNT - fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl); -#endif - for (i=0; i= v) - continue; - else - { - if (((++nrp[0])&BN_MASK2) != 0) continue; - if (((++nrp[1])&BN_MASK2) != 0) continue; - for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; - } - } - bn_correct_top(r); - - /* mont->ri will be a multiple of the word size and below code - * is kind of BN_rshift(ret,r,mont->ri) equivalent */ - if (r->top <= ri) - { - ret->top=0; - retn=1; - goto err; - } - al=r->top-ri; - -# define BRANCH_FREE 1 -# if BRANCH_FREE - if (bn_wexpand(ret,ri) == NULL) goto err; - x=0-(((al-ri)>>(sizeof(al)*8-1))&1); - ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */ - ret->neg=r->neg; - - rp=ret->d; - ap=&(r->d[ri]); - - { - size_t m1,m2; - - v=bn_sub_words(rp,ap,np,ri); - /* this ----------------^^ works even in alri) nrp=rp; else nrp=ap; */ - /* in other words if subtraction result is real, then - * trick unconditional memcpy below to perform in-place - * "refresh" instead of actual copy. */ - m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al>(sizeof(al)*8-1))&1); /* al>ri */ - m1|=m2; /* (al!=ri) */ - m1|=(0-(size_t)v); /* (al!=ri || v) */ - m1&=~m2; /* (al!=ri || v) && !al>ri */ - nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1)); - } - - /* 'itop=al; ret->neg=r->neg; @@ -497,8 +323,30 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, al+=4; for (; iN)) >= 0) + { + if (!BN_usub(ret,ret,&(mont->N))) return(0); + } +#endif + bn_check_top(ret); + + return(1); + } +#endif /* MONT_WORD */ + +int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) + { + int retn=0; +#ifdef MONT_WORD + BIGNUM *t; + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) && BN_copy(t,a)) + retn = BN_from_montgomery_word(ret,t,mont); + BN_CTX_end(ctx); +#else /* !MONT_WORD */ BIGNUM *t1,*t2; BN_CTX_start(ctx); @@ -515,21 +363,18 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, if (!BN_mul(t1,t2,&mont->N,ctx)) goto err; if (!BN_add(t2,a,t1)) goto err; if (!BN_rshift(ret,t2,mont->ri)) goto err; -#endif /* MONT_WORD */ -#if !defined(BRANCH_FREE) || BRANCH_FREE==0 if (BN_ucmp(ret, &(mont->N)) >= 0) { if (!BN_usub(ret,ret,&(mont->N))) goto err; } -#endif retn=1; bn_check_top(ret); err: BN_CTX_end(ctx); +#endif /* MONT_WORD */ return(retn); } -#endif /* MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */ BN_MONT_CTX *BN_MONT_CTX_new(void) { @@ -549,11 +394,7 @@ void BN_MONT_CTX_init(BN_MONT_CTX *ctx) BN_init(&(ctx->RR)); BN_init(&(ctx->N)); BN_init(&(ctx->Ni)); -#if 0 /* for OpenSSL 0.9.9 mont->n0 */ ctx->n0[0] = ctx->n0[1] = 0; -#else - ctx->n0 = 0; -#endif ctx->flags=0; } @@ -585,26 +426,22 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) BIGNUM tmod; BN_ULONG buf[2]; - mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; - BN_zero(R); -#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)", - only certain BN_BITS2<=32 platforms actually need this */ - if (!(BN_set_bit(R,2*BN_BITS2))) goto err; /* R */ -#else - if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ -#endif - - buf[0]=mod->d[0]; /* tmod = N mod word size */ - buf[1]=0; - BN_init(&tmod); tmod.d=buf; - tmod.top = buf[0] != 0 ? 1 : 0; tmod.dmax=2; tmod.neg=0; -#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)"; - only certain BN_BITS2<=32 platforms actually need this */ + mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; + +#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) + /* Only certain BN_BITS2<=32 platforms actually make use of + * n0[1], and we could use the #else case (with a shorter R + * value) for the others. However, currently only the assembler + * files do know which is which. */ + + BN_zero(R); + if (!(BN_set_bit(R,2*BN_BITS2))) goto err; + tmod.top=0; if ((buf[0] = mod->d[0])) tmod.top=1; if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2; @@ -632,6 +469,12 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; #else + BN_zero(R); + if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ + + buf[0]=mod->d[0]; /* tmod = N mod word size */ + buf[1]=0; + tmod.top = buf[0] != 0 ? 1 : 0; /* Ri = R^-1 mod N*/ if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) goto err; @@ -647,12 +490,8 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; /* Ni = (R*Ri-1)/N, * keep only least significant word: */ -# if 0 /* for OpenSSL 0.9.9 mont->n0 */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = 0; -# else - mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0; -# endif #endif } #else /* !MONT_WORD */ @@ -689,12 +528,8 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) if (!BN_copy(&(to->N),&(from->N))) return NULL; if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL; to->ri=from->ri; -#if 0 /* for OpenSSL 0.9.9 mont->n0 */ to->n0[0]=from->n0[0]; to->n0[1]=from->n0[1]; -#else - to->n0=from->n0; -#endif return(to); } diff --git a/crypto/openssl/crypto/bn/bn_opt.c b/crypto/openssl/crypto/bn/bn_opt.c deleted file mode 100644 index 21cbb38f62..0000000000 --- a/crypto/openssl/crypto/bn/bn_opt.c +++ /dev/null @@ -1,87 +0,0 @@ -/* crypto/bn/bn_opt.c */ -/* 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 BN_DEBUG -# undef NDEBUG /* avoid conflicting definitions */ -# define NDEBUG -#endif - -#include -#include -#include -#include "cryptlib.h" -#include "bn_lcl.h" - -char *BN_options(void) - { - static int init=0; - static char data[16]; - - if (!init) - { - init++; -#ifdef BN_LLONG - BIO_snprintf(data,sizeof data,"bn(%d,%d)", - (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8); -#else - BIO_snprintf(data,sizeof data,"bn(%d,%d)", - (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8); -#endif - } - return(data); - } diff --git a/crypto/openssl/crypto/bn/bn_print.c b/crypto/openssl/crypto/bn/bn_print.c index 810dde34e1..bebb466d08 100644 --- a/crypto/openssl/crypto/bn/bn_print.c +++ b/crypto/openssl/crypto/bn/bn_print.c @@ -294,6 +294,27 @@ err: return(0); } +int BN_asc2bn(BIGNUM **bn, const char *a) + { + const char *p = a; + if (*p == '-') + p++; + + if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) + { + if (!BN_hex2bn(bn, p + 2)) + return 0; + } + else + { + if (!BN_dec2bn(bn, p)) + return 0; + } + if (*a == '-') + (*bn)->neg = 1; + return 1; + } + #ifndef OPENSSL_NO_BIO #ifndef OPENSSL_NO_FP_API int BN_print_fp(FILE *fp, const BIGNUM *a) diff --git a/crypto/openssl/crypto/bn/bn_x931p.c b/crypto/openssl/crypto/bn/bn_x931p.c deleted file mode 100644 index 04c5c874ec..0000000000 --- a/crypto/openssl/crypto/bn/bn_x931p.c +++ /dev/null @@ -1,272 +0,0 @@ -/* bn_x931p.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2005. - */ -/* ==================================================================== - * Copyright (c) 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 - * 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 -#include - -/* X9.31 routines for prime derivation */ - -/* X9.31 prime derivation. This is used to generate the primes pi - * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd - * integers. - */ - -static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, - BN_GENCB *cb) - { - int i = 0; - if (!BN_copy(pi, Xpi)) - return 0; - if (!BN_is_odd(pi) && !BN_add_word(pi, 1)) - return 0; - for(;;) - { - i++; - BN_GENCB_call(cb, 0, i); - /* NB 27 MR is specificed in X9.31 */ - if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) - break; - if (!BN_add_word(pi, 2)) - return 0; - } - BN_GENCB_call(cb, 2, i); - return 1; - } - -/* This is the main X9.31 prime derivation function. From parameters - * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are - * not NULL they will be returned too: this is needed for testing. - */ - -int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, - const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) - { - int ret = 0; - - BIGNUM *t, *p1p2, *pm1; - - /* Only even e supported */ - if (!BN_is_odd(e)) - return 0; - - BN_CTX_start(ctx); - if (!p1) - p1 = BN_CTX_get(ctx); - - if (!p2) - p2 = BN_CTX_get(ctx); - - t = BN_CTX_get(ctx); - - p1p2 = BN_CTX_get(ctx); - - pm1 = BN_CTX_get(ctx); - - if (!bn_x931_derive_pi(p1, Xp1, ctx, cb)) - goto err; - - if (!bn_x931_derive_pi(p2, Xp2, ctx, cb)) - goto err; - - if (!BN_mul(p1p2, p1, p2, ctx)) - goto err; - - /* First set p to value of Rp */ - - if (!BN_mod_inverse(p, p2, p1, ctx)) - goto err; - - if (!BN_mul(p, p, p2, ctx)) - goto err; - - if (!BN_mod_inverse(t, p1, p2, ctx)) - goto err; - - if (!BN_mul(t, t, p1, ctx)) - goto err; - - if (!BN_sub(p, p, t)) - goto err; - - if (p->neg && !BN_add(p, p, p1p2)) - goto err; - - /* p now equals Rp */ - - if (!BN_mod_sub(p, p, Xp, p1p2, ctx)) - goto err; - - if (!BN_add(p, p, Xp)) - goto err; - - /* p now equals Yp0 */ - - for (;;) - { - int i = 1; - BN_GENCB_call(cb, 0, i++); - if (!BN_copy(pm1, p)) - goto err; - if (!BN_sub_word(pm1, 1)) - goto err; - if (!BN_gcd(t, pm1, e, ctx)) - goto err; - if (BN_is_one(t) - /* X9.31 specifies 8 MR and 1 Lucas test or any prime test - * offering similar or better guarantees 50 MR is considerably - * better. - */ - && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb)) - break; - if (!BN_add(p, p, p1p2)) - goto err; - } - - BN_GENCB_call(cb, 3, 0); - - ret = 1; - - err: - - BN_CTX_end(ctx); - - return ret; - } - -/* Generate pair of paramters Xp, Xq for X9.31 prime generation. - * Note: nbits paramter is sum of number of bits in both. - */ - -int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) - { - BIGNUM *t; - int i; - /* Number of bits for each prime is of the form - * 512+128s for s = 0, 1, ... - */ - if ((nbits < 1024) || (nbits & 0xff)) - return 0; - nbits >>= 1; - /* The random value Xp must be between sqrt(2) * 2^(nbits-1) and - * 2^nbits - 1. By setting the top two bits we ensure that the lower - * bound is exceeded. - */ - if (!BN_rand(Xp, nbits, 1, 0)) - return 0; - - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); - - for (i = 0; i < 1000; i++) - { - if (!BN_rand(Xq, nbits, 1, 0)) - return 0; - /* Check that |Xp - Xq| > 2^(nbits - 100) */ - BN_sub(t, Xp, Xq); - if (BN_num_bits(t) > (nbits - 100)) - break; - } - - BN_CTX_end(ctx); - - if (i < 1000) - return 1; - - return 0; - - } - -/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 - * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL - * the relevant parameter will be stored in it. - * - * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq - * are generated using the previous function and supplied as input. - */ - -int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - BIGNUM *Xp1, BIGNUM *Xp2, - const BIGNUM *Xp, - const BIGNUM *e, BN_CTX *ctx, - BN_GENCB *cb) - { - int ret = 0; - - BN_CTX_start(ctx); - if (!Xp1) - Xp1 = BN_CTX_get(ctx); - if (!Xp2) - Xp2 = BN_CTX_get(ctx); - - if (!BN_rand(Xp1, 101, 0, 0)) - goto error; - if (!BN_rand(Xp2, 101, 0, 0)) - goto error; - if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) - goto error; - - ret = 1; - - error: - BN_CTX_end(ctx); - - return ret; - - } - diff --git a/crypto/openssl/crypto/buffer/buf_err.c b/crypto/openssl/crypto/buffer/buf_err.c index 3e25bbe879..8f1de6192b 100644 --- a/crypto/openssl/crypto/buffer/buf_err.c +++ b/crypto/openssl/crypto/buffer/buf_err.c @@ -1,6 +1,6 @@ /* crypto/buffer/buf_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/buffer/buffer.c b/crypto/openssl/crypto/buffer/buffer.c index b3e947771d..620ea8d536 100644 --- a/crypto/openssl/crypto/buffer/buffer.c +++ b/crypto/openssl/crypto/buffer/buffer.c @@ -89,10 +89,10 @@ void BUF_MEM_free(BUF_MEM *a) OPENSSL_free(a); } -int BUF_MEM_grow(BUF_MEM *str, int len) +int BUF_MEM_grow(BUF_MEM *str, size_t len) { char *ret; - unsigned int n; + size_t n; if (str->length >= len) { @@ -125,10 +125,10 @@ int BUF_MEM_grow(BUF_MEM *str, int len) return(len); } -int BUF_MEM_grow_clean(BUF_MEM *str, int len) +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) { char *ret; - unsigned int n; + size_t n; if (str->length >= len) { @@ -161,3 +161,84 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int len) } return(len); } + +char *BUF_strdup(const char *str) + { + if (str == NULL) return(NULL); + return BUF_strndup(str, strlen(str)); + } + +char *BUF_strndup(const char *str, size_t siz) + { + char *ret; + + if (str == NULL) return(NULL); + + ret=OPENSSL_malloc(siz+1); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE); + return(NULL); + } + BUF_strlcpy(ret,str,siz+1); + return(ret); + } + +void *BUF_memdup(const void *data, size_t siz) + { + void *ret; + + if (data == NULL) return(NULL); + + ret=OPENSSL_malloc(siz); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE); + return(NULL); + } + return memcpy(ret, data, siz); + } + +size_t BUF_strlcpy(char *dst, const char *src, size_t size) + { + size_t l = 0; + for(; size > 1 && *src; size--) + { + *dst++ = *src++; + l++; + } + if (size) + *dst = '\0'; + return l + strlen(src); + } + +size_t BUF_strlcat(char *dst, const char *src, size_t size) + { + size_t l = 0; + for(; size > 0 && *dst; size--, dst++) + l++; + return l + BUF_strlcpy(dst, src, size); + } + +void BUF_reverse(unsigned char *out, unsigned char *in, size_t size) + { + size_t i; + if (in) + { + out += size - 1; + for (i = 0; i < size; i++) + *in++ = *out--; + } + else + { + unsigned char *q; + char c; + q = out + size - 1; + for (i = 0; i < size/2; i++) + { + c = *q; + *q-- = *out; + *out++ = c; + } + } + } diff --git a/crypto/openssl/crypto/buffer/buffer.h b/crypto/openssl/crypto/buffer/buffer.h index 1db9607450..178e418282 100644 --- a/crypto/openssl/crypto/buffer/buffer.h +++ b/crypto/openssl/crypto/buffer/buffer.h @@ -76,18 +76,19 @@ extern "C" { struct buf_mem_st { - int length; /* current number of bytes */ + size_t length; /* current number of bytes */ char *data; - int max; /* size of buffer */ + size_t max; /* size of buffer */ }; BUF_MEM *BUF_MEM_new(void); void BUF_MEM_free(BUF_MEM *a); -int BUF_MEM_grow(BUF_MEM *str, int len); -int BUF_MEM_grow_clean(BUF_MEM *str, int len); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); char * BUF_strdup(const char *str); char * BUF_strndup(const char *str, size_t siz); void * BUF_memdup(const void *data, size_t siz); +void BUF_reverse(unsigned char *out, unsigned char *in, size_t siz); /* safe string functions */ size_t BUF_strlcpy(char *dst,const char *src,size_t siz); diff --git a/crypto/openssl/crypto/camellia/camellia.c b/crypto/openssl/crypto/camellia/camellia.c index 491c26b39e..75fc8991c0 100644 --- a/crypto/openssl/crypto/camellia/camellia.c +++ b/crypto/openssl/crypto/camellia/camellia.c @@ -68,1557 +68,515 @@ /* Algorithm Specification http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ - - -#include -#include + +/* + * This release balances code size and performance. In particular key + * schedule setup is fully unrolled, because doing so *significantly* + * reduces amount of instructions per setup round and code increase is + * justifiable. In block functions on the other hand only inner loops + * are unrolled, as full unroll gives only nominal performance boost, + * while code size grows 4 or 7 times. Also, unlike previous versions + * this one "encourages" compiler to keep intermediate variables in + * registers, which should give better "all round" results, in other + * words reasonable performance even with not so modern compilers. + */ #include "camellia.h" #include "cmll_locl.h" +#include +#include -/* key constants */ -#define CAMELLIA_SIGMA1L (0xA09E667FL) -#define CAMELLIA_SIGMA1R (0x3BCC908BL) -#define CAMELLIA_SIGMA2L (0xB67AE858L) -#define CAMELLIA_SIGMA2R (0x4CAA73B2L) -#define CAMELLIA_SIGMA3L (0xC6EF372FL) -#define CAMELLIA_SIGMA3R (0xE94F82BEL) -#define CAMELLIA_SIGMA4L (0x54FF53A5L) -#define CAMELLIA_SIGMA4R (0xF1D36F1CL) -#define CAMELLIA_SIGMA5L (0x10E527FAL) -#define CAMELLIA_SIGMA5R (0xDE682D1DL) -#define CAMELLIA_SIGMA6L (0xB05688C2L) -#define CAMELLIA_SIGMA6R (0xB3E6C1FDL) - +/* 32-bit rotations */ +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define RightRotate(x, s) _lrotr(x, s) +# define LeftRotate(x, s) _lrotl(x, s) +# if _MSC_VER >= 1400 +# define SWAP(x) _byteswap_ulong(x) +# else +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +# endif +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v))) +# elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined(__x86_64) +# define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# if defined(B_ENDIAN) /* stratus.com does it */ +# define GETU32(p) (*(u32 *)(p)) +# define PUTU32(p,v) (*(u32 *)(p)=(v)) +# else +# define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; }) +# define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; }) +# endif +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# elif defined(__s390x__) +# define LeftRotate(x,s) ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# define GETU32(p) (*(u32 *)(p)) +# define PUTU32(p,v) (*(u32 *)(p)=(v)) +# endif +# endif +#endif + +#if !defined(RightRotate) && !defined(LeftRotate) +# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) ) +# define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) ) +#endif + +#if !defined(GETU32) && !defined(PUTU32) +# define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3])) +# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v)) +#endif + +/* S-box data */ +#define SBOX1_1110 Camellia_SBOX[0] +#define SBOX4_4404 Camellia_SBOX[1] +#define SBOX2_0222 Camellia_SBOX[2] +#define SBOX3_3033 Camellia_SBOX[3] +static const u32 Camellia_SBOX[][256] = { +{ 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, + 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, + 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, + 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, + 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, + 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, + 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, + 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, + 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, + 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, + 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, + 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, + 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, + 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, + 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, + 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, + 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, + 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, + 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, + 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, + 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, + 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 }, +{ 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, + 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, + 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, + 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, + 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, + 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, + 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, + 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, + 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, + 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, + 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, + 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, + 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, + 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, + 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, + 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, + 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, + 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, + 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, + 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, + 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, + 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e }, +{ 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, + 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, + 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, + 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, + 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, + 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, + 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, + 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, + 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, + 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, + 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, + 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, + 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, + 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, + 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, + 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, + 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, + 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, + 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, + 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, + 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, + 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d }, +{ 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, + 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, + 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, + 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, + 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, + 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, + 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, + 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, + 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, + 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, + 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, + 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, + 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, + 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, + 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, + 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, + 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, + 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, + 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, + 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, + 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, + 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f } +}; + +/* Key generation constants */ +static const u32 SIGMA[] = { + 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd +}; + +/* The phi algorithm given in C.2.7 of the Camellia spec document. */ /* - * macros + * This version does not attempt to minimize amount of temporary + * variables, but instead explicitly exposes algorithm's parallelism. + * It is therefore most appropriate for platforms with not less than + * ~16 registers. For platforms with less registers [well, x86 to be + * specific] assembler version should be/is provided anyway... */ - -/* e is pointer of subkey */ -#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) -#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) - -/* rotation right shift 1byte */ -#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) -/* rotation left shift 1bit */ -#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) -/* rotation left shift 1byte */ -#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) - -#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ -do \ - { \ - w0 = ll; \ - ll = (ll << bits) + (lr >> (32 - bits)); \ - lr = (lr << bits) + (rl >> (32 - bits)); \ - rl = (rl << bits) + (rr >> (32 - bits)); \ - rr = (rr << bits) + (w0 >> (32 - bits)); \ - } while(0) - -#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ -do \ - { \ - w0 = ll; \ - w1 = lr; \ - ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ - lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ - rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ - rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ - } while(0) - -#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) -#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) -#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) -#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) - -#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ -do \ - { \ - il = xl ^ kl; \ - ir = xr ^ kr; \ - t0 = il >> 16; \ - t1 = ir >> 16; \ - yl = CAMELLIA_SP1110(ir & 0xff) \ - ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ - ^ CAMELLIA_SP3033(t1 & 0xff) \ - ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ - yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ - ^ CAMELLIA_SP0222(t0 & 0xff) \ - ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ - ^ CAMELLIA_SP4404(il & 0xff); \ - yl ^= yr; \ - yr = CAMELLIA_RR8(yr); \ - yr ^= yl; \ - } while(0) - +#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\ + register u32 _t0,_t1,_t2,_t3;\ +\ + _t0 = _s0 ^ (_key)[0];\ + _t3 = SBOX4_4404[_t0&0xff];\ + _t1 = _s1 ^ (_key)[1];\ + _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\ + _t2 = SBOX1_1110[_t1&0xff];\ + _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\ + _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\ + _t3 ^= SBOX1_1110[(_t0 >> 24)];\ + _t2 ^= _t3;\ + _t3 = RightRotate(_t3,8);\ + _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\ + _s3 ^= _t3;\ + _t2 ^= SBOX2_0222[(_t1 >> 24)];\ + _s2 ^= _t2; \ + _s3 ^= _t2;\ +} while(0) /* - * for speed up - * + * Note that n has to be less than 32. Rotations for larger amount + * of bits are achieved by "rotating" order of s-elements and + * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32). */ -#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ -do \ - { \ - t0 = kll; \ - t0 &= ll; \ - lr ^= CAMELLIA_RL1(t0); \ - t1 = klr; \ - t1 |= lr; \ - ll ^= t1; \ - \ - t2 = krr; \ - t2 |= rr; \ - rl ^= t2; \ - t3 = krl; \ - t3 &= rl; \ - rr ^= CAMELLIA_RL1(t3); \ - } while(0) - -#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ -do \ - { \ - il = xl; \ - ir = xr; \ - t0 = il >> 16; \ - t1 = ir >> 16; \ - ir = CAMELLIA_SP1110(ir & 0xff) \ - ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ - ^ CAMELLIA_SP3033(t1 & 0xff) \ - ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ - il = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ - ^ CAMELLIA_SP0222(t0 & 0xff) \ - ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ - ^ CAMELLIA_SP4404(il & 0xff); \ - il ^= kl; \ - ir ^= kr; \ - ir ^= il; \ - il = CAMELLIA_RR8(il); \ - il ^= ir; \ - yl ^= ir; \ - yr ^= il; \ - } while(0) - -static const u32 camellia_sp1110[256] = - { - 0x70707000,0x82828200,0x2c2c2c00,0xececec00, - 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, - 0xe4e4e400,0x85858500,0x57575700,0x35353500, - 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, - 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, - 0x45454500,0x19191900,0xa5a5a500,0x21212100, - 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, - 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, - 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, - 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, - 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, - 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, - 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, - 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, - 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, - 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, - 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, - 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, - 0x74747400,0x12121200,0x2b2b2b00,0x20202000, - 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, - 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, - 0x34343400,0x7e7e7e00,0x76767600,0x05050500, - 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, - 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, - 0x14141400,0x58585800,0x3a3a3a00,0x61616100, - 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, - 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, - 0x53535300,0x18181800,0xf2f2f200,0x22222200, - 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, - 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, - 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, - 0x60606000,0xfcfcfc00,0x69696900,0x50505000, - 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, - 0xa1a1a100,0x89898900,0x62626200,0x97979700, - 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, - 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, - 0x10101000,0xc4c4c400,0x00000000,0x48484800, - 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, - 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, - 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, - 0x87878700,0x5c5c5c00,0x83838300,0x02020200, - 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, - 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, - 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, - 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, - 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, - 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, - 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, - 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, - 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, - 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, - 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, - 0x78787800,0x98989800,0x06060600,0x6a6a6a00, - 0xe7e7e700,0x46464600,0x71717100,0xbababa00, - 0xd4d4d400,0x25252500,0xababab00,0x42424200, - 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, - 0x72727200,0x07070700,0xb9b9b900,0x55555500, - 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, - 0x36363600,0x49494900,0x2a2a2a00,0x68686800, - 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, - 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, - 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, - 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, - 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, - }; - -static const u32 camellia_sp0222[256] = +#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\ + u32 _t0=_s0>>(32-_n);\ + _s0 = (_s0<<_n) | (_s1>>(32-_n));\ + _s1 = (_s1<<_n) | (_s2>>(32-_n));\ + _s2 = (_s2<<_n) | (_s3>>(32-_n));\ + _s3 = (_s3<<_n) | _t0;\ +} while (0) + +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) { - 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, - 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, - 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, - 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, - 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, - 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, - 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, - 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, - 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, - 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, - 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, - 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, - 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, - 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, - 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, - 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, - 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, - 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, - 0x00e8e8e8,0x00242424,0x00565656,0x00404040, - 0x00e1e1e1,0x00636363,0x00090909,0x00333333, - 0x00bfbfbf,0x00989898,0x00979797,0x00858585, - 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, - 0x00dadada,0x006f6f6f,0x00535353,0x00626262, - 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, - 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, - 0x00bdbdbd,0x00363636,0x00222222,0x00383838, - 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, - 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, - 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, - 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, - 0x00484848,0x00101010,0x00d1d1d1,0x00515151, - 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, - 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, - 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, - 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, - 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, - 0x00202020,0x00898989,0x00000000,0x00909090, - 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, - 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, - 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, - 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, - 0x009b9b9b,0x00949494,0x00212121,0x00666666, - 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, - 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, - 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, - 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, - 0x00030303,0x002d2d2d,0x00dedede,0x00969696, - 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, - 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, - 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, - 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, - 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, - 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, - 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, - 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, - 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, - 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, - 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, - 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, - 0x00787878,0x00707070,0x00e3e3e3,0x00494949, - 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, - 0x00777777,0x00939393,0x00868686,0x00838383, - 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, - 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, - }; - -static const u32 camellia_sp3033[256] = - { - 0x38003838,0x41004141,0x16001616,0x76007676, - 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, - 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, - 0x75007575,0x06000606,0x57005757,0xa000a0a0, - 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, - 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, - 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, - 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, - 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, - 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, - 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, - 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, - 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, - 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, - 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, - 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, - 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, - 0xfd00fdfd,0x66006666,0x58005858,0x96009696, - 0x3a003a3a,0x09000909,0x95009595,0x10001010, - 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, - 0xef00efef,0x26002626,0xe500e5e5,0x61006161, - 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, - 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, - 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, - 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, - 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, - 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, - 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, - 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, - 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, - 0x12001212,0x04000404,0x74007474,0x54005454, - 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, - 0x55005555,0x68006868,0x50005050,0xbe00bebe, - 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, - 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, - 0x70007070,0xff00ffff,0x32003232,0x69006969, - 0x08000808,0x62006262,0x00000000,0x24002424, - 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, - 0x45004545,0x81008181,0x73007373,0x6d006d6d, - 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, - 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, - 0xe600e6e6,0x25002525,0x48004848,0x99009999, - 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, - 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, - 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, - 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, - 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, - 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, - 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, - 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, - 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, - 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, - 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, - 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, - 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, - 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, - 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, - 0x7c007c7c,0x77007777,0x56005656,0x05000505, - 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, - 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, - 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, - 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, - 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, - 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, - }; - -static const u32 camellia_sp4404[256] = - { - 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, - 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, - 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, - 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, - 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, - 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, - 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, - 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, - 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, - 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, - 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, - 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, - 0x14140014,0x3a3a003a,0xdede00de,0x11110011, - 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, - 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, - 0x24240024,0xe8e800e8,0x60600060,0x69690069, - 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, - 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, - 0x10100010,0x00000000,0xa3a300a3,0x75750075, - 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, - 0x87870087,0x83830083,0xcdcd00cd,0x90900090, - 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, - 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, - 0x81810081,0x6f6f006f,0x13130013,0x63630063, - 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, - 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, - 0x78780078,0x06060006,0xe7e700e7,0x71710071, - 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, - 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, - 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, - 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, - 0x15150015,0xadad00ad,0x77770077,0x80800080, - 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, - 0x85850085,0x35350035,0x0c0c000c,0x41410041, - 0xefef00ef,0x93930093,0x19190019,0x21210021, - 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, - 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, - 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, - 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, - 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, - 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, - 0x12120012,0x20200020,0xb1b100b1,0x99990099, - 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, - 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, - 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, - 0x0f0f000f,0x16160016,0x18180018,0x22220022, - 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, - 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, - 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, - 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, - 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, - 0x03030003,0xdada00da,0x3f3f003f,0x94940094, - 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, - 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, - 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, - 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, - 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, - 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, - 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, - 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, - 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, - 0x49490049,0x68680068,0x38380038,0xa4a400a4, - 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, - 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, - }; - -/** - * Stuff related to the Camellia key schedule - */ -#define subl(x) subL[(x)] -#define subr(x) subR[(x)] - -void camellia_setup128(const u8 *key, u32 *subkey) - { - u32 kll, klr, krl, krr; - u32 il, ir, t0, t1, w0, w1; - u32 kw4l, kw4r, dw, tl, tr; - u32 subL[26]; - u32 subR[26]; - - /** - * k == kll || klr || krl || krr (|| is concatination) - */ - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - /** - * generate KL dependent subkeys - */ - /* kw1 */ - subl(0) = kll; subr(0) = klr; - /* kw2 */ - subl(1) = krl; subr(1) = krr; - /* rotation left shift 15bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k3 */ - subl(4) = kll; subr(4) = klr; - /* k4 */ - subl(5) = krl; subr(5) = krr; - /* rotation left shift 15+30bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - /* k7 */ - subl(10) = kll; subr(10) = klr; - /* k8 */ - subl(11) = krl; subr(11) = krr; - /* rotation left shift 15+30+15bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k10 */ - subl(13) = krl; subr(13) = krr; - /* rotation left shift 15+30+15+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* kl3 */ - subl(16) = kll; subr(16) = klr; - /* kl4 */ - subl(17) = krl; subr(17) = krr; - /* rotation left shift 15+30+15+17+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k13 */ - subl(18) = kll; subr(18) = klr; - /* k14 */ - subl(19) = krl; subr(19) = krr; - /* rotation left shift 15+30+15+17+17+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k17 */ - subl(22) = kll; subr(22) = klr; - /* k18 */ - subl(23) = krl; subr(23) = krr; - - /* generate KA */ - kll = subl(0); klr = subr(0); - krl = subl(1); krr = subr(1); - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - /* current status == (kll, klr, w0, w1) */ - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KA dependent subkeys */ - /* k1, k2 */ - subl(2) = kll; subr(2) = klr; - subl(3) = krl; subr(3) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k5,k6 */ - subl(6) = kll; subr(6) = klr; - subl(7) = krl; subr(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* kl1, kl2 */ - subl(8) = kll; subr(8) = klr; - subl(9) = krl; subr(9) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k9 */ - subl(12) = kll; subr(12) = klr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k11, k12 */ - subl(14) = kll; subr(14) = klr; - subl(15) = krl; subr(15) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - /* k15, k16 */ - subl(20) = kll; subr(20) = klr; - subl(21) = krl; subr(21) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* kw3, kw4 */ - subl(24) = kll; subr(24) = klr; - subl(25) = krl; subr(25) = krr; - - - /* absorb kw2 to other subkeys */ -/* round 2 */ - subl(3) ^= subl(1); subr(3) ^= subr(1); -/* round 4 */ - subl(5) ^= subl(1); subr(5) ^= subr(1); -/* round 6 */ - subl(7) ^= subl(1); subr(7) ^= subr(1); - subl(1) ^= subr(1) & ~subr(9); - dw = subl(1) & subl(9), - subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ -/* round 8 */ - subl(11) ^= subl(1); subr(11) ^= subr(1); -/* round 10 */ - subl(13) ^= subl(1); subr(13) ^= subr(1); -/* round 12 */ - subl(15) ^= subl(1); subr(15) ^= subr(1); - subl(1) ^= subr(1) & ~subr(17); - dw = subl(1) & subl(17), - subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ -/* round 14 */ - subl(19) ^= subl(1); subr(19) ^= subr(1); -/* round 16 */ - subl(21) ^= subl(1); subr(21) ^= subr(1); -/* round 18 */ - subl(23) ^= subl(1); subr(23) ^= subr(1); -/* kw3 */ - subl(24) ^= subl(1); subr(24) ^= subr(1); - - /* absorb kw4 to other subkeys */ - kw4l = subl(25); kw4r = subr(25); -/* round 17 */ - subl(22) ^= kw4l; subr(22) ^= kw4r; -/* round 15 */ - subl(20) ^= kw4l; subr(20) ^= kw4r; -/* round 13 */ - subl(18) ^= kw4l; subr(18) ^= kw4r; - kw4l ^= kw4r & ~subr(16); - dw = kw4l & subl(16), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ -/* round 11 */ - subl(14) ^= kw4l; subr(14) ^= kw4r; -/* round 9 */ - subl(12) ^= kw4l; subr(12) ^= kw4r; -/* round 7 */ - subl(10) ^= kw4l; subr(10) ^= kw4r; - kw4l ^= kw4r & ~subr(8); - dw = kw4l & subl(8), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ -/* round 5 */ - subl(6) ^= kw4l; subr(6) ^= kw4r; -/* round 3 */ - subl(4) ^= kw4l; subr(4) ^= kw4r; -/* round 1 */ - subl(2) ^= kw4l; subr(2) ^= kw4r; -/* kw1 */ - subl(0) ^= kw4l; subr(0) ^= kw4r; - - - /* key XOR is end of F-function */ - CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */ - CamelliaSubkeyR(0) = subr(0) ^ subr(2); - CamelliaSubkeyL(2) = subl(3); /* round 1 */ - CamelliaSubkeyR(2) = subr(3); - CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */ - CamelliaSubkeyR(3) = subr(2) ^ subr(4); - CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */ - CamelliaSubkeyR(4) = subr(3) ^ subr(5); - CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */ - CamelliaSubkeyR(5) = subr(4) ^ subr(6); - CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */ - CamelliaSubkeyR(6) = subr(5) ^ subr(7); - tl = subl(10) ^ (subr(10) & ~subr(8)); - dw = tl & subl(8), /* FL(kl1) */ - tr = subr(10) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */ - CamelliaSubkeyR(7) = subr(6) ^ tr; - CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */ - CamelliaSubkeyR(8) = subr(8); - CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */ - CamelliaSubkeyR(9) = subr(9); - tl = subl(7) ^ (subr(7) & ~subr(9)); - dw = tl & subl(9), /* FLinv(kl2) */ - tr = subr(7) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */ - CamelliaSubkeyR(10) = tr ^ subr(11); - CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */ - CamelliaSubkeyR(11) = subr(10) ^ subr(12); - CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */ - CamelliaSubkeyR(12) = subr(11) ^ subr(13); - CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */ - CamelliaSubkeyR(13) = subr(12) ^ subr(14); - CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */ - CamelliaSubkeyR(14) = subr(13) ^ subr(15); - tl = subl(18) ^ (subr(18) & ~subr(16)); - dw = tl & subl(16), /* FL(kl3) */ - tr = subr(18) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */ - CamelliaSubkeyR(15) = subr(14) ^ tr; - CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */ - CamelliaSubkeyR(16) = subr(16); - CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */ - CamelliaSubkeyR(17) = subr(17); - tl = subl(15) ^ (subr(15) & ~subr(17)); - dw = tl & subl(17), /* FLinv(kl4) */ - tr = subr(15) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */ - CamelliaSubkeyR(18) = tr ^ subr(19); - CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */ - CamelliaSubkeyR(19) = subr(18) ^ subr(20); - CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */ - CamelliaSubkeyR(20) = subr(19) ^ subr(21); - CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */ - CamelliaSubkeyR(21) = subr(20) ^ subr(22); - CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */ - CamelliaSubkeyR(22) = subr(21) ^ subr(23); - CamelliaSubkeyL(23) = subl(22); /* round 18 */ - CamelliaSubkeyR(23) = subr(22); - CamelliaSubkeyL(24) = subl(24) ^ subl(23); /* kw3 */ - CamelliaSubkeyR(24) = subr(24) ^ subr(23); - - /* apply the inverse of the last half of P-function */ - dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), - dw = CAMELLIA_RL8(dw);/* round 1 */ - CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, - CamelliaSubkeyL(2) = dw; - dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), - dw = CAMELLIA_RL8(dw);/* round 2 */ - CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, - CamelliaSubkeyL(3) = dw; - dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), - dw = CAMELLIA_RL8(dw);/* round 3 */ - CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, - CamelliaSubkeyL(4) = dw; - dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), - dw = CAMELLIA_RL8(dw);/* round 4 */ - CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, - CamelliaSubkeyL(5) = dw; - dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), - dw = CAMELLIA_RL8(dw);/* round 5 */ - CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, - CamelliaSubkeyL(6) = dw; - dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), - dw = CAMELLIA_RL8(dw);/* round 6 */ - CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, - CamelliaSubkeyL(7) = dw; - dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), - dw = CAMELLIA_RL8(dw);/* round 7 */ - CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, - CamelliaSubkeyL(10) = dw; - dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), - dw = CAMELLIA_RL8(dw);/* round 8 */ - CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, - CamelliaSubkeyL(11) = dw; - dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), - dw = CAMELLIA_RL8(dw);/* round 9 */ - CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, - CamelliaSubkeyL(12) = dw; - dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), - dw = CAMELLIA_RL8(dw);/* round 10 */ - CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, - CamelliaSubkeyL(13) = dw; - dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), - dw = CAMELLIA_RL8(dw);/* round 11 */ - CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, - CamelliaSubkeyL(14) = dw; - dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), - dw = CAMELLIA_RL8(dw);/* round 12 */ - CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, - CamelliaSubkeyL(15) = dw; - dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), - dw = CAMELLIA_RL8(dw);/* round 13 */ - CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, - CamelliaSubkeyL(18) = dw; - dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), - dw = CAMELLIA_RL8(dw);/* round 14 */ - CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, - CamelliaSubkeyL(19) = dw; - dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), - dw = CAMELLIA_RL8(dw);/* round 15 */ - CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, - CamelliaSubkeyL(20) = dw; - dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), - dw = CAMELLIA_RL8(dw);/* round 16 */ - CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, - CamelliaSubkeyL(21) = dw; - dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), - dw = CAMELLIA_RL8(dw);/* round 17 */ - CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, - CamelliaSubkeyL(22) = dw; - dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), - dw = CAMELLIA_RL8(dw);/* round 18 */ - CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, - CamelliaSubkeyL(23) = dw; - - return; + register u32 s0,s1,s2,s3; + + k[0] = s0 = GETU32(rawKey); + k[1] = s1 = GETU32(rawKey+4); + k[2] = s2 = GETU32(rawKey+8); + k[3] = s3 = GETU32(rawKey+12); + + if (keyBitLength != 128) + { + k[8] = s0 = GETU32(rawKey+16); + k[9] = s1 = GETU32(rawKey+20); + if (keyBitLength == 192) + { + k[10] = s2 = ~s0; + k[11] = s3 = ~s1; + } + else + { + k[10] = s2 = GETU32(rawKey+24); + k[11] = s3 = GETU32(rawKey+28); + } + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + } + + /* Use the Feistel routine to scramble the key material */ + Camellia_Feistel(s0,s1,s2,s3,SIGMA+0); + Camellia_Feistel(s2,s3,s0,s1,SIGMA+2); + + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + Camellia_Feistel(s0,s1,s2,s3,SIGMA+4); + Camellia_Feistel(s2,s3,s0,s1,SIGMA+6); + + /* Fill the keyTable. Requires many block rotations. */ + if (keyBitLength == 128) + { + k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3; + RotLeft128(s0,s1,s2,s3,15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0,s1,s2,s3,15); /* KA <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0,s1,s2,s3,15); /* KA <<< 45 */ + k[24] = s0, k[25] = s1; + RotLeft128(s0,s1,s2,s3,15); /* KA <<< 60 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + RotLeft128(s1,s2,s3,s0,2); /* KA <<< 94 */ + k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; + RotLeft128(s1,s2,s3,s0,17); /* KA <<<111 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + + s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3]; + RotLeft128(s0,s1,s2,s3,15); /* KL <<< 15 */ + k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0,s1,s2,s3,30); /* KL <<< 45 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0,s1,s2,s3,15); /* KL <<< 60 */ + k[26] = s2, k[27] = s3; + RotLeft128(s0,s1,s2,s3,17); /* KL <<< 77 */ + k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; + RotLeft128(s0,s1,s2,s3,17); /* KL <<< 94 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s0,s1,s2,s3,17); /* KL <<<111 */ + k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; + + return 3; /* grand rounds */ + } + else + { + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11]; + Camellia_Feistel(s0,s1,s2,s3,(SIGMA+8)); + Camellia_Feistel(s2,s3,s0,s1,(SIGMA+10)); + + k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3; + RotLeft128(s0,s1,s2,s3,30); /* KB <<< 30 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0,s1,s2,s3,30); /* KB <<< 60 */ + k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; + RotLeft128(s1,s2,s3,s0,19); /* KB <<<111 */ + k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; + + s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11]; + RotLeft128(s0,s1,s2,s3,15); /* KR <<< 15 */ + k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0,s1,s2,s3,15); /* KR <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0,s1,s2,s3,30); /* KR <<< 60 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s1,s2,s3,s0,2); /* KR <<< 94 */ + k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; + + s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; + RotLeft128(s0,s1,s2,s3,15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0,s1,s2,s3,30); /* KA <<< 45 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + /* KA <<< 77 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + RotLeft128(s1,s2,s3,s0,17); /* KA <<< 94 */ + k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; + + s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3]; + RotLeft128(s1,s2,s3,s0,13); /* KL <<< 45 */ + k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; + RotLeft128(s1,s2,s3,s0,15); /* KL <<< 60 */ + k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; + RotLeft128(s1,s2,s3,s0,17); /* KL <<< 77 */ + k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; + RotLeft128(s2,s3,s0,s1,2); /* KL <<<111 */ + k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; + + return 4; /* grand rounds */ + } + /* + * It is possible to perform certain precalculations, which + * would spare few cycles in block procedure. It's not done, + * because it upsets the performance balance between key + * setup and block procedures, negatively affecting overall + * throughput in applications operating on short messages + * and volatile keys. + */ } -void camellia_setup256(const u8 *key, u32 *subkey) +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) { - u32 kll,klr,krl,krr; /* left half of key */ - u32 krll,krlr,krrl,krrr; /* right half of key */ - u32 il, ir, t0, t1, w0, w1; /* temporary variables */ - u32 kw4l, kw4r, dw, tl, tr; - u32 subL[34]; - u32 subR[34]; - - /** - * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) - * (|| is concatination) - */ - - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - krll = GETU32(key + 16); - krlr = GETU32(key + 20); - krrl = GETU32(key + 24); - krrr = GETU32(key + 28); - - /* generate KL dependent subkeys */ - /* kw1 */ - subl(0) = kll; subr(0) = klr; - /* kw2 */ - subl(1) = krl; subr(1) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); - /* k9 */ - subl(12) = kll; subr(12) = klr; - /* k10 */ - subl(13) = krl; subr(13) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* kl3 */ - subl(16) = kll; subr(16) = klr; - /* kl4 */ - subl(17) = krl; subr(17) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k17 */ - subl(22) = kll; subr(22) = klr; - /* k18 */ - subl(23) = krl; subr(23) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - /* k23 */ - subl(30) = kll; subr(30) = klr; - /* k24 */ - subl(31) = krl; subr(31) = krr; - - /* generate KR dependent subkeys */ - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - /* k3 */ - subl(4) = krll; subr(4) = krlr; - /* k4 */ - subl(5) = krrl; subr(5) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - /* kl1 */ - subl(8) = krll; subr(8) = krlr; - /* kl2 */ - subl(9) = krrl; subr(9) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k13 */ - subl(18) = krll; subr(18) = krlr; - /* k14 */ - subl(19) = krrl; subr(19) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - /* k19 */ - subl(26) = krll; subr(26) = krlr; - /* k20 */ - subl(27) = krrl; subr(27) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - - /* generate KA */ - kll = subl(0) ^ krll; klr = subr(0) ^ krlr; - krl = subl(1) ^ krrl; krr = subr(1) ^ krrr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - kll ^= krll; klr ^= krlr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KB */ - krll ^= kll; krlr ^= klr; - krrl ^= krl; krrr ^= krr; - CAMELLIA_F(krll, krlr, - CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, - w0, w1, il, ir, t0, t1); - krrl ^= w0; krrr ^= w1; - CAMELLIA_F(krrl, krrr, - CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, - w0, w1, il, ir, t0, t1); - krll ^= w0; krlr ^= w1; - - /* generate KA dependent subkeys */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k5 */ - subl(6) = kll; subr(6) = klr; - /* k6 */ - subl(7) = krl; subr(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - /* k11 */ - subl(14) = kll; subr(14) = klr; - /* k12 */ - subl(15) = krl; subr(15) = krr; - /* rotation left shift 32bit */ - /* kl5 */ - subl(24) = klr; subr(24) = krl; - /* kl6 */ - subl(25) = krr; subr(25) = kll; - /* rotation left shift 49 from k11,k12 -> k21,k22 */ - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); - /* k21 */ - subl(28) = kll; subr(28) = klr; - /* k22 */ - subl(29) = krl; subr(29) = krr; - - /* generate KB dependent subkeys */ - /* k1 */ - subl(2) = krll; subr(2) = krlr; - /* k2 */ - subl(3) = krrl; subr(3) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k7 */ - subl(10) = krll; subr(10) = krlr; - /* k8 */ - subl(11) = krrl; subr(11) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k15 */ - subl(20) = krll; subr(20) = krlr; - /* k16 */ - subl(21) = krrl; subr(21) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); - /* kw3 */ - subl(32) = krll; subr(32) = krlr; - /* kw4 */ - subl(33) = krrl; subr(33) = krrr; - - /* absorb kw2 to other subkeys */ -/* round 2 */ - subl(3) ^= subl(1); subr(3) ^= subr(1); -/* round 4 */ - subl(5) ^= subl(1); subr(5) ^= subr(1); -/* round 6 */ - subl(7) ^= subl(1); subr(7) ^= subr(1); - subl(1) ^= subr(1) & ~subr(9); - dw = subl(1) & subl(9), - subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ -/* round 8 */ - subl(11) ^= subl(1); subr(11) ^= subr(1); -/* round 10 */ - subl(13) ^= subl(1); subr(13) ^= subr(1); -/* round 12 */ - subl(15) ^= subl(1); subr(15) ^= subr(1); - subl(1) ^= subr(1) & ~subr(17); - dw = subl(1) & subl(17), - subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ -/* round 14 */ - subl(19) ^= subl(1); subr(19) ^= subr(1); -/* round 16 */ - subl(21) ^= subl(1); subr(21) ^= subr(1); -/* round 18 */ - subl(23) ^= subl(1); subr(23) ^= subr(1); - subl(1) ^= subr(1) & ~subr(25); - dw = subl(1) & subl(25), - subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */ -/* round 20 */ - subl(27) ^= subl(1); subr(27) ^= subr(1); -/* round 22 */ - subl(29) ^= subl(1); subr(29) ^= subr(1); -/* round 24 */ - subl(31) ^= subl(1); subr(31) ^= subr(1); -/* kw3 */ - subl(32) ^= subl(1); subr(32) ^= subr(1); - - - /* absorb kw4 to other subkeys */ - kw4l = subl(33); kw4r = subr(33); -/* round 23 */ - subl(30) ^= kw4l; subr(30) ^= kw4r; -/* round 21 */ - subl(28) ^= kw4l; subr(28) ^= kw4r; -/* round 19 */ - subl(26) ^= kw4l; subr(26) ^= kw4r; - kw4l ^= kw4r & ~subr(24); - dw = kw4l & subl(24), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */ -/* round 17 */ - subl(22) ^= kw4l; subr(22) ^= kw4r; -/* round 15 */ - subl(20) ^= kw4l; subr(20) ^= kw4r; -/* round 13 */ - subl(18) ^= kw4l; subr(18) ^= kw4r; - kw4l ^= kw4r & ~subr(16); - dw = kw4l & subl(16), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ -/* round 11 */ - subl(14) ^= kw4l; subr(14) ^= kw4r; -/* round 9 */ - subl(12) ^= kw4l; subr(12) ^= kw4r; -/* round 7 */ - subl(10) ^= kw4l; subr(10) ^= kw4r; - kw4l ^= kw4r & ~subr(8); - dw = kw4l & subl(8), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ -/* round 5 */ - subl(6) ^= kw4l; subr(6) ^= kw4r; -/* round 3 */ - subl(4) ^= kw4l; subr(4) ^= kw4r; -/* round 1 */ - subl(2) ^= kw4l; subr(2) ^= kw4r; -/* kw1 */ - subl(0) ^= kw4l; subr(0) ^= kw4r; - - /* key XOR is end of F-function */ - CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */ - CamelliaSubkeyR(0) = subr(0) ^ subr(2); - CamelliaSubkeyL(2) = subl(3); /* round 1 */ - CamelliaSubkeyR(2) = subr(3); - CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */ - CamelliaSubkeyR(3) = subr(2) ^ subr(4); - CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */ - CamelliaSubkeyR(4) = subr(3) ^ subr(5); - CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */ - CamelliaSubkeyR(5) = subr(4) ^ subr(6); - CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */ - CamelliaSubkeyR(6) = subr(5) ^ subr(7); - tl = subl(10) ^ (subr(10) & ~subr(8)); - dw = tl & subl(8), /* FL(kl1) */ - tr = subr(10) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */ - CamelliaSubkeyR(7) = subr(6) ^ tr; - CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */ - CamelliaSubkeyR(8) = subr(8); - CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */ - CamelliaSubkeyR(9) = subr(9); - tl = subl(7) ^ (subr(7) & ~subr(9)); - dw = tl & subl(9), /* FLinv(kl2) */ - tr = subr(7) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */ - CamelliaSubkeyR(10) = tr ^ subr(11); - CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */ - CamelliaSubkeyR(11) = subr(10) ^ subr(12); - CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */ - CamelliaSubkeyR(12) = subr(11) ^ subr(13); - CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */ - CamelliaSubkeyR(13) = subr(12) ^ subr(14); - CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */ - CamelliaSubkeyR(14) = subr(13) ^ subr(15); - tl = subl(18) ^ (subr(18) & ~subr(16)); - dw = tl & subl(16), /* FL(kl3) */ - tr = subr(18) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */ - CamelliaSubkeyR(15) = subr(14) ^ tr; - CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */ - CamelliaSubkeyR(16) = subr(16); - CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */ - CamelliaSubkeyR(17) = subr(17); - tl = subl(15) ^ (subr(15) & ~subr(17)); - dw = tl & subl(17), /* FLinv(kl4) */ - tr = subr(15) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */ - CamelliaSubkeyR(18) = tr ^ subr(19); - CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */ - CamelliaSubkeyR(19) = subr(18) ^ subr(20); - CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */ - CamelliaSubkeyR(20) = subr(19) ^ subr(21); - CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */ - CamelliaSubkeyR(21) = subr(20) ^ subr(22); - CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */ - CamelliaSubkeyR(22) = subr(21) ^ subr(23); - tl = subl(26) ^ (subr(26) - & ~subr(24)); - dw = tl & subl(24), /* FL(kl5) */ - tr = subr(26) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(23) = subl(22) ^ tl; /* round 18 */ - CamelliaSubkeyR(23) = subr(22) ^ tr; - CamelliaSubkeyL(24) = subl(24); /* FL(kl5) */ - CamelliaSubkeyR(24) = subr(24); - CamelliaSubkeyL(25) = subl(25); /* FLinv(kl6) */ - CamelliaSubkeyR(25) = subr(25); - tl = subl(23) ^ (subr(23) & - ~subr(25)); - dw = tl & subl(25), /* FLinv(kl6) */ - tr = subr(23) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(26) = tl ^ subl(27); /* round 19 */ - CamelliaSubkeyR(26) = tr ^ subr(27); - CamelliaSubkeyL(27) = subl(26) ^ subl(28); /* round 20 */ - CamelliaSubkeyR(27) = subr(26) ^ subr(28); - CamelliaSubkeyL(28) = subl(27) ^ subl(29); /* round 21 */ - CamelliaSubkeyR(28) = subr(27) ^ subr(29); - CamelliaSubkeyL(29) = subl(28) ^ subl(30); /* round 22 */ - CamelliaSubkeyR(29) = subr(28) ^ subr(30); - CamelliaSubkeyL(30) = subl(29) ^ subl(31); /* round 23 */ - CamelliaSubkeyR(30) = subr(29) ^ subr(31); - CamelliaSubkeyL(31) = subl(30); /* round 24 */ - CamelliaSubkeyR(31) = subr(30); - CamelliaSubkeyL(32) = subl(32) ^ subl(31); /* kw3 */ - CamelliaSubkeyR(32) = subr(32) ^ subr(31); - - /* apply the inverse of the last half of P-function */ - dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), - dw = CAMELLIA_RL8(dw);/* round 1 */ - CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, - CamelliaSubkeyL(2) = dw; - dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), - dw = CAMELLIA_RL8(dw);/* round 2 */ - CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, - CamelliaSubkeyL(3) = dw; - dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), - dw = CAMELLIA_RL8(dw);/* round 3 */ - CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, - CamelliaSubkeyL(4) = dw; - dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), - dw = CAMELLIA_RL8(dw);/* round 4 */ - CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, - CamelliaSubkeyL(5) = dw; - dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), - dw = CAMELLIA_RL8(dw);/* round 5 */ - CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, - CamelliaSubkeyL(6) = dw; - dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), - dw = CAMELLIA_RL8(dw);/* round 6 */ - CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, - CamelliaSubkeyL(7) = dw; - dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), - dw = CAMELLIA_RL8(dw);/* round 7 */ - CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, - CamelliaSubkeyL(10) = dw; - dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), - dw = CAMELLIA_RL8(dw);/* round 8 */ - CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, - CamelliaSubkeyL(11) = dw; - dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), - dw = CAMELLIA_RL8(dw);/* round 9 */ - CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, - CamelliaSubkeyL(12) = dw; - dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), - dw = CAMELLIA_RL8(dw);/* round 10 */ - CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, - CamelliaSubkeyL(13) = dw; - dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), - dw = CAMELLIA_RL8(dw);/* round 11 */ - CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, - CamelliaSubkeyL(14) = dw; - dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), - dw = CAMELLIA_RL8(dw);/* round 12 */ - CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, - CamelliaSubkeyL(15) = dw; - dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), - dw = CAMELLIA_RL8(dw);/* round 13 */ - CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, - CamelliaSubkeyL(18) = dw; - dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), - dw = CAMELLIA_RL8(dw);/* round 14 */ - CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, - CamelliaSubkeyL(19) = dw; - dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), - dw = CAMELLIA_RL8(dw);/* round 15 */ - CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, - CamelliaSubkeyL(20) = dw; - dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), - dw = CAMELLIA_RL8(dw);/* round 16 */ - CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, - CamelliaSubkeyL(21) = dw; - dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), - dw = CAMELLIA_RL8(dw);/* round 17 */ - CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, - CamelliaSubkeyL(22) = dw; - dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), - dw = CAMELLIA_RL8(dw);/* round 18 */ - CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, - CamelliaSubkeyL(23) = dw; - dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), - dw = CAMELLIA_RL8(dw);/* round 19 */ - CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, - CamelliaSubkeyL(26) = dw; - dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), - dw = CAMELLIA_RL8(dw);/* round 20 */ - CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, - CamelliaSubkeyL(27) = dw; - dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), - dw = CAMELLIA_RL8(dw);/* round 21 */ - CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, - CamelliaSubkeyL(28) = dw; - dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), - dw = CAMELLIA_RL8(dw);/* round 22 */ - CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, - CamelliaSubkeyL(29) = dw; - dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), - dw = CAMELLIA_RL8(dw);/* round 23 */ - CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, - CamelliaSubkeyL(30) = dw; - dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), - dw = CAMELLIA_RL8(dw);/* round 24 */ - CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw, - CamelliaSubkeyL(31) = dw; - - - return; + register u32 s0,s1,s2,s3; + const u32 *k = keyTable,*kend = keyTable+grandRounds*16; + + s0 = GETU32(plaintext) ^ k[0]; + s1 = GETU32(plaintext+4) ^ k[1]; + s2 = GETU32(plaintext+8) ^ k[2]; + s3 = GETU32(plaintext+12) ^ k[3]; + k += 4; + + while (1) + { + /* Camellia makes 6 Feistel rounds */ + Camellia_Feistel(s0,s1,s2,s3,k+0); + Camellia_Feistel(s2,s3,s0,s1,k+2); + Camellia_Feistel(s0,s1,s2,s3,k+4); + Camellia_Feistel(s2,s3,s0,s1,k+6); + Camellia_Feistel(s0,s1,s2,s3,k+8); + Camellia_Feistel(s2,s3,s0,s1,k+10); + k += 12; + + if (k == kend) break; + + /* This is the same function as the diffusion function D + * of the accompanying documentation. See section 3.2 + * for properties of the FLlayer function. */ + s1 ^= LeftRotate(s0 & k[0], 1); + s2 ^= s3 | k[3]; + s0 ^= s1 | k[1]; + s3 ^= LeftRotate(s2 & k[2], 1); + k += 4; + } + + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(ciphertext, s2); + PUTU32(ciphertext+4, s3); + PUTU32(ciphertext+8, s0); + PUTU32(ciphertext+12,s1); } - -void camellia_setup192(const u8 *key, u32 *subkey) - { - u8 kk[32]; - u32 krll, krlr, krrl,krrr; - - memcpy(kk, key, 24); - memcpy((u8 *)&krll, key+16,4); - memcpy((u8 *)&krlr, key+20,4); - krrl = ~krll; - krrr = ~krlr; - memcpy(kk+24, (u8 *)&krrl, 4); - memcpy(kk+28, (u8 *)&krrr, 4); - camellia_setup256(kk, subkey); - return; - } - - -/** - * Stuff related to camellia encryption/decryption - */ -void camellia_encrypt128(const u32 *subkey, u32 *io) - { - u32 il, ir, t0, t1; - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(0); - io[1] ^= CamelliaSubkeyR(0); - /* main iteration */ - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(24); - io[3] ^= CamelliaSubkeyR(24); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; - } - -void camellia_decrypt128(const u32 *subkey, u32 *io) +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) { - u32 il,ir,t0,t1; /* temporary valiables */ - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(24); - io[1] ^= CamelliaSubkeyR(24); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(0); - io[3] ^= CamelliaSubkeyR(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; + Camellia_EncryptBlock_Rounds(keyBitLength==128?3:4, + plaintext,keyTable,ciphertext); } -/** - * stuff for 192 and 256bit encryption/decryption - */ -void camellia_encrypt256(const u32 *subkey, u32 *io) +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]) { - u32 il,ir,t0,t1; /* temporary valiables */ - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(0); - io[1] ^= CamelliaSubkeyR(0); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(24),CamelliaSubkeyR(24), - CamelliaSubkeyL(25),CamelliaSubkeyR(25), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(26),CamelliaSubkeyR(26), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(27),CamelliaSubkeyR(27), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(28),CamelliaSubkeyR(28), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(29),CamelliaSubkeyR(29), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(30),CamelliaSubkeyR(30), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(31),CamelliaSubkeyR(31), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(32); - io[3] ^= CamelliaSubkeyR(32); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; + u32 s0,s1,s2,s3; + const u32 *k = keyTable+grandRounds*16,*kend = keyTable+4; + + s0 = GETU32(ciphertext) ^ k[0]; + s1 = GETU32(ciphertext+4) ^ k[1]; + s2 = GETU32(ciphertext+8) ^ k[2]; + s3 = GETU32(ciphertext+12) ^ k[3]; + + while (1) + { + /* Camellia makes 6 Feistel rounds */ + k -= 12; + Camellia_Feistel(s0,s1,s2,s3,k+10); + Camellia_Feistel(s2,s3,s0,s1,k+8); + Camellia_Feistel(s0,s1,s2,s3,k+6); + Camellia_Feistel(s2,s3,s0,s1,k+4); + Camellia_Feistel(s0,s1,s2,s3,k+2); + Camellia_Feistel(s2,s3,s0,s1,k+0); + + if (k == kend) break; + + /* This is the same function as the diffusion function D + * of the accompanying documentation. See section 3.2 + * for properties of the FLlayer function. */ + k -= 4; + s1 ^= LeftRotate(s0 & k[2], 1); + s2 ^= s3 | k[1]; + s0 ^= s1 | k[3]; + s3 ^= LeftRotate(s2 & k[0], 1); + } + + k -= 4; + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(plaintext, s2); + PUTU32(plaintext+4, s3); + PUTU32(plaintext+8, s0); + PUTU32(plaintext+12,s1); } - -void camellia_decrypt256(const u32 *subkey, u32 *io) +void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) { - u32 il,ir,t0,t1; /* temporary valiables */ - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(32); - io[1] ^= CamelliaSubkeyR(32); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(31),CamelliaSubkeyR(31), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(30),CamelliaSubkeyR(30), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(29),CamelliaSubkeyR(29), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(28),CamelliaSubkeyR(28), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(27),CamelliaSubkeyR(27), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(26),CamelliaSubkeyR(26), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(25),CamelliaSubkeyR(25), - CamelliaSubkeyL(24),CamelliaSubkeyR(24), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(0); - io[3] ^= CamelliaSubkeyR(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; + Camellia_DecryptBlock_Rounds(keyBitLength==128?3:4, + plaintext,keyTable,ciphertext); } - diff --git a/crypto/openssl/crypto/camellia/camellia.h b/crypto/openssl/crypto/camellia/camellia.h index b8a8b6e10b..cf0457dd97 100644 --- a/crypto/openssl/crypto/camellia/camellia.h +++ b/crypto/openssl/crypto/camellia/camellia.h @@ -58,6 +58,8 @@ #error CAMELLIA is disabled. #endif +#include + #define CAMELLIA_ENCRYPT 1 #define CAMELLIA_DECRYPT 0 @@ -74,24 +76,18 @@ extern "C" { #define CAMELLIA_TABLE_BYTE_LEN 272 #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) - /* to match with WORD */ -typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */ struct camellia_key_st { - KEY_TABLE_TYPE rd_key; - int bitLength; - void (*enc)(const unsigned int *subkey, unsigned int *io); - void (*dec)(const unsigned int *subkey, unsigned int *io); + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; }; - typedef struct camellia_key_st CAMELLIA_KEY; -#ifdef OPENSSL_FIPS -int private_Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key); -#endif - int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key); @@ -103,25 +99,22 @@ void Camellia_decrypt(const unsigned char *in, unsigned char *out, void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key, const int enc); void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, const int enc); void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc); void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc); void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc); -void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, - const int nbits,const CAMELLIA_KEY *key, - unsigned char *ivec,const int enc); void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num); void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char ivec[CAMELLIA_BLOCK_SIZE], unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], unsigned int *num); @@ -131,4 +124,3 @@ void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, #endif #endif /* !HEADER_Camellia_H */ - diff --git a/crypto/openssl/crypto/camellia/cmll_cbc.c b/crypto/openssl/crypto/camellia/cmll_cbc.c index 4141a7b59b..4c8d455ade 100644 --- a/crypto/openssl/crypto/camellia/cmll_cbc.c +++ b/crypto/openssl/crypto/camellia/cmll_cbc.c @@ -49,225 +49,16 @@ * */ -#ifndef CAMELLIA_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include -#include -#include - #include -#include "cmll_locl.h" +#include void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, - unsigned char *ivec, const int enc) { - - unsigned long n; - unsigned long len = length; - const unsigned char *iv = ivec; - union { u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; - u8 t8 [CAMELLIA_BLOCK_SIZE]; } tmp; - const union { long one; char little; } camellia_endian = {1}; - - - assert(in && out && key && ivec); - assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc)); + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc) + { - if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0) - { - if (CAMELLIA_ENCRYPT == enc) - { - while (len >= CAMELLIA_BLOCK_SIZE) - { - XOR4WORD2((u32 *)out, - (u32 *)in, (u32 *)iv); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - key->enc(key->rd_key, (u32 *)out); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - iv = out; - len -= CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - out += CAMELLIA_BLOCK_SIZE; - } - if (len) - { - for(n=0; n < len; ++n) - out[n] = in[n] ^ iv[n]; - for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) - out[n] = iv[n]; - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - key->enc(key->rd_key, (u32 *)out); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - iv = out; - } - memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); - } - else if (in != out) - { - while (len >= CAMELLIA_BLOCK_SIZE) - { - memcpy(out,in,CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - key->dec(key->rd_key,(u32 *)out); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - XOR4WORD((u32 *)out, (u32 *)iv); - iv = in; - len -= CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - out += CAMELLIA_BLOCK_SIZE; - } - if (len) - { - memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->dec(key->rd_key, tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - for(n=0; n < len; ++n) - out[n] = tmp.t8[n] ^ iv[n]; - iv = in; - } - memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); - } - else /* in == out */ - { - while (len >= CAMELLIA_BLOCK_SIZE) - { - memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - key->dec(key->rd_key, (u32 *)out); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - XOR4WORD((u32 *)out, (u32 *)ivec); - memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); - len -= CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - out += CAMELLIA_BLOCK_SIZE; - } - if (len) - { - memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - key->dec(key->rd_key,(u32 *)out); - if (camellia_endian.little) - SWAP4WORD((u32 *)out); - for(n=0; n < len; ++n) - out[n] ^= ivec[n]; - for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) - out[n] = tmp.t8[n]; - memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); - } - } - } - else /* no aligned */ - { - if (CAMELLIA_ENCRYPT == enc) - { - while (len >= CAMELLIA_BLOCK_SIZE) - { - for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) - tmp.t8[n] = in[n] ^ iv[n]; - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->enc(key->rd_key, tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); - iv = out; - len -= CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - out += CAMELLIA_BLOCK_SIZE; - } - if (len) - { - for(n=0; n < len; ++n) - tmp.t8[n] = in[n] ^ iv[n]; - for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) - tmp.t8[n] = iv[n]; - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->enc(key->rd_key, tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); - iv = out; - } - memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); - } - else if (in != out) - { - while (len >= CAMELLIA_BLOCK_SIZE) - { - memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->dec(key->rd_key,tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) - out[n] = tmp.t8[n] ^ iv[n]; - iv = in; - len -= CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - out += CAMELLIA_BLOCK_SIZE; - } - if (len) - { - memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->dec(key->rd_key, tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - for(n=0; n < len; ++n) - out[n] = tmp.t8[n] ^ iv[n]; - iv = in; - } - memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); - } - else - { - while (len >= CAMELLIA_BLOCK_SIZE) - { - memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->dec(key->rd_key, tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) - tmp.t8[n] ^= ivec[n]; - memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); - memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); - len -= CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - out += CAMELLIA_BLOCK_SIZE; - } - if (len) - { - memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - key->dec(key->rd_key,tmp.t32); - if (camellia_endian.little) - SWAP4WORD(tmp.t32); - for(n=0; n < len; ++n) - tmp.t8[n] ^= ivec[n]; - memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); - memcpy(out,tmp.t8,len); - } - } - } -} + if (enc) + CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)Camellia_encrypt); + else + CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)Camellia_decrypt); + } diff --git a/crypto/openssl/crypto/camellia/cmll_cfb.c b/crypto/openssl/crypto/camellia/cmll_cfb.c index af0f9f49ad..3d81b51d3f 100644 --- a/crypto/openssl/crypto/camellia/cmll_cfb.c +++ b/crypto/openssl/crypto/camellia/cmll_cfb.c @@ -105,17 +105,8 @@ * [including the GNU Public Licence.] */ -#ifndef CAMELLIA_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include -#include - #include -#include "cmll_locl.h" -#include "e_os.h" +#include /* The input and output encrypted as though 128bit cfb mode is being @@ -124,112 +115,25 @@ */ void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) { - unsigned int n; - unsigned long l = length; - unsigned char c; - - assert(in && out && key && ivec && num); - - n = *num; - - if (enc) - { - while (l--) - { - if (n == 0) - { - Camellia_encrypt(ivec, ivec, key); - } - ivec[n] = *(out++) = *(in++) ^ ivec[n]; - n = (n+1) % CAMELLIA_BLOCK_SIZE; - } - } - else - { - while (l--) - { - if (n == 0) - { - Camellia_encrypt(ivec, ivec, key); - } - c = *(in); - *(out++) = *(in++) ^ ivec[n]; - ivec[n] = c; - n = (n+1) % CAMELLIA_BLOCK_SIZE; - } - } - - *num=n; - } - -/* This expects a single block of size nbits for both in and out. Note that - it corrupts any extra bits in the last byte of out */ -void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, - const int nbits,const CAMELLIA_KEY *key, - unsigned char *ivec,const int enc) - { - int n,rem,num; - unsigned char ovec[CAMELLIA_BLOCK_SIZE*2]; - - if (nbits<=0 || nbits>128) return; - - /* fill in the first half of the new IV with the current IV */ - memcpy(ovec,ivec,CAMELLIA_BLOCK_SIZE); - /* construct the new IV */ - Camellia_encrypt(ivec,ivec,key); - num = (nbits+7)/8; - if (enc) /* encrypt the input */ - for(n=0 ; n < num ; ++n) - out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n] ^ ivec[n]); - else /* decrypt the input */ - for(n=0 ; n < num ; ++n) - out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n]) ^ ivec[n]; - /* shift ovec left... */ - rem = nbits%8; - num = nbits/8; - if(rem==0) - memcpy(ivec,ovec+num,CAMELLIA_BLOCK_SIZE); - else - for(n=0 ; n < CAMELLIA_BLOCK_SIZE ; ++n) - ivec[n] = ovec[n+num]<>(8-rem); - - /* it is not necessary to cleanse ovec, since the IV is not secret */ + CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); } /* N.B. This expects the input to be packed, MS bit first */ void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) { - unsigned int n; - unsigned char c[1],d[1]; - - assert(in && out && key && ivec && num); - assert(*num == 0); - - memset(out,0,(length+7)/8); - for(n=0 ; n < length ; ++n) - { - c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; - Camellia_cfbr_encrypt_block(c,d,1,key,ivec,enc); - out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8)); - } + CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); } void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) { - unsigned int n; - - assert(in && out && key && ivec && num); - assert(*num == 0); - - for(n=0 ; n < length ; ++n) - Camellia_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc); + CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); } diff --git a/crypto/openssl/crypto/camellia/cmll_ctr.c b/crypto/openssl/crypto/camellia/cmll_ctr.c index cc21b70890..014e621a34 100644 --- a/crypto/openssl/crypto/camellia/cmll_ctr.c +++ b/crypto/openssl/crypto/camellia/cmll_ctr.c @@ -49,95 +49,16 @@ * */ -#ifndef CAMELLIA_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - #include -#include "cmll_locl.h" - -/* NOTE: the IV/counter CTR mode is big-endian. The rest of the Camellia code - * is endian-neutral. */ -/* increment counter (128-bit int) by 1 */ -static void Camellia_ctr128_inc(unsigned char *counter) - { - unsigned long c; - - /* Grab bottom dword of counter and increment */ - c = GETU32(counter + 12); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 12, c); - - /* if no overflow, we're done */ - if (c) - return; - - /* Grab 1st dword of counter and increment */ - c = GETU32(counter + 8); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 8, c); - - /* if no overflow, we're done */ - if (c) - return; - - /* Grab 2nd dword of counter and increment */ - c = GETU32(counter + 4); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 4, c); - - /* if no overflow, we're done */ - if (c) - return; +#include - /* Grab top dword of counter and increment */ - c = GETU32(counter + 0); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 0, c); - } - -/* The input encrypted as though 128bit counter mode is being - * used. The extra state information to record how much of the - * 128bit block we have used is contained in *num, and the - * encrypted counter is kept in ecount_buf. Both *num and - * ecount_buf must be initialised with zeros before the first - * call to Camellia_ctr128_encrypt(). - * - * This algorithm assumes that the counter is in the x lower bits - * of the IV (ivec), and that the application has full control over - * overflow and the rest of the IV. This implementation takes NO - * responsability for checking that the counter doesn't overflow - * into the rest of the IV when incremented. - */ void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char ivec[CAMELLIA_BLOCK_SIZE], unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], unsigned int *num) { - unsigned int n; - unsigned long l=length; - - assert(in && out && key && counter && num); - assert(*num < CAMELLIA_BLOCK_SIZE); - - n = *num; - - while (l--) - { - if (n == 0) - { - Camellia_encrypt(ivec, ecount_buf, key); - Camellia_ctr128_inc(ivec); - } - *(out++) = *(in++) ^ ecount_buf[n]; - n = (n+1) % CAMELLIA_BLOCK_SIZE; - } - - *num=n; + CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)Camellia_encrypt); } diff --git a/crypto/openssl/crypto/camellia/cmll_locl.h b/crypto/openssl/crypto/camellia/cmll_locl.h index 2ac2e95435..4a4d880d16 100644 --- a/crypto/openssl/crypto/camellia/cmll_locl.h +++ b/crypto/openssl/crypto/camellia/cmll_locl.h @@ -68,98 +68,16 @@ #ifndef HEADER_CAMELLIA_LOCL_H #define HEADER_CAMELLIA_LOCL_H -#include "openssl/e_os2.h" -#include -#include -#include - +typedef unsigned int u32; typedef unsigned char u8; -typedef unsigned int u32; - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 ) -# define GETU32(p) SWAP(*((u32 *)(p))) -# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } -# define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) ) - -#else /* not windows */ -# define GETU32(pt) (((u32)(pt)[0] << 24) \ - ^ ((u32)(pt)[1] << 16) \ - ^ ((u32)(pt)[2] << 8) \ - ^ ((u32)(pt)[3])) - -# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \ - (ct)[1] = (u8)((st) >> 16); \ - (ct)[2] = (u8)((st) >> 8); \ - (ct)[3] = (u8)(st); } - -#if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64))) -#define CAMELLIA_SWAP4(x) \ - do{\ - asm("bswap %1" : "+r" (x));\ - }while(0) -#else -#define CAMELLIA_SWAP4(x) \ - do{\ - x = ((u32)x << 16) + ((u32)x >> 16);\ - x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\ - } while(0) -#endif -#endif - -#define COPY4WORD(dst, src) \ - do \ - { \ - (dst)[0]=(src)[0]; \ - (dst)[1]=(src)[1]; \ - (dst)[2]=(src)[2]; \ - (dst)[3]=(src)[3]; \ - }while(0) - -#define SWAP4WORD(word) \ - do \ - { \ - CAMELLIA_SWAP4((word)[0]); \ - CAMELLIA_SWAP4((word)[1]); \ - CAMELLIA_SWAP4((word)[2]); \ - CAMELLIA_SWAP4((word)[3]); \ - }while(0) - -#define XOR4WORD(a, b)/* a = a ^ b */ \ - do \ - { \ - (a)[0]^=(b)[0]; \ - (a)[1]^=(b)[1]; \ - (a)[2]^=(b)[2]; \ - (a)[3]^=(b)[3]; \ - }while(0) - -#define XOR4WORD2(a, b, c)/* a = b ^ c */ \ - do \ - { \ - (a)[0]=(b)[0]^(c)[0]; \ - (a)[1]=(b)[1]^(c)[1]; \ - (a)[2]=(b)[2]^(c)[2]; \ - (a)[3]=(b)[3]^(c)[3]; \ - }while(0) - - -void camellia_setup128(const u8 *key, u32 *subkey); -void camellia_setup192(const u8 *key, u32 *subkey); -void camellia_setup256(const u8 *key, u32 *subkey); - -void camellia_encrypt128(const u32 *subkey, u32 *io); -void camellia_decrypt128(const u32 *subkey, u32 *io); -void camellia_encrypt256(const u32 *subkey, u32 *io); -void camellia_decrypt256(const u32 *subkey, u32 *io); - -#ifdef __cplusplus -} -#endif +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE keyTable); +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]); +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); +void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]); #endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ - diff --git a/crypto/openssl/crypto/camellia/cmll_misc.c b/crypto/openssl/crypto/camellia/cmll_misc.c index 2cd7aba9bb..f44689124b 100644 --- a/crypto/openssl/crypto/camellia/cmll_misc.c +++ b/crypto/openssl/crypto/camellia/cmll_misc.c @@ -52,78 +52,28 @@ #include #include #include "cmll_locl.h" -#include -#ifdef OPENSSL_FIPS -#include -#endif const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key) -#ifdef OPENSSL_FIPS { - if (FIPS_mode()) - FIPS_BAD_ABORT(CAMELLIA) - return private_Camellia_set_key(userKey, bits, key); - } -int private_Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key) -#endif - { - if (!userKey || !key) - { + if(!userKey || !key) return -1; - } - - switch(bits) - { - case 128: - camellia_setup128(userKey, (unsigned int *)key->rd_key); - key->enc = camellia_encrypt128; - key->dec = camellia_decrypt128; - break; - case 192: - camellia_setup192(userKey, (unsigned int *)key->rd_key); - key->enc = camellia_encrypt256; - key->dec = camellia_decrypt256; - break; - case 256: - camellia_setup256(userKey, (unsigned int *)key->rd_key); - key->enc = camellia_encrypt256; - key->dec = camellia_decrypt256; - break; - default: + if(bits != 128 && bits != 192 && bits != 256) return -2; - } - - key->bitLength = bits; + key->grand_rounds = Camellia_Ekeygen(bits , userKey, key->u.rd_key); return 0; } void Camellia_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) { - u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; - const union { long one; char little; } camellia_endian = {1}; - - memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) SWAP4WORD(tmp); - key->enc(key->rd_key, tmp); - if (camellia_endian.little) SWAP4WORD(tmp); - memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); + Camellia_EncryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out); } void Camellia_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) { - u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; - const union { long one; char little; } camellia_endian = {1}; - - memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); - if (camellia_endian.little) SWAP4WORD(tmp); - key->dec(key->rd_key, tmp); - if (camellia_endian.little) SWAP4WORD(tmp); - memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); + Camellia_DecryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out); } - diff --git a/crypto/openssl/crypto/camellia/cmll_ofb.c b/crypto/openssl/crypto/camellia/cmll_ofb.c index d89cf9f3b3..a482befc74 100644 --- a/crypto/openssl/crypto/camellia/cmll_ofb.c +++ b/crypto/openssl/crypto/camellia/cmll_ofb.c @@ -105,37 +105,15 @@ * [including the GNU Public Licence.] */ -#ifndef CAMELLIA_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include #include -#include "cmll_locl.h" +#include /* The input and output encrypted as though 128bit ofb mode is being * used. The extra state information to record how much of the * 128bit block we have used is contained in *num; */ void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num) { - - unsigned int n; - unsigned long l=length; - - assert(in && out && key && ivec && num); - - n = *num; - - while (l--) { - if (n == 0) { - Camellia_encrypt(ivec, ivec, key); - } - *(out++) = *(in++) ^ ivec[n]; - n = (n+1) % CAMELLIA_BLOCK_SIZE; - } - - *num=n; + CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)Camellia_encrypt); } diff --git a/crypto/openssl/crypto/cast/c_skey.c b/crypto/openssl/crypto/cast/c_skey.c index 68e690a60c..76e40005c9 100644 --- a/crypto/openssl/crypto/cast/c_skey.c +++ b/crypto/openssl/crypto/cast/c_skey.c @@ -57,11 +57,6 @@ */ #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - #include "cast_lcl.h" #include "cast_s.h" @@ -77,7 +72,7 @@ #define S6 CAST_S_table6 #define S7 CAST_S_table7 -FIPS_NON_FIPS_VCIPHER_Init(CAST) +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) { CAST_LONG x[16]; CAST_LONG z[16]; diff --git a/crypto/openssl/crypto/cast/cast.h b/crypto/openssl/crypto/cast/cast.h index 6e0cd31ae4..1a264f8143 100644 --- a/crypto/openssl/crypto/cast/cast.h +++ b/crypto/openssl/crypto/cast/cast.h @@ -72,7 +72,7 @@ extern "C" { #define CAST_ENCRYPT 1 #define CAST_DECRYPT 0 -#define CAST_LONG unsigned long +#define CAST_LONG unsigned int #define CAST_BLOCK 8 #define CAST_KEY_LENGTH 16 @@ -83,9 +83,7 @@ typedef struct cast_key_st int short_key; /* Use reduced rounds for short key */ } CAST_KEY; -#ifdef OPENSSL_FIPS -void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); -#endif + void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key, int enc); diff --git a/crypto/openssl/crypto/cms/cms.h b/crypto/openssl/crypto/cms/cms.h index 25f88745f2..09c45d0412 100644 --- a/crypto/openssl/crypto/cms/cms.h +++ b/crypto/openssl/crypto/cms/cms.h @@ -76,8 +76,9 @@ typedef struct CMS_Receipt_st CMS_Receipt; DECLARE_STACK_OF(CMS_SignerInfo) DECLARE_STACK_OF(GENERAL_NAMES) -DECLARE_ASN1_FUNCTIONS_const(CMS_ContentInfo) -DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) #define CMS_SIGNERINFO_ISSUER_SERIAL 0 #define CMS_SIGNERINFO_KEYIDENTIFIER 1 @@ -124,9 +125,13 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached); DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) #endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); @@ -230,6 +235,7 @@ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); int CMS_SignedData_init(CMS_ContentInfo *cms); diff --git a/crypto/openssl/crypto/cms/cms_asn1.c b/crypto/openssl/crypto/cms/cms_asn1.c index 7664921861..fcba4dcbcc 100644 --- a/crypto/openssl/crypto/cms/cms_asn1.c +++ b/crypto/openssl/crypto/cms/cms_asn1.c @@ -87,7 +87,8 @@ ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = { } ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) /* Minor tweak to operation: free up signer key, cert */ -static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_FREE_POST) { @@ -130,8 +131,8 @@ ASN1_NDEF_SEQUENCE(CMS_SignedData) = { } ASN1_NDEF_SEQUENCE_END(CMS_SignedData) ASN1_SEQUENCE(CMS_OriginatorInfo) = { - ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), - ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1) + ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0), + ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) } ASN1_SEQUENCE_END(CMS_OriginatorInfo) ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { @@ -213,7 +214,8 @@ ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { } ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) /* Free up RecipientInfo additional data */ -static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_FREE_PRE) { @@ -300,10 +302,42 @@ ASN1_ADB(CMS_ContentInfo) = { ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), } ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); -ASN1_NDEF_SEQUENCE(CMS_ContentInfo) = { +/* CMS streaming support */ +static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) + { + ASN1_STREAM_ARG *sarg = exarg; + CMS_ContentInfo *cms = NULL; + if (pval) + cms = (CMS_ContentInfo *)*pval; + else + return 1; + switch(operation) + { + + case ASN1_OP_STREAM_PRE: + if (CMS_stream(&sarg->boundary, cms) <= 0) + return 0; + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = CMS_dataInit(cms, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0) + return 0; + break; + + } + return 1; + } + +ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = { ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), ASN1_ADB_OBJECT(CMS_ContentInfo) -} ASN1_NDEF_SEQUENCE_END(CMS_ContentInfo) +} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo) /* Specials for signed attributes */ diff --git a/crypto/openssl/crypto/cms/cms_env.c b/crypto/openssl/crypto/cms/cms_env.c index d499ae85b4..b3237d4b94 100644 --- a/crypto/openssl/crypto/cms/cms_env.c +++ b/crypto/openssl/crypto/cms/cms_env.c @@ -60,6 +60,7 @@ #include #include #include "cms_lcl.h" +#include "asn1_locl.h" /* CMS EnvelopedData Utilities */ @@ -151,7 +152,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, CMS_KeyTransRecipientInfo *ktri; CMS_EnvelopedData *env; EVP_PKEY *pk = NULL; - int type; + int i, type; env = cms_get0_enveloped(cms); if (!env) goto err; @@ -200,21 +201,22 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) goto err; - /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, - * hard code algorithm parameters. - */ - - if (pk->type == EVP_PKEY_RSA) - { - X509_ALGOR_set0(ktri->keyEncryptionAlgorithm, - OBJ_nid2obj(NID_rsaEncryption), - V_ASN1_NULL, 0); - } - else + if (pk->ameth && pk->ameth->pkey_ctrl) { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, + 0, ri); + if (i == -2) + { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; + goto err; + } + if (i <= 0) + { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + CMS_R_CTRL_FAILURE); + goto err; + } } if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) @@ -301,8 +303,9 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, { CMS_KeyTransRecipientInfo *ktri; CMS_EncryptedContentInfo *ec; + EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; - int eklen; + size_t eklen; int ret = 0; @@ -315,7 +318,22 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, ktri = ri->d.ktri; ec = cms->d.envelopedData->encryptedContentInfo; - eklen = EVP_PKEY_size(ktri->pkey); + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) + { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) + goto err; ek = OPENSSL_malloc(eklen); @@ -326,9 +344,7 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, goto err; } - eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey); - - if (eklen <= 0) + if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) goto err; ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); @@ -337,6 +353,8 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, ret = 1; err: + if (pctx) + EVP_PKEY_CTX_free(pctx); if (ek) OPENSSL_free(ek); return ret; @@ -349,8 +367,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; - int eklen; + size_t eklen; int ret = 0; if (ktri->pkey == NULL) @@ -360,7 +379,24 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, return 0; } - eklen = EVP_PKEY_size(ktri->pkey); + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) + { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, NULL, &eklen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) + goto err; ek = OPENSSL_malloc(eklen); @@ -371,10 +407,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, goto err; } - eklen = EVP_PKEY_decrypt(ek, + if (EVP_PKEY_decrypt(pctx, ek, &eklen, ktri->encryptedKey->data, - ktri->encryptedKey->length, ktri->pkey); - if (eklen <= 0) + ktri->encryptedKey->length) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); goto err; @@ -386,6 +421,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, cms->d.envelopedData->encryptedContentInfo->keylen = eklen; err: + if (pctx) + EVP_PKEY_CTX_free(pctx); if (!ret && ek) OPENSSL_free(ek); diff --git a/crypto/openssl/crypto/cms/cms_err.c b/crypto/openssl/crypto/cms/cms_err.c index 52fa53954f..ff7b0309e5 100644 --- a/crypto/openssl/crypto/cms/cms_err.c +++ b/crypto/openssl/crypto/cms/cms_err.c @@ -1,6 +1,6 @@ /* crypto/cms/cms_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -133,7 +133,7 @@ static ERR_STRING_DATA CMS_str_functs[]= {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"}, {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"}, {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, -{ERR_FUNC(CMS_F_CMS_STREAM), "CMS_STREAM"}, +{ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"}, {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, {0,NULL} diff --git a/crypto/openssl/crypto/cms/cms_ess.c b/crypto/openssl/crypto/cms/cms_ess.c index 65613aab65..90c0b82fb5 100644 --- a/crypto/openssl/crypto/cms/cms_ess.c +++ b/crypto/openssl/crypto/cms/cms_ess.c @@ -63,7 +63,7 @@ DECLARE_ASN1_ITEM(CMS_ReceiptRequest) DECLARE_ASN1_ITEM(CMS_Receipt) -IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) +IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) /* ESS services: for now just Signed Receipt related */ diff --git a/crypto/openssl/crypto/cms/cms_io.c b/crypto/openssl/crypto/cms/cms_io.c index 30f5ddfe6d..1cb0264cc5 100644 --- a/crypto/openssl/crypto/cms/cms_io.c +++ b/crypto/openssl/crypto/cms/cms_io.c @@ -58,6 +58,25 @@ #include "cms.h" #include "cms_lcl.h" +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) + { + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return 0; + if (!*pos) + *pos = ASN1_OCTET_STRING_new(); + if (*pos) + { + (*pos)->flags |= ASN1_STRING_FLAG_NDEF; + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + *boundary = &(*pos)->data; + return 1; + } + CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE); + return 0; + } + CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) { return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); @@ -70,52 +89,26 @@ int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) -/* Callback for int_smime_write_ASN1 */ - -static int cms_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, - const ASN1_ITEM *it) +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) { - CMS_ContentInfo *cms = (CMS_ContentInfo *)val; - BIO *tmpbio, *cmsbio; - int r = 0; - - if (!(flags & SMIME_DETACHED)) - { - SMIME_crlf_copy(data, out, flags); - return 1; - } - - /* Let CMS code prepend any needed BIOs */ - - cmsbio = CMS_dataInit(cms, out); - - if (!cmsbio) - return 0; - - /* Copy data across, passing through filter BIOs for processing */ - SMIME_crlf_copy(data, cmsbio, flags); - - /* Finalize structure */ - if (CMS_dataFinal(cms, cmsbio) <= 0) - goto err; - - r = 1; - - err: - - /* Now remove any digests prepended to the BIO */ - - while (cmsbio != out) - { - tmpbio = BIO_pop(cmsbio); - BIO_free(cmsbio); - cmsbio = tmpbio; - } + return BIO_new_NDEF(out, (ASN1_VALUE *)cms, + ASN1_ITEM_rptr(CMS_ContentInfo)); + } - return 1; +/* CMS wrappers round generalised stream and MIME routines */ +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) + { + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags, + ASN1_ITEM_rptr(CMS_ContentInfo)); } +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) + { + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags, + "CMS", + ASN1_ITEM_rptr(CMS_ContentInfo)); + } int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) { @@ -127,9 +120,8 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) else mdalgs = NULL; - return int_smime_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, + return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, ctype_nid, econt_nid, mdalgs, - cms_output_data, ASN1_ITEM_rptr(CMS_ContentInfo)); } @@ -138,3 +130,4 @@ CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(CMS_ContentInfo)); } + diff --git a/crypto/openssl/crypto/cms/cms_lcl.h b/crypto/openssl/crypto/cms/cms_lcl.h index 7d60fac67e..c8ecfa724a 100644 --- a/crypto/openssl/crypto/cms/cms_lcl.h +++ b/crypto/openssl/crypto/cms/cms_lcl.h @@ -406,6 +406,7 @@ struct CMS_Receipt_st ASN1_OCTET_STRING *originatorSignatureValue; }; +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) DECLARE_ASN1_ITEM(CMS_SignerInfo) DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) DECLARE_ASN1_ITEM(CMS_Attributes_Sign) diff --git a/crypto/openssl/crypto/cms/cms_lib.c b/crypto/openssl/crypto/cms/cms_lib.c index cc00526d3e..d00fe0f87b 100644 --- a/crypto/openssl/crypto/cms/cms_lib.c +++ b/crypto/openssl/crypto/cms/cms_lib.c @@ -60,7 +60,8 @@ #include "cms.h" #include "cms_lcl.h" -IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo) +IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) +IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) DECLARE_ASN1_ITEM(CMS_CertificateChoices) DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) @@ -346,20 +347,10 @@ void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) { int param_type; - switch (EVP_MD_type(md)) - { - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: + if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) param_type = V_ASN1_UNDEF; - break; - - default: + else param_type = V_ASN1_NULL; - break; - } X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); @@ -561,6 +552,15 @@ int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) return 1; } +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) + { + int r; + r = CMS_add0_crl(cms, crl); + if (r > 0) + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); + return r; + } + STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) { STACK_OF(X509) *certs = NULL; diff --git a/crypto/openssl/crypto/cms/cms_sd.c b/crypto/openssl/crypto/cms/cms_sd.c index cdac3b870d..e3192b9c57 100644 --- a/crypto/openssl/crypto/cms/cms_sd.c +++ b/crypto/openssl/crypto/cms/cms_sd.c @@ -58,6 +58,7 @@ #include #include #include "cms_lcl.h" +#include "asn1_locl.h" /* CMS SignedData Utilities */ @@ -218,10 +219,9 @@ int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, X509_get_issuer_name(cert))) goto merr; - ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber); - sid->d.issuerAndSerialNumber->serialNumber = - ASN1_STRING_dup(X509_get_serialNumber(cert)); - if(!sid->d.issuerAndSerialNumber->serialNumber) + if (!ASN1_STRING_copy( + sid->d.issuerAndSerialNumber->serialNumber, + X509_get_serialNumber(cert))) goto merr; break; @@ -341,16 +341,22 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; - /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */ if (md == NULL) - md = EVP_sha1(); - - /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ + { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) + goto err; + md = EVP_get_digestbynid(def_nid); + if (md == NULL) + { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); + goto err; + } + } - if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) + if (!md) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); goto err; } @@ -379,37 +385,21 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, } } - /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, - * hard code algorithm parameters. - */ - - switch (pk->type) + if (pk->ameth && pk->ameth->pkey_ctrl) { - - case EVP_PKEY_RSA: - X509_ALGOR_set0(si->signatureAlgorithm, - OBJ_nid2obj(NID_rsaEncryption), - V_ASN1_NULL, 0); - break; - - case EVP_PKEY_DSA: - X509_ALGOR_set0(si->signatureAlgorithm, - OBJ_nid2obj(NID_dsaWithSHA1), - V_ASN1_UNDEF, 0); - break; - - - case EVP_PKEY_EC: - X509_ALGOR_set0(si->signatureAlgorithm, - OBJ_nid2obj(NID_ecdsa_with_SHA1), - V_ASN1_UNDEF, 0); - break; - - default: - CMSerr(CMS_F_CMS_ADD1_SIGNER, + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, + 0, si); + if (i == -2) + { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - + goto err; + } + if (i <= 0) + { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE); + goto err; + } } if (!(flags & CMS_NOATTR)) @@ -626,25 +616,6 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, *psig = si->signatureAlgorithm; } -/* In OpenSSL 0.9.8 we have the link between digest types and public - * key types so we need to fixup the digest type if the public key - * type is not appropriate. - */ - -static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey) - { - if (EVP_MD_CTX_type(mctx) != NID_sha1) - return; -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - mctx->digest = EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) - mctx->digest = EVP_ecdsa(); -#endif - } - static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, CMS_SignerInfo *si, BIO *chain) { @@ -693,7 +664,6 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, ERR_R_MALLOC_FAILURE); goto err; } - cms_fixup_mctx(&mctx, si->pkey); if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) { CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, @@ -731,9 +701,10 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) int CMS_SignerInfo_sign(CMS_SignerInfo *si) { EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; unsigned char *abuf = NULL; int alen; - unsigned int siglen; + size_t siglen; const EVP_MD *md = NULL; md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); @@ -748,40 +719,38 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) goto err; } - if (EVP_SignInit_ex(&mctx, md, NULL) <= 0) + if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) goto err; -#if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); goto err; } -#endif alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, ASN1_ITEM_rptr(CMS_Attributes_Sign)); if(!abuf) goto err; - if (EVP_SignUpdate(&mctx, abuf, alen) <= 0) + if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) + goto err; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) goto err; - siglen = EVP_PKEY_size(si->pkey); OPENSSL_free(abuf); abuf = OPENSSL_malloc(siglen); if(!abuf) goto err; - cms_fixup_mctx(&mctx, si->pkey); - if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0) + if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) goto err; -#if 0 + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); goto err; } -#endif + EVP_MD_CTX_cleanup(&mctx); ASN1_STRING_set0(si->signature, abuf, siglen); @@ -799,6 +768,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) int CMS_SignerInfo_verify(CMS_SignerInfo *si) { EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; unsigned char *abuf = NULL; int alen, r = -1; const EVP_MD *md = NULL; @@ -813,23 +783,22 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) if (md == NULL) return -1; EVP_MD_CTX_init(&mctx); - if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0) + if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) goto err; alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, ASN1_ITEM_rptr(CMS_Attributes_Verify)); if(!abuf) goto err; - r = EVP_VerifyUpdate(&mctx, abuf, alen); + r = EVP_DigestVerifyUpdate(&mctx, abuf, alen); OPENSSL_free(abuf); if (r <= 0) { r = -1; goto err; } - cms_fixup_mctx(&mctx, si->pkey); - r = EVP_VerifyFinal(&mctx, - si->signature->data, si->signature->length, si->pkey); + r = EVP_DigestVerifyFinal(&mctx, + si->signature->data, si->signature->length); if (r <= 0) CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); err: @@ -922,7 +891,6 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) } else { - cms_fixup_mctx(&mctx, si->pkey); r = EVP_VerifyFinal(&mctx, si->signature->data, si->signature->length, si->pkey); if (r <= 0) @@ -991,17 +959,19 @@ static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) return CMS_add_simple_smimecap(sk, nid, arg); return 1; } -#if 0 + static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) { if (EVP_get_digestbynid(nid)) return CMS_add_simple_smimecap(sk, nid, arg); return 1; } -#endif + int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) { if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) + || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) + || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) diff --git a/crypto/openssl/crypto/cms/cms_smime.c b/crypto/openssl/crypto/cms/cms_smime.c index f35883aa22..4a799eb897 100644 --- a/crypto/openssl/crypto/cms/cms_smime.c +++ b/crypto/openssl/crypto/cms/cms_smime.c @@ -171,7 +171,7 @@ CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) if (!cms) return NULL; - if (CMS_final(cms, in, NULL, flags)) + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) return cms; CMS_ContentInfo_free(cms); @@ -214,10 +214,7 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, return NULL; if(!(flags & CMS_DETACHED)) - { - flags &= ~CMS_STREAM; CMS_set_detached(cms, 0); - } if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) return cms; @@ -269,10 +266,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, return NULL; if(!(flags & CMS_DETACHED)) - { - flags &= ~CMS_STREAM; CMS_set_detached(cms, 0); - } if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, in, NULL, flags)) @@ -456,6 +450,7 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, X509_STORE *store, unsigned int flags) { int r; + flags &= ~(CMS_DETACHED|CMS_TEXT); r = CMS_verify(rcms, certs, store, NULL, NULL, flags); if (r <= 0) return r; @@ -486,10 +481,7 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, } if(!(flags & CMS_DETACHED)) - { - flags &= ~CMS_STREAM; CMS_set_detached(cms, 0); - } if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, data, NULL, flags)) @@ -517,7 +509,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, BIO *rct_cont = NULL; int r = 0; - flags &= ~CMS_STREAM; + flags &= ~(CMS_STREAM|CMS_TEXT); /* Not really detached but avoids content being allocated */ flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED; if (!pkey || !signcert) @@ -598,10 +590,7 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, } if(!(flags & CMS_DETACHED)) - { - flags &= ~CMS_STREAM; CMS_set_detached(cms, 0); - } if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, data, NULL, flags)) @@ -781,12 +770,9 @@ CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) return NULL; if(!(flags & CMS_DETACHED)) - { - flags &= ~CMS_STREAM; CMS_set_detached(cms, 0); - } - if (CMS_final(cms, in, NULL, flags)) + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) return cms; CMS_ContentInfo_free(cms); diff --git a/crypto/openssl/crypto/comp/c_zlib.c b/crypto/openssl/crypto/comp/c_zlib.c index 8df7792c50..8adf35f3fc 100644 --- a/crypto/openssl/crypto/comp/c_zlib.c +++ b/crypto/openssl/crypto/comp/c_zlib.c @@ -781,6 +781,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) default: ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; + } return ret; diff --git a/crypto/openssl/crypto/comp/comp_err.c b/crypto/openssl/crypto/comp/comp_err.c index 187d68b725..661c94c3a4 100644 --- a/crypto/openssl/crypto/comp/comp_err.c +++ b/crypto/openssl/crypto/comp/comp_err.c @@ -1,6 +1,6 @@ /* crypto/comp/comp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 diff --git a/crypto/openssl/crypto/conf/README b/crypto/openssl/crypto/conf/README index ca58d0240f..96e53b34ed 100644 --- a/crypto/openssl/crypto/conf/README +++ b/crypto/openssl/crypto/conf/README @@ -1,8 +1,3 @@ -WARNING WARNING WARNING!!! - -This stuff is experimental, may change radically or be deleted altogether -before OpenSSL 0.9.7 release. You have been warned! - Configuration modules. These are a set of modules which can perform various configuration functions. @@ -13,7 +8,7 @@ The routines read a configuration file set up like this: ----- #default section -openssl_init=init_section +openssl_conf=init_section [init_section] @@ -30,29 +25,27 @@ path=/some/path/to/some/dso.so other_stuff=other_value ---- -When this file is loaded a configuration module with the specified -string (module* in the above example) is looked up and its init -function called as: +When this file is loaded a configuration module with the specified string +(module* in the above example) is looked up and its init function called as: int conf_init_func(CONF_IMODULE *md, CONF *cnf); -The function can then take whatever action is appropriate, for example -further lookups based on the value. Multiple instances of the same -config module can be loaded. +The function can then take whatever action is appropriate, for example further +lookups based on the value. Multiple instances of the same config module can be +loaded. -When the application closes down the modules are cleaned up by calling -an optional finish function: +When the application closes down the modules are cleaned up by calling an +optional finish function: void conf_finish_func(CONF_IMODULE *md); The finish functions are called in reverse order: that is the last module loaded is the first one cleaned up. -If no module exists with a given name then an attempt is made to load -a DSO with the supplied name. This might mean that "module3" attempts -to load a DSO called libmodule3.so or module3.dll for example. An explicit -DSO name can be given by including a separate section as in the module4 example -above. +If no module exists with a given name then an attempt is made to load a DSO +with the supplied name. This might mean that "module3" attempts to load a DSO +called libmodule3.so or module3.dll for example. An explicit DSO name can be +given by including a separate section as in the module4 example above. The DSO is expected to at least contain an initialization function: @@ -64,15 +57,17 @@ void OPENSSL_finish(CONF_IMODULE *md); Static modules can also be added using, -int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func *ffunc); +int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func +*ffunc); -where "name" is the name in the configuration file this function corresponds to. +where "name" is the name in the configuration file this function corresponds +to. -A set of builtin modules (currently only an ASN1 non functional test module) can be -added by calling OPENSSL_load_builtin_modules(). +A set of builtin modules (currently only an ASN1 non functional test module) +can be added by calling OPENSSL_load_builtin_modules(). -The function OPENSSL_config() is intended as a simple configuration function that -any application can call to perform various default configuration tasks. It uses the -file openssl.cnf in the usual locations. +The function OPENSSL_config() is intended as a simple configuration function +that any application can call to perform various default configuration tasks. +It uses the file openssl.cnf in the usual locations. diff --git a/crypto/openssl/crypto/conf/conf.h b/crypto/openssl/crypto/conf/conf.h index 8aa06bc5ec..c2199978a3 100644 --- a/crypto/openssl/crypto/conf/conf.h +++ b/crypto/openssl/crypto/conf/conf.h @@ -79,8 +79,7 @@ typedef struct } CONF_VALUE; DECLARE_STACK_OF(CONF_VALUE) -DECLARE_STACK_OF(CONF_MODULE) -DECLARE_STACK_OF(CONF_IMODULE) +DECLARE_LHASH_OF(CONF_VALUE); struct conf_st; struct conf_method_st; @@ -105,6 +104,9 @@ struct conf_method_st typedef struct conf_imodule_st CONF_IMODULE; typedef struct conf_module_st CONF_MODULE; +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + /* DSO module function typedefs */ typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf); typedef void conf_finish_func(CONF_IMODULE *md); @@ -117,18 +119,23 @@ typedef void conf_finish_func(CONF_IMODULE *md); #define CONF_MFLAGS_DEFAULT_SECTION 0x20 int CONF_set_default_method(CONF_METHOD *meth); -void CONF_set_nconf(CONF *conf,LHASH *hash); -LHASH *CONF_load(LHASH *conf,const char *file,long *eline); +void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file, + long *eline); #ifndef OPENSSL_NO_FP_API -LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline); +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); #endif -LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline); -STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section); -char *CONF_get_string(LHASH *conf,const char *group,const char *name); -long CONF_get_number(LHASH *conf,const char *group,const char *name); -void CONF_free(LHASH *conf); -int CONF_dump_fp(LHASH *conf, FILE *out); -int CONF_dump_bio(LHASH *conf, BIO *out); +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); void OPENSSL_config(const char *config_name); void OPENSSL_no_config(void); @@ -140,7 +147,7 @@ struct conf_st { CONF_METHOD *meth; void *meth_data; - LHASH *data; + LHASH_OF(CONF_VALUE) *data; }; CONF *NCONF_new(CONF_METHOD *meth); @@ -214,6 +221,7 @@ void ERR_load_CONF_strings(void); #define CONF_F_CONF_LOAD_BIO 102 #define CONF_F_CONF_LOAD_FP 103 #define CONF_F_CONF_MODULES_LOAD 116 +#define CONF_F_CONF_PARSE_LIST 119 #define CONF_F_DEF_LOAD 120 #define CONF_F_DEF_LOAD_BIO 121 #define CONF_F_MODULE_INIT 115 @@ -233,6 +241,7 @@ void ERR_load_CONF_strings(void); /* Reason codes. */ #define CONF_R_ERROR_LOADING_DSO 110 +#define CONF_R_LIST_CANNOT_BE_NULL 115 #define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 #define CONF_R_MISSING_EQUAL_SIGN 101 #define CONF_R_MISSING_FINISH_FUNCTION 111 diff --git a/crypto/openssl/crypto/conf/conf_api.c b/crypto/openssl/crypto/conf/conf_api.c index 909d72b4b8..22617e5fa1 100644 --- a/crypto/openssl/crypto/conf/conf_api.c +++ b/crypto/openssl/crypto/conf/conf_api.c @@ -69,16 +69,12 @@ #include #include "e_os.h" -static void value_free_hash(CONF_VALUE *a, LHASH *conf); -static void value_free_stack(CONF_VALUE *a,LHASH *conf); -static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE *, LHASH *) -static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_stack, CONF_VALUE *, LHASH *) -/* We don't use function pointer casting or wrapper functions - but cast each - * callback parameter inside the callback functions. */ -/* static unsigned long hash(CONF_VALUE *v); */ -static unsigned long hash(const void *v_void); -/* static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); */ -static int cmp_conf(const void *a_void,const void *b_void); +static void value_free_hash_doall_arg(CONF_VALUE *a, + LHASH_OF(CONF_VALUE) *conf); +static void value_free_stack_doall(CONF_VALUE *a); +static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, + LHASH_OF(CONF_VALUE)) +static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) /* Up until OpenSSL 0.9.5a, this was get_section */ CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) @@ -88,7 +84,7 @@ CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) if ((conf == NULL) || (section == NULL)) return(NULL); vv.name=NULL; vv.section=(char *)section; - v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); + v=lh_CONF_VALUE_retrieve(conf->data,&vv); return(v); } @@ -118,7 +114,7 @@ int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) return 0; } - v = (CONF_VALUE *)lh_insert(conf->data, value); + v = lh_CONF_VALUE_insert(conf->data, value); if (v != NULL) { (void)sk_CONF_VALUE_delete_ptr(ts,v); @@ -141,24 +137,24 @@ char *_CONF_get_string(const CONF *conf, const char *section, const char *name) { vv.name=(char *)name; vv.section=(char *)section; - v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); + v=lh_CONF_VALUE_retrieve(conf->data,&vv); if (v != NULL) return(v->value); if (strcmp(section,"ENV") == 0) { - p=Getenv(name); + p=getenv(name); if (p != NULL) return(p); } } vv.section="default"; vv.name=(char *)name; - v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); + v=lh_CONF_VALUE_retrieve(conf->data,&vv); if (v != NULL) return(v->value); else return(NULL); } else - return(Getenv(name)); + return(getenv(name)); } #if 0 /* There's no way to provide error checking with this function, so @@ -182,6 +178,34 @@ long _CONF_get_number(CONF *conf, char *section, char *name) } #endif +static unsigned long conf_value_hash(const CONF_VALUE *v) + { + return (lh_strhash(v->section)<<2)^lh_strhash(v->name); + } +static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) + +static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) + { + int i; + + if (a->section != b->section) + { + i=strcmp(a->section,b->section); + if (i) return(i); + } + + if ((a->name != NULL) && (b->name != NULL)) + { + i=strcmp(a->name,b->name); + return(i); + } + else if (a->name == b->name) + return(0); + else + return((a->name == NULL)?-1:1); + } +static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) + int _CONF_new_data(CONF *conf) { if (conf == NULL) @@ -189,7 +213,7 @@ int _CONF_new_data(CONF *conf) return 0; } if (conf->data == NULL) - if ((conf->data = lh_new(hash, cmp_conf)) == NULL) + if ((conf->data = lh_CONF_VALUE_new()) == NULL) { return 0; } @@ -200,105 +224,73 @@ void _CONF_free_data(CONF *conf) { if (conf == NULL || conf->data == NULL) return; - conf->data->down_load=0; /* evil thing to make sure the 'OPENSSL_free()' - * works as expected */ - lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_hash), - conf->data); + lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make + * sure the 'OPENSSL_free()' works as + * expected */ + lh_CONF_VALUE_doall_arg(conf->data, + LHASH_DOALL_ARG_FN(value_free_hash), + LHASH_OF(CONF_VALUE), conf->data); /* We now have only 'section' entries in the hash table. * Due to problems with */ - lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_stack), - conf->data); - lh_free(conf->data); + lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); + lh_CONF_VALUE_free(conf->data); } -static void value_free_hash(CONF_VALUE *a, LHASH *conf) +static void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) { if (a->name != NULL) - { - a=(CONF_VALUE *)lh_delete(conf,a); - } + (void)lh_CONF_VALUE_delete(conf,a); } -static void value_free_stack(CONF_VALUE *a, LHASH *conf) +static void value_free_stack_doall(CONF_VALUE *a) { CONF_VALUE *vv; - STACK *sk; + STACK_OF(CONF_VALUE) *sk; int i; if (a->name != NULL) return; - sk=(STACK *)a->value; - for (i=sk_num(sk)-1; i>=0; i--) + sk=(STACK_OF(CONF_VALUE) *)a->value; + for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--) { - vv=(CONF_VALUE *)sk_value(sk,i); + vv=sk_CONF_VALUE_value(sk,i); OPENSSL_free(vv->value); OPENSSL_free(vv->name); OPENSSL_free(vv); } - if (sk != NULL) sk_free(sk); + if (sk != NULL) sk_CONF_VALUE_free(sk); OPENSSL_free(a->section); OPENSSL_free(a); } -/* static unsigned long hash(CONF_VALUE *v) */ -static unsigned long hash(const void *v_void) - { - CONF_VALUE *v = (CONF_VALUE *)v_void; - return((lh_strhash(v->section)<<2)^lh_strhash(v->name)); - } - -/* static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) */ -static int cmp_conf(const void *a_void,const void *b_void) - { - int i; - CONF_VALUE *a = (CONF_VALUE *)a_void; - CONF_VALUE *b = (CONF_VALUE *)b_void; - - if (a->section != b->section) - { - i=strcmp(a->section,b->section); - if (i) return(i); - } - - if ((a->name != NULL) && (b->name != NULL)) - { - i=strcmp(a->name,b->name); - return(i); - } - else if (a->name == b->name) - return(0); - else - return((a->name == NULL)?-1:1); - } - /* Up until OpenSSL 0.9.5a, this was new_section */ CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) { - STACK *sk=NULL; + STACK_OF(CONF_VALUE) *sk=NULL; int ok=0,i; CONF_VALUE *v=NULL,*vv; - if ((sk=sk_new_null()) == NULL) + if ((sk=sk_CONF_VALUE_new_null()) == NULL) goto err; - if ((v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) + if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) goto err; i=strlen(section)+1; - if ((v->section=(char *)OPENSSL_malloc(i)) == NULL) + if ((v->section=OPENSSL_malloc(i)) == NULL) goto err; memcpy(v->section,section,i); v->name=NULL; v->value=(char *)sk; - vv=(CONF_VALUE *)lh_insert(conf->data,v); + vv=lh_CONF_VALUE_insert(conf->data,v); assert(vv == NULL); ok=1; err: if (!ok) { - if (sk != NULL) sk_free(sk); + if (sk != NULL) sk_CONF_VALUE_free(sk); if (v != NULL) OPENSSL_free(v); v=NULL; } diff --git a/crypto/openssl/crypto/conf/conf_def.c b/crypto/openssl/crypto/conf/conf_def.c index d8bce8732a..0b571b0394 100644 --- a/crypto/openssl/crypto/conf/conf_def.c +++ b/crypto/openssl/crypto/conf/conf_def.c @@ -129,7 +129,7 @@ static CONF *def_create(CONF_METHOD *meth) { CONF *ret; - ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); + ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); if (ret) if (meth->init(ret) == 0) { @@ -145,7 +145,7 @@ static int def_init_default(CONF *conf) return 0; conf->meth = &default_method; - conf->meth_data = (void *)CONF_type_default; + conf->meth_data = CONF_type_default; conf->data = NULL; return 1; @@ -722,7 +722,7 @@ static char *scan_dquote(CONF *conf, char *p) return(p); } -static void dump_value(CONF_VALUE *a, BIO *out) +static void dump_value_doall_arg(CONF_VALUE *a, BIO *out) { if (a->name) BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); @@ -730,11 +730,12 @@ static void dump_value(CONF_VALUE *a, BIO *out) BIO_printf(out, "[[%s]]\n", a->section); } -static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE *, BIO *) +static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) static int def_dump(const CONF *conf, BIO *out) { - lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), out); + lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), + BIO, out); return 1; } diff --git a/crypto/openssl/crypto/conf/conf_err.c b/crypto/openssl/crypto/conf/conf_err.c index a16a5e0bd4..25bb5dc9aa 100644 --- a/crypto/openssl/crypto/conf/conf_err.c +++ b/crypto/openssl/crypto/conf/conf_err.c @@ -1,6 +1,6 @@ /* crypto/conf/conf_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -75,6 +75,7 @@ static ERR_STRING_DATA CONF_str_functs[]= {ERR_FUNC(CONF_F_CONF_LOAD_BIO), "CONF_load_bio"}, {ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"}, {ERR_FUNC(CONF_F_CONF_MODULES_LOAD), "CONF_modules_load"}, +{ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"}, {ERR_FUNC(CONF_F_DEF_LOAD), "DEF_LOAD"}, {ERR_FUNC(CONF_F_DEF_LOAD_BIO), "DEF_LOAD_BIO"}, {ERR_FUNC(CONF_F_MODULE_INIT), "MODULE_INIT"}, @@ -97,6 +98,7 @@ static ERR_STRING_DATA CONF_str_functs[]= static ERR_STRING_DATA CONF_str_reasons[]= { {ERR_REASON(CONF_R_ERROR_LOADING_DSO) ,"error loading dso"}, +{ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL) ,"list cannot be null"}, {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),"missing close square bracket"}, {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN) ,"missing equal sign"}, {ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION),"missing finish function"}, diff --git a/crypto/openssl/crypto/conf/conf_lib.c b/crypto/openssl/crypto/conf/conf_lib.c index 2a3399d269..54046defca 100644 --- a/crypto/openssl/crypto/conf/conf_lib.c +++ b/crypto/openssl/crypto/conf/conf_lib.c @@ -69,7 +69,7 @@ static CONF_METHOD *default_CONF_method=NULL; /* Init a 'CONF' structure from an old LHASH */ -void CONF_set_nconf(CONF *conf, LHASH *hash) +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) { if (default_CONF_method == NULL) default_CONF_method = NCONF_default(); @@ -87,9 +87,10 @@ int CONF_set_default_method(CONF_METHOD *meth) return 1; } -LHASH *CONF_load(LHASH *conf, const char *file, long *eline) +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline) { - LHASH *ltmp; + LHASH_OF(CONF_VALUE) *ltmp; BIO *in=NULL; #ifdef OPENSSL_SYS_VMS @@ -110,10 +111,11 @@ LHASH *CONF_load(LHASH *conf, const char *file, long *eline) } #ifndef OPENSSL_NO_FP_API -LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline) +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline) { BIO *btmp; - LHASH *ltmp; + LHASH_OF(CONF_VALUE) *ltmp; if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); return NULL; @@ -124,7 +126,8 @@ LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline) } #endif -LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline) +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline) { CONF ctmp; int ret; @@ -137,7 +140,8 @@ LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline) return NULL; } -STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section) +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section) { if (conf == NULL) { @@ -151,7 +155,8 @@ STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section) } } -char *CONF_get_string(LHASH *conf,const char *group,const char *name) +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group, + const char *name) { if (conf == NULL) { @@ -165,7 +170,8 @@ char *CONF_get_string(LHASH *conf,const char *group,const char *name) } } -long CONF_get_number(LHASH *conf,const char *group,const char *name) +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group, + const char *name) { int status; long result = 0; @@ -189,7 +195,7 @@ long CONF_get_number(LHASH *conf,const char *group,const char *name) return result; } -void CONF_free(LHASH *conf) +void CONF_free(LHASH_OF(CONF_VALUE) *conf) { CONF ctmp; CONF_set_nconf(&ctmp, conf); @@ -197,7 +203,7 @@ void CONF_free(LHASH *conf) } #ifndef OPENSSL_NO_FP_API -int CONF_dump_fp(LHASH *conf, FILE *out) +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) { BIO *btmp; int ret; @@ -212,7 +218,7 @@ int CONF_dump_fp(LHASH *conf, FILE *out) } #endif -int CONF_dump_bio(LHASH *conf, BIO *out) +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) { CONF ctmp; CONF_set_nconf(&ctmp, conf); diff --git a/crypto/openssl/crypto/conf/conf_mall.c b/crypto/openssl/crypto/conf/conf_mall.c index 1cc1fd5534..c6f4cb2d55 100644 --- a/crypto/openssl/crypto/conf/conf_mall.c +++ b/crypto/openssl/crypto/conf/conf_mall.c @@ -63,7 +63,6 @@ #include #include #include -#include #ifndef OPENSSL_NO_ENGINE #include #endif @@ -77,6 +76,5 @@ void OPENSSL_load_builtin_modules(void) #ifndef OPENSSL_NO_ENGINE ENGINE_add_conf_module(); #endif - EVP_add_alg_module(); } diff --git a/crypto/openssl/crypto/conf/conf_mod.c b/crypto/openssl/crypto/conf/conf_mod.c index ee9c677d9b..df1642a0a5 100644 --- a/crypto/openssl/crypto/conf/conf_mod.c +++ b/crypto/openssl/crypto/conf/conf_mod.c @@ -582,8 +582,14 @@ int CONF_parse_list(const char *list_, int sep, int nospc, { int ret; const char *lstart, *tmpend, *p; - lstart = list_; + if(list_ == NULL) + { + CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list_; for(;;) { if (nospc) diff --git a/crypto/openssl/crypto/cpt_err.c b/crypto/openssl/crypto/cpt_err.c index 9fd41fff8c..139b9284e4 100644 --- a/crypto/openssl/crypto/cpt_err.c +++ b/crypto/openssl/crypto/cpt_err.c @@ -1,6 +1,6 @@ /* crypto/cpt_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/cryptlib.c b/crypto/openssl/crypto/cryptlib.c index 497d00363e..b4449b86d6 100644 --- a/crypto/openssl/crypto/cryptlib.c +++ b/crypto/openssl/crypto/cryptlib.c @@ -1,6 +1,6 @@ /* crypto/cryptlib.c */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -121,17 +121,279 @@ static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ #endif +DECLARE_STACK_OF(CRYPTO_dynlock) + +/* real #defines in crypto.h, keep these upto date */ +static const char* const lock_names[CRYPTO_NUM_LOCKS] = + { + "<>", + "err", + "ex_data", + "x509", + "x509_info", + "x509_pkey", + "x509_crl", + "x509_req", + "dsa", + "rsa", + "evp_pkey", + "x509_store", + "ssl_ctx", + "ssl_cert", + "ssl_session", + "ssl_sess_cert", + "ssl", + "ssl_method", + "rand", + "rand2", + "debug_malloc", + "BIO", + "gethostbyname", + "getservbyname", + "readdir", + "RSA_blinding", + "dh", + "debug_malloc2", + "dso", + "dynlock", + "engine", + "ui", + "ecdsa", + "ec", + "ecdh", + "bn", + "ec_pre_comp", + "store", + "comp", + "fips", + "fips2", +#if CRYPTO_NUM_LOCKS != 41 +# error "Inconsistency between crypto.h and cryptlib.c" +#endif + }; + +/* This is for applications to allocate new type names in the non-dynamic + array of lock names. These are numbered with positive numbers. */ +static STACK_OF(OPENSSL_STRING) *app_locks=NULL; + +/* For applications that want a more dynamic way of handling threads, the + following stack is used. These are externally numbered with negative + numbers. */ +static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; + + static void (MS_FAR *locking_callback)(int mode,int type, - const char *file,int line)=NULL; + const char *file,int line)=0; static int (MS_FAR *add_lock_callback)(int *pointer,int amount, - int type,const char *file,int line)=NULL; -static unsigned long (MS_FAR *id_callback)(void)=NULL; + int type,const char *file,int line)=0; +#ifndef OPENSSL_NO_DEPRECATED +static unsigned long (MS_FAR *id_callback)(void)=0; +#endif +static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0; +static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) + (const char *file,int line)=0; +static void (MS_FAR *dynlock_lock_callback)(int mode, + struct CRYPTO_dynlock_value *l, const char *file,int line)=0; +static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, + const char *file,int line)=0; + +int CRYPTO_get_new_lockid(char *name) + { + char *str; + int i; + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) + /* A hack to make Visual C++ 5.0 work correctly when linking as + * a DLL using /MT. Without this, the application cannot use + * any floating point printf's. + * It also seems to be needed for Visual C 1.5 (win16) */ + SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; +#endif + + if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) == NULL)) + { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); + return(0); + } + if ((str=BUF_strdup(name)) == NULL) + { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); + return(0); + } + i=sk_OPENSSL_STRING_push(app_locks,str); + if (!i) + OPENSSL_free(str); + else + i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ + return(i); + } int CRYPTO_num_locks(void) { return CRYPTO_NUM_LOCKS; } +int CRYPTO_get_new_dynlockid(void) + { + int i = 0; + CRYPTO_dynlock *pointer = NULL; + + if (dynlock_create_callback == NULL) + { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); + return(0); + } + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + if ((dyn_locks == NULL) + && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL)) + { + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); + return(0); + } + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock)); + if (pointer == NULL) + { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); + return(0); + } + pointer->references = 1; + pointer->data = dynlock_create_callback(__FILE__,__LINE__); + if (pointer->data == NULL) + { + OPENSSL_free(pointer); + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); + return(0); + } + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + /* First, try to find an existing empty slot */ + i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); + /* If there was none, push, thereby creating a new one */ + if (i == -1) + /* Since sk_push() returns the number of items on the + stack, not the location of the pushed item, we need + to transform the returned number into a position, + by decreasing it. */ + i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1; + else + /* If we found a place with a NULL pointer, put our pointer + in it. */ + (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (i == -1) + { + dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); + OPENSSL_free(pointer); + } + else + i += 1; /* to avoid 0 */ + return -i; + } + +void CRYPTO_destroy_dynlockid(int i) + { + CRYPTO_dynlock *pointer = NULL; + if (i) + i = -i-1; + if (dynlock_destroy_callback == NULL) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) + { + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + return; + } + pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); + if (pointer != NULL) + { + --pointer->references; +#ifdef REF_CHECK + if (pointer->references < 0) + { + fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n"); + abort(); + } + else +#endif + if (pointer->references <= 0) + { + (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); + } + else + pointer = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (pointer) + { + dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); + OPENSSL_free(pointer); + } + } + +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) + { + CRYPTO_dynlock *pointer = NULL; + if (i) + i = -i-1; + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) + pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); + if (pointer) + pointer->references++; + + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (pointer) + return pointer->data; + return NULL; + } + +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) + (const char *file,int line) + { + return(dynlock_create_callback); + } + +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, + struct CRYPTO_dynlock_value *l, const char *file,int line) + { + return(dynlock_lock_callback); + } + +void (*CRYPTO_get_dynlock_destroy_callback(void)) + (struct CRYPTO_dynlock_value *l, const char *file,int line) + { + return(dynlock_destroy_callback); + } + +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) + (const char *file, int line)) + { + dynlock_create_callback=func; + } + +void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, + struct CRYPTO_dynlock_value *l, const char *file, int line)) + { + dynlock_lock_callback=func; + } + +void CRYPTO_set_dynlock_destroy_callback(void (*func) + (struct CRYPTO_dynlock_value *l, const char *file, int line)) + { + dynlock_destroy_callback=func; + } + + void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, int line) { @@ -156,6 +418,108 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, add_lock_callback=func; } +/* the memset() here and in set_pointer() seem overkill, but for the sake of + * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two + * "equal" THREADID structs to not be memcmp()-identical. */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) + { + memset(id, 0, sizeof(*id)); + id->val = val; + } + +static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 }; +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) + { + unsigned char *dest = (void *)&id->val; + unsigned int accum = 0; + unsigned char dnum = sizeof(id->val); + + memset(id, 0, sizeof(*id)); + id->ptr = ptr; + if (sizeof(id->val) >= sizeof(id->ptr)) + { + /* 'ptr' can be embedded in 'val' without loss of uniqueness */ + id->val = (unsigned long)id->ptr; + return; + } + /* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a + * linear function over the bytes in 'ptr', the co-efficients of which + * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - + * the starting prime for the sequence varies for each byte of 'val' + * (unique polynomials unless pointers are >64-bit). For added spice, + * the totals accumulate rather than restarting from zero, and the index + * of the 'val' byte is added each time (position dependence). If I was + * a black-belt, I'd scan big-endian pointers in reverse to give + * low-order bits more play, but this isn't crypto and I'd prefer nobody + * mistake it as such. Plus I'm lazy. */ + while (dnum--) + { + const unsigned char *src = (void *)&id->ptr; + unsigned char snum = sizeof(id->ptr); + while (snum--) + accum += *(src++) * hash_coeffs[(snum + dnum) & 7]; + accum += dnum; + *(dest++) = accum & 255; + } + } + +int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) + { + if (threadid_callback) + return 0; + threadid_callback = func; + return 1; + } + +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) + { + return threadid_callback; + } + +void CRYPTO_THREADID_current(CRYPTO_THREADID *id) + { + if (threadid_callback) + { + threadid_callback(id); + return; + } +#ifndef OPENSSL_NO_DEPRECATED + /* If the deprecated callback was set, fall back to that */ + if (id_callback) + { + CRYPTO_THREADID_set_numeric(id, id_callback()); + return; + } +#endif + /* Else pick a backup */ +#ifdef OPENSSL_SYS_WIN16 + CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask()); +#elif defined(OPENSSL_SYS_WIN32) + CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId()); +#elif defined(OPENSSL_SYS_BEOS) + CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL)); +#else + /* For everything else, default to using the address of 'errno' */ + CRYPTO_THREADID_set_pointer(id, &errno); +#endif + } + +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) + { + return memcmp(a, b, sizeof(*a)); + } + +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) + { + memcpy(dest, src, sizeof(*src)); + } + +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) + { + return id->val; + } + +#ifndef OPENSSL_NO_DEPRECATED unsigned long (*CRYPTO_get_id_callback(void))(void) { return(id_callback); @@ -178,6 +542,8 @@ unsigned long CRYPTO_thread_id(void) ret=(unsigned long)GetCurrentThreadId(); #elif defined(GETPID_IS_MEANINGLESS) ret=1L; +#elif defined(OPENSSL_SYS_BEOS) + ret=(unsigned long)find_thread(NULL); #else ret=(unsigned long)getpid(); #endif @@ -186,19 +552,13 @@ unsigned long CRYPTO_thread_id(void) ret=id_callback(); return(ret); } - -static void (*do_dynlock_cb)(int mode, int type, const char *file, int line); - -void int_CRYPTO_set_do_dynlock_callback( - void (*dyn_cb)(int mode, int type, const char *file, int line)) - { - do_dynlock_cb = dyn_cb; - } +#endif void CRYPTO_lock(int mode, int type, const char *file, int line) { #ifdef LOCK_DEBUG { + CRYPTO_THREADID id; char *rw_text,*operation_text; if (mode & CRYPTO_LOCK) @@ -215,15 +575,25 @@ void CRYPTO_lock(int mode, int type, const char *file, int line) else rw_text="ERROR"; + CRYPTO_THREADID_current(&id); fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", - CRYPTO_thread_id(), rw_text, operation_text, + CRYPTO_THREADID_hash(&id), rw_text, operation_text, CRYPTO_get_lock_name(type), file, line); } #endif if (type < 0) { - if (do_dynlock_cb) - do_dynlock_cb(mode, type, file, line); + if (dynlock_lock_callback != NULL) + { + struct CRYPTO_dynlock_value *pointer + = CRYPTO_get_dynlock_value(type); + + OPENSSL_assert(pointer != NULL); + + dynlock_lock_callback(mode, pointer, file, line); + + CRYPTO_destroy_dynlockid(type); + } } else if (locking_callback != NULL) @@ -243,11 +613,14 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, ret=add_lock_callback(pointer,amount,type,file,line); #ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + CRYPTO_THREADID_current(&id); fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_thread_id(), - before,amount,ret, + CRYPTO_THREADID_hash(&id), before,amount,ret, CRYPTO_get_lock_name(type), file,line); + } #endif } else @@ -256,11 +629,15 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, ret= *pointer+amount; #ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + CRYPTO_THREADID_current(&id); fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_thread_id(), + CRYPTO_THREADID_hash(&id), *pointer,amount,ret, CRYPTO_get_lock_name(type), file,line); + } #endif *pointer=ret; CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); @@ -268,6 +645,18 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, return(ret); } +const char *CRYPTO_get_lock_name(int type) + { + if (type < 0) + return("dynamic"); + else if (type < CRYPTO_NUM_LOCKS) + return(lock_names[type]); + else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) + return("ERROR"); + else + return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS)); + } + #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__INTEL__) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) @@ -301,70 +690,16 @@ void OPENSSL_cpuid_setup(void) unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; } #endif int OPENSSL_NONPIC_relocated = 0; -#if !defined(OPENSSL_CPUID_SETUP) +#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) void OPENSSL_cpuid_setup(void) {} #endif #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) - -#ifdef OPENSSL_FIPS - -#include -#if defined(__GNUC__) && __GNUC__>=2 -static int DllInit(void) __attribute__((constructor)); -#elif defined(_MSC_VER) -static int DllInit(void); -# ifdef _WIN64 -# pragma section(".CRT$XCU",read) - __declspec(allocate(".CRT$XCU")) -# else -# pragma data_seg(".CRT$XCU") -# endif - static int (*p)(void) = DllInit; -# pragma data_seg() -#endif - -static int DllInit(void) -{ -#if defined(_WIN32_WINNT) - union { int(*f)(void); BYTE *p; } t = { DllInit }; - HANDLE hModuleSnap = INVALID_HANDLE_VALUE; - IMAGE_DOS_HEADER *dos_header; - IMAGE_NT_HEADERS *nt_headers; - MODULEENTRY32 me32 = {sizeof(me32)}; - - hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0); - if (hModuleSnap != INVALID_HANDLE_VALUE && - Module32First(hModuleSnap,&me32)) do - { - if (t.p >= me32.modBaseAddr && - t.p < me32.modBaseAddr+me32.modBaseSize) - { - dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr; - if (dos_header->e_magic==IMAGE_DOS_SIGNATURE) - { - nt_headers=(IMAGE_NT_HEADERS *) - ((BYTE *)dos_header+dos_header->e_lfanew); - if (nt_headers->Signature==IMAGE_NT_SIGNATURE && - me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase) - OPENSSL_NONPIC_relocated=1; - } - break; - } - } while (Module32Next(hModuleSnap,&me32)); - - if (hModuleSnap != INVALID_HANDLE_VALUE) - CloseHandle(hModuleSnap); -#endif - OPENSSL_cpuid_setup(); - return 0; -} - -#else - #ifdef __CYGWIN__ /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ #include +/* this has side-effect of _WIN32 getting defined, which otherwise + * is mutually exclusive with __CYGWIN__... */ #endif /* All we really need to do is remove the 'error' state when a thread @@ -405,16 +740,27 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, } #endif -#endif - #if defined(_WIN32) && !defined(__CYGWIN__) #include +#include #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 int OPENSSL_isservice(void) { HWINSTA h; DWORD len; WCHAR *name; + static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL }; + + if (_OPENSSL_isservice.p == NULL) { + HANDLE h = GetModuleHandle(NULL); + if (h != NULL) + _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice"); + if (_OPENSSL_isservice.p == NULL) + _OPENSSL_isservice.p = (void *)-1; + } + + if (_OPENSSL_isservice.p != (void *)-1) + return (*_OPENSSL_isservice.f)(); (void)GetDesktopWindow(); /* return value is ignored */ @@ -539,7 +885,13 @@ void OpenSSLDie(const char *file,int line,const char *assertion) OPENSSL_showfatal( "%s(%d): OpenSSL internal error, assertion failed: %s\n", file,line,assertion); +#if !defined(_WIN32) || defined(__CYGWIN__) abort(); +#else + /* Win32 abort() customarily shows a dialog, but we just did that... */ + raise(SIGABRT); + _exit(3); +#endif } void *OPENSSL_stderr(void) { return stderr; } diff --git a/crypto/openssl/crypto/crypto.h b/crypto/openssl/crypto/crypto.h index 0e4fb0723c..b0360cec51 100644 --- a/crypto/openssl/crypto/crypto.h +++ b/crypto/openssl/crypto/crypto.h @@ -1,6 +1,6 @@ /* crypto/crypto.h */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -219,13 +219,9 @@ typedef struct openssl_item_st #define CRYPTO_LOCK_EC_PRE_COMP 36 #define CRYPTO_LOCK_STORE 37 #define CRYPTO_LOCK_COMP 38 -#ifndef OPENSSL_FIPS -#define CRYPTO_NUM_LOCKS 39 -#else #define CRYPTO_LOCK_FIPS 39 #define CRYPTO_LOCK_FIPS2 40 #define CRYPTO_NUM_LOCKS 41 -#endif #define CRYPTO_LOCK 1 #define CRYPTO_UNLOCK 2 @@ -288,9 +284,10 @@ typedef struct bio_st BIO_dummy; struct crypto_ex_data_st { - STACK *sk; + STACK_OF(void) *sk; int dummy; /* gcc is screwing up this data structure :-( */ }; +DECLARE_STACK_OF(void) /* This stuff is basically class callback functions * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */ @@ -347,7 +344,14 @@ DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) /* Set standard debugging functions (not done by default * unless CRYPTO_MDEBUG is defined) */ -void CRYPTO_malloc_debug_init(void); +#define CRYPTO_malloc_debug_init() do {\ + CRYPTO_set_mem_debug_functions(\ + CRYPTO_dbg_malloc,\ + CRYPTO_dbg_realloc,\ + CRYPTO_dbg_free,\ + CRYPTO_dbg_set_options,\ + CRYPTO_dbg_get_options);\ + } while(0) int CRYPTO_mem_ctrl(int mode); int CRYPTO_is_mem_check_on(void); @@ -420,16 +424,32 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, const char *file, int line)); int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, const char *file,int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st + { + void *ptr; + unsigned long val; + } CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); +#ifndef OPENSSL_NO_DEPRECATED void CRYPTO_set_id_callback(unsigned long (*func)(void)); unsigned long (*CRYPTO_get_id_callback(void))(void); unsigned long CRYPTO_thread_id(void); +#endif + const char *CRYPTO_get_lock_name(int type); int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, int line); -void int_CRYPTO_set_do_dynlock_callback( - void (*do_dynlock_cb)(int mode, int type, const char *file, int line)); - int CRYPTO_get_new_dynlockid(void); void CRYPTO_destroy_dynlockid(int i); struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); @@ -454,10 +474,6 @@ int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int), void (*f)(void *,int), void (*so)(long), long (*go)(void)); -void CRYPTO_set_mem_info_functions( - int (*push_info_fn)(const char *info, const char *file, int line), - int (*pop_info_fn)(void), - int (*remove_all_info_fn)(void)); void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *)); void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)); void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int), @@ -514,9 +530,6 @@ void CRYPTO_dbg_free(void *addr,int before_p); void CRYPTO_dbg_set_options(long bits); long CRYPTO_dbg_get_options(void); -int CRYPTO_dbg_push_info(const char *info, const char *file, int line); -int CRYPTO_dbg_pop_info(void); -int CRYPTO_dbg_remove_all_info(void); #ifndef OPENSSL_NO_FP_API void CRYPTO_mem_leaks_fp(FILE *); @@ -534,69 +547,12 @@ unsigned long *OPENSSL_ia32cap_loc(void); #define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) int OPENSSL_isservice(void); -#ifdef OPENSSL_FIPS -#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \ - alg " previous FIPS forbidden algorithm error ignored"); - -#define FIPS_BAD_ABORT(alg) OpenSSLDie(__FILE__, __LINE__, \ - #alg " Algorithm forbidden in FIPS mode"); - -#ifdef OPENSSL_FIPS_STRICT -#define FIPS_BAD_ALGORITHM(alg) FIPS_BAD_ABORT(alg) -#else -#define FIPS_BAD_ALGORITHM(alg) \ - { \ - FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); \ - ERR_add_error_data(2, "Algorithm=", #alg); \ - return 0; \ - } -#endif - -/* Low level digest API blocking macro */ - -#define FIPS_NON_FIPS_MD_Init(alg) \ - int alg##_Init(alg##_CTX *c) \ - { \ - if (FIPS_mode()) \ - FIPS_BAD_ALGORITHM(alg) \ - return private_##alg##_Init(c); \ - } \ - int private_##alg##_Init(alg##_CTX *c) - -/* For ciphers the API often varies from cipher to cipher and each needs to - * be treated as a special case. Variable key length ciphers (Blowfish, RC4, - * CAST) however are very similar and can use a blocking macro. - */ - -#define FIPS_NON_FIPS_VCIPHER_Init(alg) \ - void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) \ - { \ - if (FIPS_mode()) \ - FIPS_BAD_ABORT(alg) \ - private_##alg##_set_key(key, len, data); \ - } \ - void private_##alg##_set_key(alg##_KEY *key, int len, \ - const unsigned char *data) - -#else - -#define FIPS_NON_FIPS_VCIPHER_Init(alg) \ - void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) - -#define FIPS_NON_FIPS_MD_Init(alg) \ - int alg##_Init(alg##_CTX *c) - -#endif /* def OPENSSL_FIPS */ - /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ void ERR_load_CRYPTO_strings(void); -#define OPENSSL_HAVE_INIT 1 -void OPENSSL_init(void); - /* Error codes for the CRYPTO functions. */ /* Function codes. */ diff --git a/crypto/openssl/crypto/des/des_enc.c b/crypto/openssl/crypto/des/des_enc.c index cf71965aca..828feba208 100644 --- a/crypto/openssl/crypto/des/des_enc.c +++ b/crypto/openssl/crypto/des/des_enc.c @@ -57,6 +57,7 @@ */ #include "des_locl.h" +#include "spr.h" void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) { @@ -107,12 +108,10 @@ void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) D_ENCRYPT(l,r,28); /* 15 */ D_ENCRYPT(r,l,30); /* 16 */ #else - for (i=0; i<32; i+=8) + for (i=0; i<32; i+=4) { D_ENCRYPT(l,r,i+0); /* 1 */ D_ENCRYPT(r,l,i+2); /* 2 */ - D_ENCRYPT(l,r,i+4); /* 3 */ - D_ENCRYPT(r,l,i+6); /* 4 */ } #endif } @@ -136,12 +135,10 @@ void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) D_ENCRYPT(l,r, 2); /* 2 */ D_ENCRYPT(r,l, 0); /* 1 */ #else - for (i=30; i>0; i-=8) + for (i=30; i>0; i-=4) { D_ENCRYPT(l,r,i-0); /* 16 */ D_ENCRYPT(r,l,i-2); /* 15 */ - D_ENCRYPT(l,r,i-4); /* 14 */ - D_ENCRYPT(r,l,i-6); /* 13 */ } #endif } @@ -203,12 +200,10 @@ void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc) D_ENCRYPT(l,r,28); /* 15 */ D_ENCRYPT(r,l,30); /* 16 */ #else - for (i=0; i<32; i+=8) + for (i=0; i<32; i+=4) { D_ENCRYPT(l,r,i+0); /* 1 */ D_ENCRYPT(r,l,i+2); /* 2 */ - D_ENCRYPT(l,r,i+4); /* 3 */ - D_ENCRYPT(r,l,i+6); /* 4 */ } #endif } @@ -232,12 +227,10 @@ void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc) D_ENCRYPT(l,r, 2); /* 2 */ D_ENCRYPT(r,l, 0); /* 1 */ #else - for (i=30; i>0; i-=8) + for (i=30; i>0; i-=4) { D_ENCRYPT(l,r,i-0); /* 16 */ D_ENCRYPT(r,l,i-2); /* 15 */ - D_ENCRYPT(l,r,i-4); /* 14 */ - D_ENCRYPT(r,l,i-6); /* 13 */ } #endif } @@ -289,8 +282,6 @@ void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, #ifndef DES_DEFAULT_OPTIONS -#if !defined(OPENSSL_FIPS_DES_ASM) - #undef CBC_ENC_C__DONT_UPDATE_IV #include "ncbc_enc.c" /* DES_ncbc_encrypt */ @@ -406,6 +397,4 @@ void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, tin[0]=tin[1]=0; } -#endif - #endif /* DES_DEFAULT_OPTIONS */ diff --git a/crypto/openssl/crypto/des/des_lib.c b/crypto/openssl/crypto/des/des_lib.c deleted file mode 100644 index d4b3047932..0000000000 --- a/crypto/openssl/crypto/des/des_lib.c +++ /dev/null @@ -1,106 +0,0 @@ -/* crypto/des/ecb_enc.c */ -/* 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 "des_locl.h" -#include "des_ver.h" -#include -#include - -OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT; -OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT; - -const char *DES_options(void) - { - static int init=1; - static char buf[32]; - - if (init) - { - const char *ptr,*unroll,*risc,*size; - -#ifdef DES_PTR - ptr="ptr"; -#else - ptr="idx"; -#endif -#if defined(DES_RISC1) || defined(DES_RISC2) -#ifdef DES_RISC1 - risc="risc1"; -#endif -#ifdef DES_RISC2 - risc="risc2"; -#endif -#else - risc="cisc"; -#endif -#ifdef DES_UNROLL - unroll="16"; -#else - unroll="4"; -#endif - if (sizeof(DES_LONG) != sizeof(long)) - size="int"; - else - size="long"; - BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll, - size); - init=0; - } - return(buf); - } - diff --git a/crypto/openssl/crypto/des/des_locl.h b/crypto/openssl/crypto/des/des_locl.h index 4b9ecff233..a3b512e9b0 100644 --- a/crypto/openssl/crypto/des/des_locl.h +++ b/crypto/openssl/crypto/des/des_locl.h @@ -61,7 +61,7 @@ #include -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) +#if defined(OPENSSL_SYS_WIN32) #ifndef OPENSSL_SYS_MSDOS #define OPENSSL_SYS_MSDOS #endif @@ -425,4 +425,8 @@ extern const DES_LONG DES_SPtrans[8][64]; void fcrypt_body(DES_LONG *out,DES_key_schedule *ks, DES_LONG Eswap0, DES_LONG Eswap1); + +#ifdef OPENSSL_SMALL_FOOTPRINT +#undef DES_UNROLL +#endif #endif diff --git a/crypto/openssl/crypto/des/ecb_enc.c b/crypto/openssl/crypto/des/ecb_enc.c index 75ae6cf8bb..0684e769b3 100644 --- a/crypto/openssl/crypto/des/ecb_enc.c +++ b/crypto/openssl/crypto/des/ecb_enc.c @@ -57,7 +57,53 @@ */ #include "des_locl.h" -#include "spr.h" +#include "des_ver.h" +#include +#include + +OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT; +OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT; + +const char *DES_options(void) + { + static int init=1; + static char buf[32]; + + if (init) + { + const char *ptr,*unroll,*risc,*size; + +#ifdef DES_PTR + ptr="ptr"; +#else + ptr="idx"; +#endif +#if defined(DES_RISC1) || defined(DES_RISC2) +#ifdef DES_RISC1 + risc="risc1"; +#endif +#ifdef DES_RISC2 + risc="risc2"; +#endif +#else + risc="cisc"; +#endif +#ifdef DES_UNROLL + unroll="16"; +#else + unroll="2"; +#endif + if (sizeof(DES_LONG) != sizeof(long)) + size="int"; + else + size="long"; + BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll, + size); + init=0; + } + return(buf); + } + void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks, int enc) diff --git a/crypto/openssl/crypto/des/enc_read.c b/crypto/openssl/crypto/des/enc_read.c index e7da2ec66b..edb6620d08 100644 --- a/crypto/openssl/crypto/des/enc_read.c +++ b/crypto/openssl/crypto/des/enc_read.c @@ -63,7 +63,7 @@ /* This has some uglies in it but it works - even over sockets. */ /*extern int errno;*/ -OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode)=DES_PCBC_MODE; +OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode,DES_PCBC_MODE) /* @@ -87,6 +87,9 @@ OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode)=DES_PCBC_MODE; int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, DES_cblock *iv) { +#if defined(OPENSSL_NO_POSIX_IO) + return(0); +#else /* data to be unencrypted */ int net_num=0; static unsigned char *net=NULL; @@ -147,7 +150,7 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, /* first - get the length */ while (net_num < HDRSIZE) { -#ifndef _WIN32 +#ifndef OPENSSL_SYS_WIN32 i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); #else i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); @@ -173,7 +176,11 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, net_num=0; while (net_num < rnum) { +#ifndef OPENSSL_SYS_WIN32 i=read(fd,(void *)&(net[net_num]),rnum-net_num); +#else + i=_read(fd,(void *)&(net[net_num]),rnum-net_num); +#endif #ifdef EINTR if ((i == -1) && (errno == EINTR)) continue; #endif @@ -228,5 +235,6 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, } } return num; +#endif /* OPENSSL_NO_POSIX_IO */ } diff --git a/crypto/openssl/crypto/des/enc_writ.c b/crypto/openssl/crypto/des/enc_writ.c index c2f032c9a6..2353ac1e89 100644 --- a/crypto/openssl/crypto/des/enc_writ.c +++ b/crypto/openssl/crypto/des/enc_writ.c @@ -80,6 +80,9 @@ int DES_enc_write(int fd, const void *_buf, int len, DES_key_schedule *sched, DES_cblock *iv) { +#if defined(OPENSSL_NO_POSIX_IO) + return (-1); +#else #ifdef _LIBC extern unsigned long time(); extern int write(); @@ -172,4 +175,5 @@ int DES_enc_write(int fd, const void *_buf, int len, } return(len); +#endif /* OPENSSL_NO_POSIX_IO */ } diff --git a/crypto/openssl/crypto/des/fcrypt_b.c b/crypto/openssl/crypto/des/fcrypt_b.c index 1390138787..8822816938 100644 --- a/crypto/openssl/crypto/des/fcrypt_b.c +++ b/crypto/openssl/crypto/des/fcrypt_b.c @@ -100,12 +100,10 @@ void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0, #ifndef DES_UNROLL register int i; - for (i=0; i<32; i+=8) + for (i=0; i<32; i+=4) { D_ENCRYPT(l,r,i+0); /* 1 */ D_ENCRYPT(r,l,i+2); /* 2 */ - D_ENCRYPT(l,r,i+4); /* 1 */ - D_ENCRYPT(r,l,i+6); /* 2 */ } #else D_ENCRYPT(l,r, 0); /* 1 */ diff --git a/crypto/openssl/crypto/des/rpc_des.h b/crypto/openssl/crypto/des/rpc_des.h index 4cbb4d2dcd..41328d7965 100644 --- a/crypto/openssl/crypto/des/rpc_des.h +++ b/crypto/openssl/crypto/des/rpc_des.h @@ -122,10 +122,10 @@ struct desparams { /* * Encrypt an arbitrary sized buffer */ -#define DESIOCBLOCK _IOWR(d, 6, struct desparams) +#define DESIOCBLOCK _IOWR('d', 6, struct desparams) /* * Encrypt of small amount of data, quickly */ -#define DESIOCQUICK _IOWR(d, 7, struct desparams) +#define DESIOCQUICK _IOWR('d', 7, struct desparams) diff --git a/crypto/openssl/crypto/des/set_key.c b/crypto/openssl/crypto/des/set_key.c index c0806d593c..3004cc3ab3 100644 --- a/crypto/openssl/crypto/des/set_key.c +++ b/crypto/openssl/crypto/des/set_key.c @@ -64,12 +64,8 @@ * 1.0 First working version */ #include "des_locl.h" -#ifdef OPENSSL_FIPS -#include -#endif - -OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key); /* defaults to false */ +OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0) /* defaults to false */ static const unsigned char odd_parity[256]={ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, @@ -340,7 +336,7 @@ int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) { - static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; + static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; register DES_LONG c,d,t,s,t2; register const unsigned char *in; register DES_LONG *k; @@ -353,10 +349,6 @@ void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) k = &schedule->ks->deslong[0]; in = &(*key)[0]; -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif - c2l(in,c); c2l(in,d); @@ -413,4 +405,3 @@ void des_fixup_key_parity(des_cblock *key) des_set_odd_parity(key); } */ - diff --git a/crypto/openssl/crypto/des/xcbc_enc.c b/crypto/openssl/crypto/des/xcbc_enc.c index dc0c761b71..058cab6bce 100644 --- a/crypto/openssl/crypto/des/xcbc_enc.c +++ b/crypto/openssl/crypto/des/xcbc_enc.c @@ -61,7 +61,7 @@ /* RSA's DESX */ #if 0 /* broken code, preserved just in case anyone specifically looks for this */ -static unsigned char desx_white_in2out[256]={ +static const unsigned char desx_white_in2out[256]={ 0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0, 0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A, 0x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36, diff --git a/crypto/openssl/crypto/dh/dh.h b/crypto/openssl/crypto/dh/dh.h index 10475ac4b3..849309a489 100644 --- a/crypto/openssl/crypto/dh/dh.h +++ b/crypto/openssl/crypto/dh/dh.h @@ -77,8 +77,6 @@ # define OPENSSL_DH_MAX_MODULUS_BITS 10000 #endif -#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 - #define DH_FLAG_CACHE_MONT_P 0x01 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH * implementation now uses constant time @@ -159,7 +157,6 @@ struct dh_st this for backward compatibility: */ #define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME -#define DHparams_dup(x) ASN1_dup_of_const(DH,i2d_DHparams,d2i_DHparams,x) #define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) #define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ @@ -167,12 +164,9 @@ struct dh_st #define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) #define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) -const DH_METHOD *DH_OpenSSL(void); +DH *DHparams_dup(DH *); -#ifdef OPENSSL_FIPS -DH * FIPS_dh_new(void); -void FIPS_dh_free(DH *dh); -#endif +const DH_METHOD *DH_OpenSSL(void); void DH_set_default_method(const DH_METHOD *meth); const DH_METHOD *DH_get_default_method(void); @@ -212,6 +206,18 @@ int DHparams_print(BIO *bp, const DH *x); int DHparams_print(char *bp, const DH *x); #endif +#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +#define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) + + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -222,22 +228,31 @@ void ERR_load_DH_strings(void); /* Function codes. */ #define DH_F_COMPUTE_KEY 102 -#define DH_F_DHPARAMS_PRINT 100 #define DH_F_DHPARAMS_PRINT_FP 101 #define DH_F_DH_BUILTIN_GENPARAMS 106 -#define DH_F_DH_COMPUTE_KEY 107 -#define DH_F_DH_GENERATE_KEY 108 -#define DH_F_DH_GENERATE_PARAMETERS 109 #define DH_F_DH_NEW_METHOD 105 +#define DH_F_DH_PARAM_DECODE 107 +#define DH_F_DH_PRIV_DECODE 110 +#define DH_F_DH_PRIV_ENCODE 111 +#define DH_F_DH_PUB_DECODE 108 +#define DH_F_DH_PUB_ENCODE 109 +#define DH_F_DO_DH_PRINT 100 #define DH_F_GENERATE_KEY 103 #define DH_F_GENERATE_PARAMETERS 104 +#define DH_F_PKEY_DH_DERIVE 112 +#define DH_F_PKEY_DH_KEYGEN 113 /* Reason codes. */ #define DH_R_BAD_GENERATOR 101 +#define DH_R_BN_DECODE_ERROR 109 +#define DH_R_BN_ERROR 106 +#define DH_R_DECODE_ERROR 104 #define DH_R_INVALID_PUBKEY 102 -#define DH_R_KEY_SIZE_TOO_SMALL 104 +#define DH_R_KEYS_NOT_SET 108 #define DH_R_MODULUS_TOO_LARGE 103 +#define DH_R_NO_PARAMETERS_SET 107 #define DH_R_NO_PRIVATE_VALUE 100 +#define DH_R_PARAMETER_ENCODING_ERROR 105 #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/dh/dh_ameth.c b/crypto/openssl/crypto/dh/dh_ameth.c new file mode 100644 index 0000000000..377caf96c9 --- /dev/null +++ b/crypto/openssl/crypto/dh/dh_ameth.c @@ -0,0 +1,500 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include "asn1_locl.h" + +static void int_dh_free(EVP_PKEY *pkey) + { + DH_free(pkey->pkey.dh); + } + +static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) + { + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DH *dh = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) + { + DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) + { + DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + goto err; + } + + if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) + { + DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + goto err; + } + + /* We have parameters now set public key */ + if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) + { + DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign_DH(pkey, dh); + return 1; + + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (dh) + DH_free(dh); + return 0; + + } + +static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) + { + DH *dh; + void *pval = NULL; + int ptype; + unsigned char *penc = NULL; + int penclen; + ASN1_STRING *str; + ASN1_INTEGER *pub_key = NULL; + + dh=pkey->pkey.dh; + + str = ASN1_STRING_new(); + str->length = i2d_DHparams(dh, &str->data); + if (str->length <= 0) + { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + pval = str; + ptype = V_ASN1_SEQUENCE; + + pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); + if (!pub_key) + goto err; + + penclen = i2d_ASN1_INTEGER(pub_key, &penc); + + ASN1_INTEGER_free(pub_key); + + if (penclen <= 0) + { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH), + ptype, pval, penc, penclen)) + return 1; + + err: + if (penc) + OPENSSL_free(penc); + if (pval) + ASN1_STRING_free(pval); + + return 0; + } + + +/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in + * that the AlgorithmIdentifier contains the paramaters, the private key + * is explcitly included and the pubkey must be recalculated. + */ + +static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) + { + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + + DH *dh = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + + if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) + goto decerr; + + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) + goto decerr; + /* We have parameters now set private key */ + if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) + { + DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR); + goto dherr; + } + /* Calculate public key */ + if (!DH_generate_key(dh)) + goto dherr; + + EVP_PKEY_assign_DH(pkey, dh); + + ASN1_INTEGER_free(privkey); + + return 1; + + decerr: + DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); + dherr: + DH_free(dh); + return 0; + } + +static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + unsigned char *dp = NULL; + int dplen; + + params = ASN1_STRING_new(); + + if (!params) + { + DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_DHparams(pkey->pkey.dh, ¶ms->data); + if (params->length <= 0) + { + DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); + + if (!prkey) + { + DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_INTEGER_free(prkey); + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) + goto err; + + return 1; + +err: + if (dp != NULL) + OPENSSL_free(dp); + if (params != NULL) + ASN1_STRING_free(params); + if (prkey != NULL) + ASN1_INTEGER_free(prkey); + return 0; +} + + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) + { + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; + } + +static int dh_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + DH *dh; + if (!(dh = d2i_DHparams(NULL, pder, derlen))) + { + DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); + return 0; + } + EVP_PKEY_assign_DH(pkey, dh); + return 1; + } + +static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_DHparams(pkey->pkey.dh, pder); + } + +static int do_dh_print(BIO *bp, const DH *x, int indent, + ASN1_PCTX *ctx, int ptype) + { + unsigned char *m=NULL; + int reason=ERR_R_BUF_LIB,ret=0; + size_t buf_len=0; + + const char *ktype = NULL; + + BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + update_buflen(x->p, &buf_len); + + if (buf_len == 0) + { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + update_buflen(x->g, &buf_len); + update_buflen(pub_key, &buf_len); + update_buflen(priv_key, &buf_len); + + if (ptype == 2) + ktype = "PKCS#3 DH Private-Key"; + else if (ptype == 1) + ktype = "PKCS#3 DH Public-Key"; + else + ktype = "PKCS#3 DH Parameters"; + + m= OPENSSL_malloc(buf_len+10); + if (m == NULL) + { + reason=ERR_R_MALLOC_FAILURE; + goto err; + } + + BIO_indent(bp, indent, 128); + if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) + goto err; + indent += 4; + + if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err; + if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err; + + if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err; + if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err; + if (x->length != 0) + { + BIO_indent(bp, indent, 128); + if (BIO_printf(bp,"recommended-private-length: %d bits\n", + (int)x->length) <= 0) goto err; + } + + + ret=1; + if (0) + { +err: + DHerr(DH_F_DO_DH_PRINT,reason); + } + if (m != NULL) OPENSSL_free(m); + return(ret); + } + +static int int_dh_size(const EVP_PKEY *pkey) + { + return(DH_size(pkey->pkey.dh)); + } + +static int dh_bits(const EVP_PKEY *pkey) + { + return BN_num_bits(pkey->pkey.dh->p); + } + +static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) + { + if ( BN_cmp(a->pkey.dh->p,b->pkey.dh->p) || + BN_cmp(a->pkey.dh->g,b->pkey.dh->g)) + return 0; + else + return 1; + } + +static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) + { + BIGNUM *a; + + if ((a=BN_dup(from->pkey.dh->p)) == NULL) + return 0; + if (to->pkey.dh->p != NULL) + BN_free(to->pkey.dh->p); + to->pkey.dh->p=a; + + if ((a=BN_dup(from->pkey.dh->g)) == NULL) + return 0; + if (to->pkey.dh->g != NULL) + BN_free(to->pkey.dh->g); + to->pkey.dh->g=a; + + return 1; + } + +static int dh_missing_parameters(const EVP_PKEY *a) + { + if (!a->pkey.dh->p || !a->pkey.dh->g) + return 1; + return 0; + } + +static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (dh_cmp_parameters(a, b) == 0) + return 0; + if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0) + return 0; + else + return 1; + } + +static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); + } + +static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); + } + +static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); + } + +int DHparams_print(BIO *bp, const DH *x) + { + return do_dh_print(bp, x, 4, NULL, 0); + } + +const EVP_PKEY_ASN1_METHOD dh_asn1_meth = + { + EVP_PKEY_DH, + EVP_PKEY_DH, + 0, + + "DH", + "OpenSSL PKCS#3 DH method", + + dh_pub_decode, + dh_pub_encode, + dh_pub_cmp, + dh_public_print, + + dh_priv_decode, + dh_priv_encode, + dh_private_print, + + int_dh_size, + dh_bits, + + dh_param_decode, + dh_param_encode, + dh_missing_parameters, + dh_copy_parameters, + dh_cmp_parameters, + dh_param_print, + + int_dh_free, + 0 + }; + diff --git a/crypto/openssl/crypto/dh/dh_asn1.c b/crypto/openssl/crypto/dh/dh_asn1.c index 76740af2bd..0b4357d605 100644 --- a/crypto/openssl/crypto/dh/dh_asn1.c +++ b/crypto/openssl/crypto/dh/dh_asn1.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-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 @@ -64,7 +64,8 @@ #include /* Override the default free and new methods */ -static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_NEW_PRE) { *pval = (ASN1_VALUE *)DH_new(); @@ -85,3 +86,8 @@ ASN1_SEQUENCE_cb(DHparams, dh_cb) = { } ASN1_SEQUENCE_END_cb(DH, DHparams) IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) + +DH *DHparams_dup(DH *dh) + { + return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh); + } diff --git a/crypto/openssl/crypto/dh/dh_check.c b/crypto/openssl/crypto/dh/dh_check.c index 316cb9221d..066898174e 100644 --- a/crypto/openssl/crypto/dh/dh_check.c +++ b/crypto/openssl/crypto/dh/dh_check.c @@ -70,8 +70,6 @@ * should hold. */ -#ifndef OPENSSL_FIPS - int DH_check(const DH *dh, int *ret) { int ok=0; @@ -130,11 +128,11 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) q=BN_new(); if (q == NULL) goto err; BN_set_word(q,1); - if (BN_cmp(pub_key,q) <= 0) + if (BN_cmp(pub_key,q)<=0) *ret|=DH_CHECK_PUBKEY_TOO_SMALL; BN_copy(q,dh->p); BN_sub_word(q,1); - if (BN_cmp(pub_key,q) >= 0) + if (BN_cmp(pub_key,q)>=0) *ret|=DH_CHECK_PUBKEY_TOO_LARGE; ok = 1; @@ -142,5 +140,3 @@ err: if (q != NULL) BN_free(q); return(ok); } - -#endif diff --git a/crypto/openssl/crypto/dh/dh_err.c b/crypto/openssl/crypto/dh/dh_err.c index 13263c81c1..d5cf0c22a3 100644 --- a/crypto/openssl/crypto/dh/dh_err.c +++ b/crypto/openssl/crypto/dh/dh_err.c @@ -1,6 +1,6 @@ /* crypto/dh/dh_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -71,25 +71,34 @@ static ERR_STRING_DATA DH_str_functs[]= { {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, -{ERR_FUNC(DH_F_DHPARAMS_PRINT), "DHparams_print"}, {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, -{ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"}, -{ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"}, -{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS), "DH_generate_parameters"}, {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, +{ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"}, +{ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"}, +{ERR_FUNC(DH_F_DH_PRIV_ENCODE), "DH_PRIV_ENCODE"}, +{ERR_FUNC(DH_F_DH_PUB_DECODE), "DH_PUB_DECODE"}, +{ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"}, +{ERR_FUNC(DH_F_DO_DH_PRINT), "DO_DH_PRINT"}, {ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"}, {ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"}, +{ERR_FUNC(DH_F_PKEY_DH_DERIVE), "PKEY_DH_DERIVE"}, +{ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "PKEY_DH_KEYGEN"}, {0,NULL} }; static ERR_STRING_DATA DH_str_reasons[]= { {ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"}, +{ERR_REASON(DH_R_BN_DECODE_ERROR) ,"bn decode error"}, +{ERR_REASON(DH_R_BN_ERROR) ,"bn error"}, +{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, -{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, +{ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"}, {ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"}, +{ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"}, {ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"}, +{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/dh/dh_gen.c b/crypto/openssl/crypto/dh/dh_gen.c index 999e1deb40..cfd5b11868 100644 --- a/crypto/openssl/crypto/dh/dh_gen.c +++ b/crypto/openssl/crypto/dh/dh_gen.c @@ -66,8 +66,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) @@ -175,5 +173,3 @@ err: } return ok; } - -#endif diff --git a/crypto/openssl/crypto/dh/dh_key.c b/crypto/openssl/crypto/dh/dh_key.c index 79dd331863..e7db440342 100644 --- a/crypto/openssl/crypto/dh/dh_key.c +++ b/crypto/openssl/crypto/dh/dh_key.c @@ -62,8 +62,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int generate_key(DH *dh); static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, @@ -263,5 +261,3 @@ static int dh_finish(DH *dh) BN_MONT_CTX_free(dh->method_mont_p); return(1); } - -#endif diff --git a/crypto/openssl/crypto/dh/dh_pmeth.c b/crypto/openssl/crypto/dh/dh_pmeth.c new file mode 100644 index 0000000000..5ae72b7d4c --- /dev/null +++ b/crypto/openssl/crypto/dh/dh_pmeth.c @@ -0,0 +1,254 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "evp_locl.h" + +/* DH pkey context structure */ + +typedef struct + { + /* Parameter gen parameters */ + int prime_len; + int generator; + int use_dsa; + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ + } DH_PKEY_CTX; + +static int pkey_dh_init(EVP_PKEY_CTX *ctx) + { + DH_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX)); + if (!dctx) + return 0; + dctx->prime_len = 1024; + dctx->generator = 2; + dctx->use_dsa = 0; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; + } + +static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + DH_PKEY_CTX *dctx, *sctx; + if (!pkey_dh_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->prime_len = sctx->prime_len; + dctx->generator = sctx->generator; + dctx->use_dsa = sctx->use_dsa; + return 1; + } + +static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) + { + DH_PKEY_CTX *dctx = ctx->data; + if (dctx) + OPENSSL_free(dctx); + } + +static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + DH_PKEY_CTX *dctx = ctx->data; + switch (type) + { + case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: + if (p1 < 256) + return -2; + dctx->prime_len = p1; + return 1; + + case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: + dctx->generator = p1; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + return 1; + + default: + return -2; + + } + } + + +static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!strcmp(type, "dh_paramgen_prime_len")) + { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); + } + if (!strcmp(type, "dh_paramgen_generator")) + { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); + } + return -2; + } + +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + DH *dh = NULL; + DH_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (ctx->pkey_gencb) + { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } + else + pcb = NULL; + dh = DH_new(); + if (!dh) + return 0; + ret = DH_generate_parameters_ex(dh, + dctx->prime_len, dctx->generator, pcb); + if (ret) + EVP_PKEY_assign_DH(pkey, dh); + else + DH_free(dh); + return ret; + } + +static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + DH *dh = NULL; + if (ctx->pkey == NULL) + { + DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); + return 0; + } + dh = DH_new(); + if (!dh) + return 0; + EVP_PKEY_assign_DH(pkey, dh); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DH_generate_key(pkey->pkey.dh); + } + +static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) + { + int ret; + if (!ctx->pkey || !ctx->peerkey) + { + DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); + return 0; + } + ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, + ctx->pkey->pkey.dh); + if (ret < 0) + return ret; + *keylen = ret; + return 1; + } + +const EVP_PKEY_METHOD dh_pkey_meth = + { + EVP_PKEY_DH, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_dh_init, + pkey_dh_copy, + pkey_dh_cleanup, + + 0, + pkey_dh_paramgen, + + 0, + pkey_dh_keygen, + + 0, + 0, + + 0, + 0, + + 0,0, + + 0,0,0,0, + + 0,0, + + 0,0, + + 0, + pkey_dh_derive, + + pkey_dh_ctrl, + pkey_dh_ctrl_str + + }; diff --git a/crypto/openssl/crypto/err/err_bio.c b/crypto/openssl/crypto/dh/dh_prn.c similarity index 89% rename from crypto/openssl/crypto/err/err_bio.c rename to crypto/openssl/crypto/dh/dh_prn.c index a42f804840..ae58c2ac87 100644 --- a/crypto/openssl/crypto/err/err_bio.c +++ b/crypto/openssl/crypto/dh/dh_prn.c @@ -1,4 +1,4 @@ -/* crypto/err/err_prn.c */ +/* crypto/asn1/t_pkey.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -58,18 +58,23 @@ #include #include "cryptlib.h" -#include -#include -#include -#include +#include +#include -static int print_bio(const char *str, size_t len, void *bp) +#ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x) { - return BIO_write((BIO *)bp, str, len); - } -void ERR_print_errors(BIO *bp) - { - ERR_print_errors_cb(print_bio, bp); - } + BIO *b; + int ret; - + if ((b=BIO_new(BIO_s_file())) == NULL) + { + DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=DHparams_print(b, x); + BIO_free(b); + return(ret); + } +#endif diff --git a/crypto/openssl/crypto/dsa/dsa.h b/crypto/openssl/crypto/dsa/dsa.h index 702c50d6dc..ac50a5c846 100644 --- a/crypto/openssl/crypto/dsa/dsa.h +++ b/crypto/openssl/crypto/dsa/dsa.h @@ -88,8 +88,6 @@ # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif -#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 - #define DSA_FLAG_CACHE_MONT_P 0x01 #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA * implementation now uses constant time @@ -99,25 +97,6 @@ * be used for all exponents. */ -/* If this flag is set the DSA method is FIPS compliant and can be used - * in FIPS mode. This is set in the validated module method. If an - * application sets this flag in its own methods it is its reposibility - * to ensure the result is compliant. - */ - -#define DSA_FLAG_FIPS_METHOD 0x0400 - -/* If this flag is set the operations normally disabled in FIPS mode are - * permitted it is then the applications responsibility to ensure that the - * usage is compliant. - */ - -#define DSA_FLAG_NON_FIPS_ALLOW 0x0400 - -#ifdef OPENSSL_FIPS -#define FIPS_DSA_SIZE_T int -#endif - #ifdef __cplusplus extern "C" { #endif @@ -139,7 +118,7 @@ struct dsa_method int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); + DSA_SIG *sig, DSA *dsa); int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont); @@ -152,7 +131,7 @@ struct dsa_method char *app_data; /* If this is non-NULL, it is used to generate DSA parameters */ int (*dsa_paramgen)(DSA *dsa, int bits, - unsigned char *seed, int seed_len, + const unsigned char *seed, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); /* If this is non-NULL, it is used to generate DSA keys */ @@ -186,7 +165,6 @@ struct dsa_st ENGINE *engine; }; -#define DSAparams_dup(x) ASN1_dup_of_const(DSA,i2d_DSAparams,d2i_DSAparams,x) #define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) #define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ @@ -195,6 +173,7 @@ struct dsa_st #define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) +DSA *DSAparams_dup(DSA *x); DSA_SIG * DSA_SIG_new(void); void DSA_SIG_free(DSA_SIG *a); int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); @@ -210,11 +189,6 @@ void DSA_set_default_method(const DSA_METHOD *); const DSA_METHOD *DSA_get_default_method(void); int DSA_set_method(DSA *dsa, const DSA_METHOD *); -#ifdef OPENSSL_FIPS -DSA * FIPS_dsa_new(void); -void FIPS_dsa_free (DSA *r); -#endif - DSA * DSA_new(void); DSA * DSA_new_method(ENGINE *engine); void DSA_free (DSA *r); @@ -246,7 +220,7 @@ DSA * DSA_generate_parameters(int bits, /* New version */ int DSA_generate_parameters_ex(DSA *dsa, int bits, - unsigned char *seed,int seed_len, + const unsigned char *seed,int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int DSA_generate_key(DSA *a); @@ -275,10 +249,13 @@ int DSA_print_fp(FILE *bp, const DSA *x, int off); DH *DSA_dup_DH(const DSA *r); #endif -#ifdef OPENSSL_FIPS -int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig); -int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen); -#endif +#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +#define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -290,33 +267,39 @@ void ERR_load_DSA_strings(void); /* Function codes. */ #define DSA_F_D2I_DSA_SIG 110 +#define DSA_F_DO_DSA_PRINT 104 #define DSA_F_DSAPARAMS_PRINT 100 #define DSA_F_DSAPARAMS_PRINT_FP 101 -#define DSA_F_DSA_BUILTIN_KEYGEN 119 -#define DSA_F_DSA_BUILTIN_PARAMGEN 118 #define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_VERIFY 113 -#define DSA_F_DSA_GENERATE_PARAMETERS 117 #define DSA_F_DSA_NEW_METHOD 103 -#define DSA_F_DSA_PRINT 104 +#define DSA_F_DSA_PARAM_DECODE 119 #define DSA_F_DSA_PRINT_FP 105 -#define DSA_F_DSA_SET_DEFAULT_METHOD 115 -#define DSA_F_DSA_SET_METHOD 116 +#define DSA_F_DSA_PRIV_DECODE 115 +#define DSA_F_DSA_PRIV_ENCODE 116 +#define DSA_F_DSA_PUB_DECODE 117 +#define DSA_F_DSA_PUB_ENCODE 118 #define DSA_F_DSA_SIGN 106 #define DSA_F_DSA_SIGN_SETUP 107 #define DSA_F_DSA_SIG_NEW 109 #define DSA_F_DSA_VERIFY 108 #define DSA_F_I2D_DSA_SIG 111 +#define DSA_F_OLD_DSA_PRIV_DECODE 122 +#define DSA_F_PKEY_DSA_CTRL 120 +#define DSA_F_PKEY_DSA_KEYGEN 121 #define DSA_F_SIG_CB 114 /* Reason codes. */ #define DSA_R_BAD_Q_VALUE 102 +#define DSA_R_BN_DECODE_ERROR 108 +#define DSA_R_BN_ERROR 109 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 -#define DSA_R_KEY_SIZE_TOO_SMALL 106 +#define DSA_R_DECODE_ERROR 104 +#define DSA_R_INVALID_DIGEST_TYPE 106 #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 -#define DSA_R_NON_FIPS_METHOD 104 -#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 105 +#define DSA_R_NO_PARAMETERS_SET 107 +#define DSA_R_PARAMETER_ENCODING_ERROR 105 #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/dsa/dsa_ameth.c b/crypto/openssl/crypto/dsa/dsa_ameth.c new file mode 100644 index 0000000000..6413aae46e --- /dev/null +++ b/crypto/openssl/crypto/dsa/dsa_ameth.c @@ -0,0 +1,657 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_CMS +#include +#endif +#include "asn1_locl.h" + +static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) + { + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DSA *dsa = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + + if (ptype == V_ASN1_SEQUENCE) + { + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) + { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } + + } + else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) + { + if (!(dsa = DSA_new())) + { + DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + else + { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) + { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } + + if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) + { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (dsa) + DSA_free(dsa); + return 0; + + } + +static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) + { + DSA *dsa; + void *pval = NULL; + int ptype; + unsigned char *penc = NULL; + int penclen; + + dsa=pkey->pkey.dsa; + if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) + { + ASN1_STRING *str; + str = ASN1_STRING_new(); + str->length = i2d_DSAparams(dsa, &str->data); + if (str->length <= 0) + { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + pval = str; + ptype = V_ASN1_SEQUENCE; + } + else + ptype = V_ASN1_UNDEF; + + dsa->write_params=0; + + penclen = i2d_DSAPublicKey(dsa, &penc); + + if (penclen <= 0) + { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), + ptype, pval, penc, penclen)) + return 1; + + err: + if (penc) + OPENSSL_free(penc); + if (pval) + ASN1_STRING_free(pval); + + return 0; + } + +/* In PKCS#8 DSA: you just get a private key integer and parameters in the + * AlgorithmIdentifier the pubkey must be recalculated. + */ + +static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) + { + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + BN_CTX *ctx = NULL; + + STACK_OF(ASN1_TYPE) *ndsa = NULL; + DSA *dsa = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + /* Check for broken DSA PKCS#8, UGH! */ + if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) + { + ASN1_TYPE *t1, *t2; + if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) + goto decerr; + if (sk_ASN1_TYPE_num(ndsa) != 2) + goto decerr; + /* Handle Two broken types: + * SEQUENCE {parameters, priv_key} + * SEQUENCE {pub_key, priv_key} + */ + + t1 = sk_ASN1_TYPE_value(ndsa, 0); + t2 = sk_ASN1_TYPE_value(ndsa, 1); + if (t1->type == V_ASN1_SEQUENCE) + { + p8->broken = PKCS8_EMBEDDED_PARAM; + pval = t1->value.ptr; + } + else if (ptype == V_ASN1_SEQUENCE) + p8->broken = PKCS8_NS_DB; + else + goto decerr; + + if (t2->type != V_ASN1_INTEGER) + goto decerr; + + privkey = t2->value.integer; + } + else + { + const unsigned char *q = p; + if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) + goto decerr; + if (privkey->type == V_ASN1_NEG_INTEGER) + { + p8->broken = PKCS8_NEG_PRIVKEY; + ASN1_INTEGER_free(privkey); + if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen))) + goto decerr; + } + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) + goto decerr; + /* We have parameters now set private key */ + if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) + { + DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); + goto dsaerr; + } + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) + { + DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + if (!(ctx = BN_CTX_new())) + { + DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + + if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) + { + DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); + goto dsaerr; + } + + EVP_PKEY_assign_DSA(pkey, dsa); + BN_CTX_free (ctx); + if(ndsa) + sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + else + ASN1_INTEGER_free(privkey); + + return 1; + + decerr: + DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); + dsaerr: + BN_CTX_free (ctx); + if (privkey) + ASN1_INTEGER_free(privkey); + sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + DSA_free(dsa); + return 0; + } + +static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + unsigned char *dp = NULL; + int dplen; + + params = ASN1_STRING_new(); + + if (!params) + { + DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); + if (params->length <= 0) + { + DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); + + if (!prkey) + { + DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_INTEGER_free(prkey); + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) + goto err; + + return 1; + +err: + if (dp != NULL) + OPENSSL_free(dp); + if (params != NULL) + ASN1_STRING_free(params); + if (prkey != NULL) + ASN1_INTEGER_free(prkey); + return 0; +} + +static int int_dsa_size(const EVP_PKEY *pkey) + { + return(DSA_size(pkey->pkey.dsa)); + } + +static int dsa_bits(const EVP_PKEY *pkey) + { + return BN_num_bits(pkey->pkey.dsa->p); + } + +static int dsa_missing_parameters(const EVP_PKEY *pkey) + { + DSA *dsa; + dsa=pkey->pkey.dsa; + if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) + return 1; + return 0; + } + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) + { + BIGNUM *a; + + if ((a=BN_dup(from->pkey.dsa->p)) == NULL) + return 0; + if (to->pkey.dsa->p != NULL) + BN_free(to->pkey.dsa->p); + to->pkey.dsa->p=a; + + if ((a=BN_dup(from->pkey.dsa->q)) == NULL) + return 0; + if (to->pkey.dsa->q != NULL) + BN_free(to->pkey.dsa->q); + to->pkey.dsa->q=a; + + if ((a=BN_dup(from->pkey.dsa->g)) == NULL) + return 0; + if (to->pkey.dsa->g != NULL) + BN_free(to->pkey.dsa->g); + to->pkey.dsa->g=a; + return 1; + } + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) + { + if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || + BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || + BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g)) + return 0; + else + return 1; + } + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) + return 0; + else + return 1; + } + +static void int_dsa_free(EVP_PKEY *pkey) + { + DSA_free(pkey->pkey.dsa); + } + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) + { + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; + } + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) + { + unsigned char *m=NULL; + int ret=0; + size_t buf_len=0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + if (ptype == 2) + ktype = "Private-Key"; + else if (ptype == 1) + ktype = "Public-Key"; + else + ktype = "DSA-Parameters"; + + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->g, &buf_len); + update_buflen(priv_key, &buf_len); + update_buflen(pub_key, &buf_len); + + m=(unsigned char *)OPENSSL_malloc(buf_len+10); + if (m == NULL) + { + DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) + { + if(!BIO_indent(bp,off,128)) + goto err; + if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p)) + <= 0) goto err; + } + + if (!ASN1_bn_print(bp,"priv:",priv_key,m,off)) + goto err; + if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off)) + goto err; + if (!ASN1_bn_print(bp,"P: ",x->p,m,off)) goto err; + if (!ASN1_bn_print(bp,"Q: ",x->q,m,off)) goto err; + if (!ASN1_bn_print(bp,"G: ",x->g,m,off)) goto err; + ret=1; +err: + if (m != NULL) OPENSSL_free(m); + return(ret); + } + +static int dsa_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + DSA *dsa; + if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) + { + DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + } + +static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_DSAparams(pkey->pkey.dsa, pder); + } + +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); + } + +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); + } + + +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); + } + +static int old_dsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + DSA *dsa; + if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen))) + { + DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + } + +static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); + } + +static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) + { + switch (op) + { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 2; + + default: + return -2; + + } + + } + +/* NB these are sorted in pkey_id order, lowest first */ + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = + { + + { + EVP_PKEY_DSA2, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS + }, + + { + EVP_PKEY_DSA1, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS + }, + + { + EVP_PKEY_DSA4, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS + }, + + { + EVP_PKEY_DSA3, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS + }, + + { + EVP_PKEY_DSA, + EVP_PKEY_DSA, + 0, + + "DSA", + "OpenSSL DSA method", + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + dsa_pub_print, + + dsa_priv_decode, + dsa_priv_encode, + dsa_priv_print, + + int_dsa_size, + dsa_bits, + + dsa_param_decode, + dsa_param_encode, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + dsa_param_print, + + int_dsa_free, + dsa_pkey_ctrl, + old_dsa_priv_decode, + old_dsa_priv_encode + } + }; + diff --git a/crypto/openssl/crypto/dsa/dsa_asn1.c b/crypto/openssl/crypto/dsa/dsa_asn1.c index bc7d7a02a3..c37460b2d6 100644 --- a/crypto/openssl/crypto/dsa/dsa_asn1.c +++ b/crypto/openssl/crypto/dsa/dsa_asn1.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-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 @@ -61,25 +61,23 @@ #include #include #include -#include -#include -#ifdef OPENSSL_FIPS -#include -#endif - /* Override the default new methods */ -static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_NEW_PRE) { DSA_SIG *sig; sig = OPENSSL_malloc(sizeof(DSA_SIG)); + if (!sig) + { + DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE); + return 0; + } sig->r = NULL; sig->s = NULL; *pval = (ASN1_VALUE *)sig; - if(sig) return 2; - DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE); - return 0; + return 2; } return 1; } @@ -89,10 +87,11 @@ ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = { ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) } ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG,DSA_SIG,DSA_SIG) +IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG) /* Override the default free and new methods */ -static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_NEW_PRE) { *pval = (ASN1_VALUE *)DSA_new(); @@ -145,76 +144,7 @@ ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = { IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) -int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, - unsigned int *siglen, DSA *dsa) - { - DSA_SIG *s; -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) - { - DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif - RAND_seed(dgst, dlen); - s=DSA_do_sign(dgst,dlen,dsa); - if (s == NULL) - { - *siglen=0; - return(0); - } - *siglen=i2d_DSA_SIG(s,&sig); - DSA_SIG_free(s); - return(1); - } - -int DSA_size(const DSA *r) - { - int ret,i; - ASN1_INTEGER bs; - unsigned char buf[4]; /* 4 bytes looks really small. - However, i2d_ASN1_INTEGER() will not look - beyond the first byte, as long as the second - parameter is NULL. */ - - i=BN_num_bits(r->q); - bs.length=(i+7)/8; - bs.data=buf; - bs.type=V_ASN1_INTEGER; - /* If the top bit is set the asn1 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); - return(ret); - } - -/* data has already been hashed (probably with SHA or SHA-1). */ -/* returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int siglen, DSA *dsa) +DSA *DSAparams_dup(DSA *dsa) { - DSA_SIG *s; - int ret=-1; -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) - { - DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif - - s = DSA_SIG_new(); - if (s == NULL) return(ret); - if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; - ret=DSA_do_verify(dgst,dgst_len,s,dsa); -err: - DSA_SIG_free(s); - return(ret); + return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); } - diff --git a/crypto/openssl/crypto/dsa/dsa_err.c b/crypto/openssl/crypto/dsa/dsa_err.c index 872839af94..bba984e92e 100644 --- a/crypto/openssl/crypto/dsa/dsa_err.c +++ b/crypto/openssl/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* crypto/dsa/dsa_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -71,23 +71,26 @@ static ERR_STRING_DATA DSA_str_functs[]= { {ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"}, +{ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, -{ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "DSA_BUILTIN_KEYGEN"}, -{ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, -{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS), "DSA_generate_parameters"}, {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, -{ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"}, +{ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"}, {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, -{ERR_FUNC(DSA_F_DSA_SET_DEFAULT_METHOD), "DSA_set_default_method"}, -{ERR_FUNC(DSA_F_DSA_SET_METHOD), "DSA_set_method"}, +{ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "DSA_PRIV_DECODE"}, +{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"}, +{ERR_FUNC(DSA_F_DSA_PUB_DECODE), "DSA_PUB_DECODE"}, +{ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "DSA_PUB_ENCODE"}, {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"}, {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"}, {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"}, {ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"}, {ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"}, +{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"}, +{ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "PKEY_DSA_CTRL"}, +{ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "PKEY_DSA_KEYGEN"}, {ERR_FUNC(DSA_F_SIG_CB), "SIG_CB"}, {0,NULL} }; @@ -95,12 +98,15 @@ static ERR_STRING_DATA DSA_str_functs[]= static ERR_STRING_DATA DSA_str_reasons[]= { {ERR_REASON(DSA_R_BAD_Q_VALUE) ,"bad q value"}, +{ERR_REASON(DSA_R_BN_DECODE_ERROR) ,"bn decode error"}, +{ERR_REASON(DSA_R_BN_ERROR) ,"bn error"}, {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, -{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, +{ERR_REASON(DSA_R_DECODE_ERROR) ,"decode error"}, +{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, {ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, -{ERR_REASON(DSA_R_NON_FIPS_METHOD) ,"non fips method"}, -{ERR_REASON(DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, +{ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"}, +{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/dsa/dsa_gen.c b/crypto/openssl/crypto/dsa/dsa_gen.c index 6f1728e3cf..0fcd25f8b0 100644 --- a/crypto/openssl/crypto/dsa/dsa_gen.c +++ b/crypto/openssl/crypto/dsa/dsa_gen.c @@ -74,69 +74,88 @@ #ifndef OPENSSL_NO_SHA #include -#include #include "cryptlib.h" #include #include -#include #include #include - -#ifndef OPENSSL_FIPS - -static int dsa_builtin_paramgen(DSA *ret, int bits, - unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); +#include "dsa_locl.h" int DSA_generate_parameters_ex(DSA *ret, int bits, - unsigned char *seed_in, int seed_len, + const unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { if(ret->meth->dsa_paramgen) return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, counter_ret, h_ret, cb); - return dsa_builtin_paramgen(ret, bits, seed_in, seed_len, - counter_ret, h_ret, cb); + else + { + const EVP_MD *evpmd; + size_t qbits = bits >= 2048 ? 256 : 160; + + if (bits >= 2048) + { + qbits = 256; + evpmd = EVP_sha256(); + } + else + { + qbits = 160; + evpmd = EVP_sha1(); + } + + return dsa_builtin_paramgen(ret, bits, qbits, evpmd, + seed_in, seed_len, counter_ret, h_ret, cb); + } } -static int dsa_builtin_paramgen(DSA *ret, int bits, - unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=0; - unsigned char seed[SHA_DIGEST_LENGTH]; - unsigned char md[SHA_DIGEST_LENGTH]; - unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH]; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH]; BIGNUM *r0,*W,*X,*c,*test; BIGNUM *g=NULL,*q=NULL,*p=NULL; BN_MONT_CTX *mont=NULL; - int k,n=0,i,b,m=0; + int i, k,n=0,b,m=0, qsize = qbits >> 3; int counter=0; int r=0; BN_CTX *ctx=NULL; unsigned int h=2; - if (bits < 512) bits=512; - bits=(bits+63)/64*64; + if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && + qsize != SHA256_DIGEST_LENGTH) + /* invalid q size */ + return 0; + + if (evpmd == NULL) + /* use SHA1 as default */ + evpmd = EVP_sha1(); + + if (bits < 512) + bits = 512; + + 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 < 20)) - seed_in = NULL; /* seed buffer too small -- ignore */ - if (seed_len > 20) - seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, - * but our internal buffers are restricted to 160 bits*/ - if ((seed_in != NULL) && (seed_len == 20)) - { - memcpy(seed,seed_in,seed_len); - /* set seed_in to NULL to avoid it being copied back */ - seed_in = NULL; - } - - if ((ctx=BN_CTX_new()) == NULL) goto err; + 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) + memcpy(seed, seed_in, seed_len); + + if ((ctx=BN_CTX_new()) == NULL) + goto err; - if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + if ((mont=BN_MONT_CTX_new()) == NULL) + goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); @@ -163,7 +182,7 @@ static int dsa_builtin_paramgen(DSA *ret, int bits, if (!seed_len) { - RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH); + RAND_pseudo_bytes(seed, qsize); seed_is_random = 1; } else @@ -171,25 +190,27 @@ static int dsa_builtin_paramgen(DSA *ret, int bits, seed_is_random = 0; seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ } - memcpy(buf,seed,SHA_DIGEST_LENGTH); - memcpy(buf2,seed,SHA_DIGEST_LENGTH); + memcpy(buf , seed, qsize); + memcpy(buf2, seed, qsize); /* precompute "SEED + 1" for step 7: */ - for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) + for (i = qsize-1; i >= 0; i--) { buf[i]++; - if (buf[i] != 0) break; + if (buf[i] != 0) + break; } /* step 2 */ - EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); - EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL); - for (i=0; i= 0; i--) + for (i = qsize-1; i >= 0; i--) { buf[i]++; - if (buf[i] != 0) break; + if (buf[i] != 0) + break; } - EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); + EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL); /* step 8 */ - if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) + if (!BN_bin2bn(md, qsize, r0)) goto err; - if (!BN_lshift(r0,r0,160*k)) goto err; + if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err; if (!BN_add(W,W,r0)) goto err; } @@ -309,7 +331,6 @@ err: ok=0; goto err; } - if (seed_in != NULL) memcpy(seed_in,seed,20); if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; } @@ -322,4 +343,3 @@ err: return ok; } #endif -#endif diff --git a/crypto/openssl/crypto/dsa/dsa_key.c b/crypto/openssl/crypto/dsa/dsa_key.c index 5e39124230..c4aa86bc6d 100644 --- a/crypto/openssl/crypto/dsa/dsa_key.c +++ b/crypto/openssl/crypto/dsa/dsa_key.c @@ -64,8 +64,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int dsa_builtin_keygen(DSA *dsa); int DSA_generate_key(DSA *dsa) @@ -128,5 +126,3 @@ err: return(ok); } #endif - -#endif diff --git a/crypto/openssl/crypto/dsa/dsa_lib.c b/crypto/openssl/crypto/dsa/dsa_lib.c index 85556d12d6..e9b75902db 100644 --- a/crypto/openssl/crypto/dsa/dsa_lib.c +++ b/crypto/openssl/crypto/dsa/dsa_lib.c @@ -76,14 +76,6 @@ static const DSA_METHOD *default_DSA_method = NULL; void DSA_set_default_method(const DSA_METHOD *meth) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD)) - { - DSAerr(DSA_F_DSA_SET_DEFAULT_METHOD, DSA_R_NON_FIPS_METHOD); - return; - } -#endif - default_DSA_method = meth; } @@ -104,13 +96,6 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) /* NB: The caller is specifically setting a method, so it's not up to us * to deal with which ENGINE it comes from. */ const DSA_METHOD *mtmp; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD)) - { - DSAerr(DSA_F_DSA_SET_METHOD, DSA_R_NON_FIPS_METHOD); - return 0; - } -#endif mtmp = dsa->meth; if (mtmp->finish) mtmp->finish(dsa); #ifndef OPENSSL_NO_ENGINE @@ -162,18 +147,6 @@ DSA *DSA_new_method(ENGINE *engine) } } #endif -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)) - { - DSAerr(DSA_F_DSA_NEW_METHOD, DSA_R_NON_FIPS_METHOD); -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - OPENSSL_free(ret); - return NULL; - } -#endif ret->pad=0; ret->version=0; @@ -190,7 +163,7 @@ DSA *DSA_new_method(ENGINE *engine) ret->method_mont_p=NULL; ret->references=1; - ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; + ret->flags=ret->meth->flags; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { @@ -260,6 +233,28 @@ int DSA_up_ref(DSA *r) return ((i > 1) ? 1 : 0); } +int DSA_size(const DSA *r) + { + int ret,i; + ASN1_INTEGER bs; + unsigned char buf[4]; /* 4 bytes looks really small. + However, i2d_ASN1_INTEGER() will not look + beyond the first byte, as long as the second + parameter is NULL. */ + + i=BN_num_bits(r->q); + bs.length=(i+7)/8; + bs.data=buf; + bs.type=V_ASN1_INTEGER; + /* If the top bit is set the asn1 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); + return(ret); + } + int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { diff --git a/crypto/openssl/crypto/o_time.h b/crypto/openssl/crypto/dsa/dsa_locl.h similarity index 82% copy from crypto/openssl/crypto/o_time.h copy to crypto/openssl/crypto/dsa/dsa_locl.h index e66044626d..2b8cfee3db 100644 --- a/crypto/openssl/crypto/o_time.h +++ b/crypto/openssl/crypto/dsa/dsa_locl.h @@ -1,9 +1,5 @@ -/* crypto/o_time.h -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2001. - */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * 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 @@ -20,12 +16,12 @@ * 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/)" + * 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. + * 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 @@ -34,7 +30,7 @@ * 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/)" + * 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 @@ -56,11 +52,8 @@ * */ -#ifndef HEADER_O_TIME_H -#define HEADER_O_TIME_H - -#include - -struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +#include -#endif +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); diff --git a/crypto/openssl/crypto/dsa/dsa_ossl.c b/crypto/openssl/crypto/dsa/dsa_ossl.c index 412cf1d88b..4fead07e80 100644 --- a/crypto/openssl/crypto/dsa/dsa_ossl.c +++ b/crypto/openssl/crypto/dsa/dsa_ossl.c @@ -61,16 +61,15 @@ #include #include "cryptlib.h" #include +#include #include #include #include -#ifndef OPENSSL_FIPS - static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, - DSA *dsa); + DSA *dsa); static int dsa_init(DSA *dsa); static int dsa_finish(DSA *dsa); @@ -135,7 +134,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) BIGNUM m; BIGNUM xr; BN_CTX *ctx=NULL; - int i,reason=ERR_R_BN_LIB; + int reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; BN_init(&m); @@ -150,8 +149,9 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) s=BN_new(); if (s == NULL) goto err; - i=BN_num_bytes(dsa->q); /* should be 20 */ - if ((dlen > i) || (dlen > 50)) + /* reject a excessive digest length (currently at most + * dsa-with-SHA256 is supported) */ + if (dlen > SHA256_DIGEST_LENGTH) { reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; goto err; @@ -172,7 +172,14 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) dsa->r=NULL; } - if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; + + if (dlen > BN_num_bytes(dsa->q)) + /* if the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see + * fips 186-3, 4.2 */ + dlen = BN_num_bytes(dsa->q); + if (BN_bin2bn(dgst,dlen,&m) == NULL) + goto err; /* Compute s = inv(k) (m + xr) mod q */ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ @@ -283,30 +290,31 @@ err: if (!ret) { DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); - if (kinv != NULL) BN_clear_free(kinv); - if (r != NULL) BN_clear_free(r); + if (r != NULL) + BN_clear_free(r); } if (ctx_in == NULL) BN_CTX_free(ctx); - if (kinv != NULL) BN_clear_free(kinv); BN_clear_free(&k); BN_clear_free(&kq); return(ret); } static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, - DSA *dsa) + DSA *dsa) { BN_CTX *ctx; BIGNUM u1,u2,t1; BN_MONT_CTX *mont=NULL; - int ret = -1; + int ret = -1, i; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); return -1; } - if (BN_num_bits(dsa->q) != 160) + i = BN_num_bits(dsa->q); + /* fips 186-3 allows only different sizes for q */ + if (i != 160 && i != 224 && i != 256) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE); return -1; @@ -318,6 +326,14 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, return -1; } + /* reject a excessive digest length (currently at most + * dsa-with-SHA256 is supported) */ + if (dgst_len > SHA256_DIGEST_LENGTH) + { + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return -1; + } + BN_init(&u1); BN_init(&u2); BN_init(&t1); @@ -342,6 +358,11 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; /* save M in u1 */ + if (dgst_len > (i >> 3)) + /* if the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see + * fips 186-3, 4.2 */ + dgst_len = (i >> 3); if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; /* u1 = M * w mod q */ @@ -393,4 +414,3 @@ static int dsa_finish(DSA *dsa) return(1); } -#endif diff --git a/crypto/openssl/crypto/dsa/dsa_pmeth.c b/crypto/openssl/crypto/dsa/dsa_pmeth.c new file mode 100644 index 0000000000..4ce91e20c6 --- /dev/null +++ b/crypto/openssl/crypto/dsa/dsa_pmeth.c @@ -0,0 +1,315 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include "evp_locl.h" +#include "dsa_locl.h" + +/* DSA pkey context structure */ + +typedef struct + { + /* Parameter gen parameters */ + int nbits; /* size of p in bits (default: 1024) */ + int qbits; /* size of q in bits (default: 160) */ + const EVP_MD *pmd; /* MD for parameter generation */ + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ + const EVP_MD *md; /* MD for the signature */ + } DSA_PKEY_CTX; + +static int pkey_dsa_init(EVP_PKEY_CTX *ctx) + { + DSA_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX)); + if (!dctx) + return 0; + dctx->nbits = 1024; + dctx->qbits = 160; + dctx->pmd = NULL; + dctx->md = NULL; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; + } + +static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + DSA_PKEY_CTX *dctx, *sctx; + if (!pkey_dsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + dctx->qbits = sctx->qbits; + dctx->pmd = sctx->pmd; + dctx->md = sctx->md; + return 1; + } + +static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) + { + DSA_PKEY_CTX *dctx = ctx->data; + if (dctx) + OPENSSL_free(dctx); + } + +static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) + { + int ret, type; + unsigned int sltmp; + DSA_PKEY_CTX *dctx = ctx->data; + DSA *dsa = ctx->pkey->pkey.dsa; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa); + + if (ret <= 0) + return ret; + *siglen = sltmp; + return 1; + } + +static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) + { + int ret, type; + DSA_PKEY_CTX *dctx = ctx->data; + DSA *dsa = ctx->pkey->pkey.dsa; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa); + + return ret; + } + +static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + DSA_PKEY_CTX *dctx = ctx->data; + switch (type) + { + case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: + if (p1 < 256) + return -2; + dctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: + if (p1 != 160 && p1 != 224 && p1 && p1 != 256) + return -2; + dctx->qbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256) + { + DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_dsa && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256) + { + DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + DSAerr(DSA_F_PKEY_DSA_CTRL, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + default: + return -2; + + } + } + +static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!strcmp(type, "dsa_paramgen_bits")) + { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); + } + if (!strcmp(type, "dsa_paramgen_q_bits")) + { + int qbits = atoi(value); + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL); + } + if (!strcmp(type, "dsa_paramgen_md")) + { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, + (void *)EVP_get_digestbyname(value)); + } + return -2; + } + +static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + DSA *dsa = NULL; + DSA_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (ctx->pkey_gencb) + { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } + else + pcb = NULL; + dsa = DSA_new(); + if (!dsa) + return 0; + ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, + NULL, 0, NULL, NULL, pcb); + if (ret) + EVP_PKEY_assign_DSA(pkey, dsa); + else + DSA_free(dsa); + return ret; + } + +static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + DSA *dsa = NULL; + if (ctx->pkey == NULL) + { + DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); + return 0; + } + dsa = DSA_new(); + if (!dsa) + return 0; + EVP_PKEY_assign_DSA(pkey, dsa); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DSA_generate_key(pkey->pkey.dsa); + } + +const EVP_PKEY_METHOD dsa_pkey_meth = + { + EVP_PKEY_DSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_dsa_init, + pkey_dsa_copy, + pkey_dsa_cleanup, + + 0, + pkey_dsa_paramgen, + + 0, + pkey_dsa_keygen, + + 0, + pkey_dsa_sign, + + 0, + pkey_dsa_verify, + + 0,0, + + 0,0,0,0, + + 0,0, + + 0,0, + + 0,0, + + pkey_dsa_ctrl, + pkey_dsa_ctrl_str + + + }; diff --git a/crypto/openssl/crypto/pem/pem_x509.c b/crypto/openssl/crypto/dsa/dsa_prn.c similarity index 69% copy from crypto/openssl/crypto/pem/pem_x509.c copy to crypto/openssl/crypto/dsa/dsa_prn.c index 3f709f13e6..6f29f5e240 100644 --- a/crypto/openssl/crypto/pem/pem_x509.c +++ b/crypto/openssl/crypto/dsa/dsa_prn.c @@ -1,9 +1,9 @@ -/* pem_x509.c */ +/* crypto/dsa/dsa_prn.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. + * project 2006. */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -57,13 +57,65 @@ */ #include -#undef SSLEAY_MACROS #include "cryptlib.h" -#include #include -#include -#include -#include +#include -IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) +#ifndef OPENSSL_NO_FP_API +int DSA_print_fp(FILE *fp, const DSA *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=DSA_print(b,x,off); + BIO_free(b); + return(ret); + } + +int DSAparams_print_fp(FILE *fp, const DSA *x) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=DSAparams_print(b, x); + BIO_free(b); + return(ret); + } +#endif + +int DSA_print(BIO *bp, const DSA *x, int off) + { + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; + } + +int DSAparams_print(BIO *bp, const DSA *x) + { + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) + return 0; + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + EVP_PKEY_free(pk); + return ret; + } diff --git a/crypto/openssl/crypto/dsa/dsa_sign.c b/crypto/openssl/crypto/dsa/dsa_sign.c index 4cfbbe57a8..17555e5892 100644 --- a/crypto/openssl/crypto/dsa/dsa_sign.c +++ b/crypto/openssl/crypto/dsa/dsa_sign.c @@ -58,38 +58,33 @@ /* Original version from Steven Schoch */ -#include #include "cryptlib.h" -#include #include #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) - { - DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return NULL; - } -#endif return dsa->meth->dsa_do_sign(dgst, dlen, dsa); } -int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, + unsigned int *siglen, DSA *dsa) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + DSA_SIG *s; + RAND_seed(dgst, dlen); + s=DSA_do_sign(dgst,dlen,dsa); + if (s == NULL) { - DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; + *siglen=0; + return(0); } -#endif + *siglen=i2d_DSA_SIG(s,&sig); + DSA_SIG_free(s); + return(1); + } + +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) + { return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); } diff --git a/crypto/openssl/crypto/dsa/dsa_utl.c b/crypto/openssl/crypto/dsa/dsa_utl.c deleted file mode 100644 index 24c021d120..0000000000 --- a/crypto/openssl/crypto/dsa/dsa_utl.c +++ /dev/null @@ -1,95 +0,0 @@ -/* crypto/dsa/dsa_lib.c */ -/* 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.] - */ - -/* Original version from Steven Schoch */ - -#include -#include "cryptlib.h" -#include -#include -#include -#ifndef OPENSSL_NO_ENGINE -#include -#endif -#ifndef OPENSSL_NO_DH -#include -#endif - -DSA_SIG *DSA_SIG_new(void) - { - DSA_SIG *sig; - sig = OPENSSL_malloc(sizeof(DSA_SIG)); - if (!sig) - return NULL; - sig->r = NULL; - sig->s = NULL; - return sig; - } - -void DSA_SIG_free(DSA_SIG *sig) - { - if (sig) - { - if (sig->r) - BN_free(sig->r); - if (sig->s) - BN_free(sig->s); - OPENSSL_free(sig); - } - } - diff --git a/crypto/openssl/crypto/dsa/dsa_vrf.c b/crypto/openssl/crypto/dsa/dsa_vrf.c index c75e423048..226a75ff3f 100644 --- a/crypto/openssl/crypto/dsa/dsa_vrf.c +++ b/crypto/openssl/crypto/dsa/dsa_vrf.c @@ -58,27 +58,32 @@ /* Original version from Steven Schoch */ -#include #include "cryptlib.h" -#include #include -#include -#include -#ifdef OPENSSL_FIPS -#include -#endif - -#include int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) - { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); } + +/* data has already been hashed (probably with SHA or SHA-1). */ +/* returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) + { + DSA_SIG *s; + int ret=-1; + + s = DSA_SIG_new(); + if (s == NULL) return(ret); + if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; + ret=DSA_do_verify(dgst,dgst_len,s,dsa); +err: + DSA_SIG_free(s); + return(ret); + } diff --git a/crypto/openssl/crypto/dso/dso.h b/crypto/openssl/crypto/dso/dso.h index 3e51913a72..839f2e0617 100644 --- a/crypto/openssl/crypto/dso/dso.h +++ b/crypto/openssl/crypto/dso/dso.h @@ -170,6 +170,11 @@ typedef struct dso_meth_st /* [De]Initialisation handlers. */ int (*init)(DSO *dso); int (*finish)(DSO *dso); + + /* Return pathname of the module containing location */ + int (*pathbyaddr)(void *addr,char *path,int sz); + /* Perform global symbol lookup, i.e. among *all* modules */ + void *(*globallookup)(const char *symname); } DSO_METHOD; /**********************************************************************/ @@ -183,7 +188,7 @@ struct dso_st * for use in the dso_bind handler. All in all, let each * method control its own destiny. "Handles" and such go in * a STACK. */ - STACK *meth_data; + STACK_OF(void) *meth_data; int references; int flags; /* For use by applications etc ... use this for your bits'n'pieces, @@ -296,6 +301,30 @@ DSO_METHOD *DSO_METHOD_win32(void); /* If VMS is defined, use shared images. If not, return NULL. */ DSO_METHOD *DSO_METHOD_vms(void); +/* This function writes null-terminated pathname of DSO module + * containing 'addr' into 'sz' large caller-provided 'path' and + * returns the number of characters [including trailing zero] + * written to it. If 'sz' is 0 or negative, 'path' is ignored and + * required amount of charachers [including trailing zero] to + * accomodate pathname is returned. If 'addr' is NULL, then + * pathname of cryptolib itself is returned. Negative or zero + * return value denotes error. + */ +int DSO_pathbyaddr(void *addr,char *path,int sz); + +/* This function should be used with caution! It looks up symbols in + * *all* loaded modules and if module gets unloaded by somebody else + * attempt to dereference the pointer is doomed to have fatal + * consequences. Primary usage for this function is to probe *core* + * system functionality, e.g. check if getnameinfo(3) is available + * at run-time without bothering about OS-specific details such as + * libc.so.versioning or where does it actually reside: in libc + * itself or libsocket. */ +void *DSO_global_lookup(const char *name); + +/* If BeOS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_beos(void); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -305,6 +334,11 @@ void ERR_load_DSO_strings(void); /* Error codes for the DSO functions. */ /* Function codes. */ +#define DSO_F_BEOS_BIND_FUNC 144 +#define DSO_F_BEOS_BIND_VAR 145 +#define DSO_F_BEOS_LOAD 146 +#define DSO_F_BEOS_NAME_CONVERTER 147 +#define DSO_F_BEOS_UNLOAD 148 #define DSO_F_DLFCN_BIND_FUNC 100 #define DSO_F_DLFCN_BIND_VAR 101 #define DSO_F_DLFCN_LOAD 102 @@ -324,22 +358,29 @@ void ERR_load_DSO_strings(void); #define DSO_F_DSO_FREE 111 #define DSO_F_DSO_GET_FILENAME 127 #define DSO_F_DSO_GET_LOADED_FILENAME 128 +#define DSO_F_DSO_GLOBAL_LOOKUP 139 #define DSO_F_DSO_LOAD 112 #define DSO_F_DSO_MERGE 132 #define DSO_F_DSO_NEW_METHOD 113 +#define DSO_F_DSO_PATHBYADDR 140 #define DSO_F_DSO_SET_FILENAME 129 #define DSO_F_DSO_SET_NAME_CONVERTER 122 #define DSO_F_DSO_UP_REF 114 +#define DSO_F_GLOBAL_LOOKUP_FUNC 138 +#define DSO_F_PATHBYADDR 137 #define DSO_F_VMS_BIND_SYM 115 #define DSO_F_VMS_LOAD 116 #define DSO_F_VMS_MERGER 133 #define DSO_F_VMS_UNLOAD 117 #define DSO_F_WIN32_BIND_FUNC 118 #define DSO_F_WIN32_BIND_VAR 119 +#define DSO_F_WIN32_GLOBALLOOKUP 142 +#define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143 #define DSO_F_WIN32_JOINER 135 #define DSO_F_WIN32_LOAD 120 #define DSO_F_WIN32_MERGER 134 #define DSO_F_WIN32_NAME_CONVERTER 125 +#define DSO_F_WIN32_PATHBYADDR 141 #define DSO_F_WIN32_SPLITTER 136 #define DSO_F_WIN32_UNLOAD 121 diff --git a/crypto/openssl/crypto/dso/dso_dl.c b/crypto/openssl/crypto/dso/dso_dl.c index 417abb6ea9..fc4236bd9a 100644 --- a/crypto/openssl/crypto/dso/dso_dl.c +++ b/crypto/openssl/crypto/dso/dso_dl.c @@ -85,6 +85,8 @@ static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); #endif static char *dl_name_converter(DSO *dso, const char *filename); static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2); +static int dl_pathbyaddr(void *addr,char *path,int sz); +static void *dl_globallookup(const char *name); static DSO_METHOD dso_meth_dl = { "OpenSSL 'dl' shared library method", @@ -101,7 +103,9 @@ static DSO_METHOD dso_meth_dl = { dl_name_converter, dl_merger, NULL, /* init */ - NULL /* finish */ + NULL, /* finish */ + dl_pathbyaddr, + dl_globallookup }; DSO_METHOD *DSO_METHOD_dl(void) @@ -350,4 +354,40 @@ static char *dl_name_converter(DSO *dso, const char *filename) return(translated); } +static int dl_pathbyaddr(void *addr,char *path,int sz) + { + struct shl_descriptor inf; + int i,len; + + if (addr == NULL) + { + union { int(*f)(void*,char*,int); void *p; } t = + { dl_pathbyaddr }; + addr = t.p; + } + + for (i=-1;shl_get_r(i,&inf)==0;i++) + { + if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) || + ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) + { + len = (int)strlen(inf.filename); + if (sz <= 0) return len+1; + if (len >= sz) len=sz-1; + memcpy(path,inf.filename,len); + path[len++] = 0; + return len; + } + } + + return -1; + } + +static void *dl_globallookup(const char *name) + { + void *ret; + shl_t h = NULL; + + return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret; + } #endif /* DSO_DL */ diff --git a/crypto/openssl/crypto/dso/dso_dlfcn.c b/crypto/openssl/crypto/dso/dso_dlfcn.c index d91e821af6..14bd322fb8 100644 --- a/crypto/openssl/crypto/dso/dso_dlfcn.c +++ b/crypto/openssl/crypto/dso/dso_dlfcn.c @@ -56,6 +56,16 @@ * */ +/* We need to do this early, because stdio.h includes the header files + that handle _GNU_SOURCE and other similar macros. Defining it later + is simply too late, because those headers are protected from re- + inclusion. */ +#ifdef __linux +# ifndef _GNU_SOURCE +# define _GNU_SOURCE /* make sure dladdr is declared */ +# endif +#endif + #include #include "cryptlib.h" #include @@ -68,7 +78,16 @@ DSO_METHOD *DSO_METHOD_dlfcn(void) #else #ifdef HAVE_DLFCN_H -#include +# ifdef __osf__ +# define __EXTENSIONS__ +# endif +# include +# define HAVE_DLINFO 1 +# if defined(_AIX) || defined(__CYGWIN__) || \ + defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ + (defined(__OpenBSD__) && !defined(RTLD_SELF)) +# undef HAVE_DLINFO +# endif #endif /* Part of the hack in "dlfcn_load" ... */ @@ -87,6 +106,8 @@ static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); static char *dlfcn_name_converter(DSO *dso, const char *filename); static char *dlfcn_merger(DSO *dso, const char *filespec1, const char *filespec2); +static int dlfcn_pathbyaddr(void *addr,char *path,int sz); +static void *dlfcn_globallookup(const char *name); static DSO_METHOD dso_meth_dlfcn = { "OpenSSL 'dlfcn' shared library method", @@ -103,7 +124,9 @@ static DSO_METHOD dso_meth_dlfcn = { dlfcn_name_converter, dlfcn_merger, NULL, /* init */ - NULL /* finish */ + NULL, /* finish */ + dlfcn_pathbyaddr, + dlfcn_globallookup }; DSO_METHOD *DSO_METHOD_dlfcn(void) @@ -163,7 +186,7 @@ static int dlfcn_load(DSO *dso) ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); goto err; } - if(!sk_push(dso->meth_data, (char *)ptr)) + if(!sk_void_push(dso->meth_data, (char *)ptr)) { DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); goto err; @@ -188,15 +211,15 @@ static int dlfcn_unload(DSO *dso) DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); return(0); } - if(sk_num(dso->meth_data) < 1) + if(sk_void_num(dso->meth_data) < 1) return(1); - ptr = (void *)sk_pop(dso->meth_data); + ptr = sk_void_pop(dso->meth_data); if(ptr == NULL) { DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE); /* Should push the value back onto the stack in * case of a retry. */ - sk_push(dso->meth_data, (char *)ptr); + sk_void_push(dso->meth_data, ptr); return(0); } /* For now I'm not aware of any errors associated with dlclose() */ @@ -213,12 +236,12 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname) DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); return(NULL); } - if(sk_num(dso->meth_data) < 1) + if(sk_void_num(dso->meth_data) < 1) { DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR); return(NULL); } - ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); if(ptr == NULL) { DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE); @@ -247,12 +270,12 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); return(NULL); } - if(sk_num(dso->meth_data) < 1) + if(sk_void_num(dso->meth_data) < 1) { DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR); return(NULL); } - ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); if(ptr == NULL) { DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); @@ -281,13 +304,12 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, } /* If the first file specification is a rooted path, it rules. same goes if the second file specification is missing. */ - if (!filespec2 || filespec1[0] == '/') + if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { merged = OPENSSL_malloc(strlen(filespec1) + 1); if(!merged) { - DSOerr(DSO_F_DLFCN_MERGER, - ERR_R_MALLOC_FAILURE); + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); return(NULL); } strcpy(merged, filespec1); @@ -313,7 +335,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, { int spec2len, len; - spec2len = (filespec2 ? strlen(filespec2) : 0); + spec2len = strlen(filespec2); len = spec2len + (filespec1 ? strlen(filespec1) : 0); if(filespec2 && filespec2[spec2len - 1] == '/') @@ -378,4 +400,83 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename) return(translated); } +#ifdef __sgi +/* +This is a quote from IRIX manual for dladdr(3c): + + does not contain a prototype for dladdr or definition of + Dl_info. The #include in the SYNOPSIS line is traditional, + but contains no dladdr prototype and no IRIX library contains an + implementation. Write your own declaration based on the code below. + + The following code is dependent on internal interfaces that are not + part of the IRIX compatibility guarantee; however, there is no future + intention to change this interface, so on a practical level, the code + below is safe to use on IRIX. +*/ +#include +#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR +#define _RLD_INTERFACE_DLFCN_H_DLADDR +typedef struct Dl_info { + const char * dli_fname; + void * dli_fbase; + const char * dli_sname; + void * dli_saddr; + int dli_version; + int dli_reserved1; + long dli_reserved[4]; +} Dl_info; +#else +typedef struct Dl_info Dl_info; +#endif +#define _RLD_DLADDR 14 + +static int dladdr(void *address, Dl_info *dl) +{ + void *v; + v = _rld_new_interface(_RLD_DLADDR,address,dl); + return (int)v; +} +#endif /* __sgi */ + +static int dlfcn_pathbyaddr(void *addr,char *path,int sz) + { +#ifdef HAVE_DLINFO + Dl_info dli; + int len; + + if (addr == NULL) + { + union { int(*f)(void*,char*,int); void *p; } t = + { dlfcn_pathbyaddr }; + addr = t.p; + } + + if (dladdr(addr,&dli)) + { + len = (int)strlen(dli.dli_fname); + if (sz <= 0) return len+1; + if (len >= sz) len=sz-1; + memcpy(path,dli.dli_fname,len); + path[len++]=0; + return len; + } + + ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror()); +#endif + return -1; + } + +static void *dlfcn_globallookup(const char *name) + { + void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY); + + if (handle) + { + ret = dlsym(handle,name); + dlclose(handle); + } + + return ret; + } #endif /* DSO_DLFCN */ diff --git a/crypto/openssl/crypto/dso/dso_err.c b/crypto/openssl/crypto/dso/dso_err.c index a8b0a210de..2bb07c2514 100644 --- a/crypto/openssl/crypto/dso/dso_err.c +++ b/crypto/openssl/crypto/dso/dso_err.c @@ -1,6 +1,6 @@ /* crypto/dso/dso_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -70,6 +70,11 @@ static ERR_STRING_DATA DSO_str_functs[]= { +{ERR_FUNC(DSO_F_BEOS_BIND_FUNC), "BEOS_BIND_FUNC"}, +{ERR_FUNC(DSO_F_BEOS_BIND_VAR), "BEOS_BIND_VAR"}, +{ERR_FUNC(DSO_F_BEOS_LOAD), "BEOS_LOAD"}, +{ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER), "BEOS_NAME_CONVERTER"}, +{ERR_FUNC(DSO_F_BEOS_UNLOAD), "BEOS_UNLOAD"}, {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"}, {ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"}, {ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"}, @@ -89,22 +94,29 @@ static ERR_STRING_DATA DSO_str_functs[]= {ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"}, {ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"}, {ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"}, +{ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"}, {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"}, {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"}, {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"}, +{ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"}, {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"}, {ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"}, {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"}, +{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "GLOBAL_LOOKUP_FUNC"}, +{ERR_FUNC(DSO_F_PATHBYADDR), "PATHBYADDR"}, {ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"}, {ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"}, {ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"}, {ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"}, {ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"}, {ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"}, +{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "WIN32_GLOBALLOOKUP"}, +{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC), "WIN32_GLOBALLOOKUP_FUNC"}, {ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"}, {ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"}, {ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"}, {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"}, +{ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "WIN32_PATHBYADDR"}, {ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"}, {ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, {0,NULL} diff --git a/crypto/openssl/crypto/dso/dso_lib.c b/crypto/openssl/crypto/dso/dso_lib.c index 49bdd71309..8a15b794ab 100644 --- a/crypto/openssl/crypto/dso/dso_lib.c +++ b/crypto/openssl/crypto/dso/dso_lib.c @@ -107,7 +107,7 @@ DSO *DSO_new_method(DSO_METHOD *meth) return(NULL); } memset(ret, 0, sizeof(DSO)); - ret->meth_data = sk_new_null(); + ret->meth_data = sk_void_new_null(); if(ret->meth_data == NULL) { /* sk_new doesn't generate any errors so we do */ @@ -163,7 +163,7 @@ int DSO_free(DSO *dso) return(0); } - sk_free(dso->meth_data); + sk_void_free(dso->meth_data); if(dso->filename != NULL) OPENSSL_free(dso->filename); if(dso->loaded_filename != NULL) @@ -399,13 +399,6 @@ char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2) DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER); return(NULL); } - if(filespec1 == NULL) - filespec1 = dso->filename; - if(filespec1 == NULL) - { - DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILE_SPECIFICATION); - return(NULL); - } if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { if(dso->merger != NULL) @@ -464,3 +457,27 @@ const char *DSO_get_loaded_filename(DSO *dso) } return(dso->loaded_filename); } + +int DSO_pathbyaddr(void *addr,char *path,int sz) + { + DSO_METHOD *meth = default_DSO_meth; + if (meth == NULL) meth = DSO_METHOD_openssl(); + if (meth->pathbyaddr == NULL) + { + DSOerr(DSO_F_DSO_PATHBYADDR,DSO_R_UNSUPPORTED); + return -1; + } + return (*meth->pathbyaddr)(addr,path,sz); + } + +void *DSO_global_lookup(const char *name) + { + DSO_METHOD *meth = default_DSO_meth; + if (meth == NULL) meth = DSO_METHOD_openssl(); + if (meth->globallookup == NULL) + { + DSOerr(DSO_F_DSO_GLOBAL_LOOKUP,DSO_R_UNSUPPORTED); + return NULL; + } + return (*meth->globallookup)(name); + } diff --git a/crypto/openssl/crypto/dso/dso_null.c b/crypto/openssl/crypto/dso/dso_null.c index 4972984651..49d842d1f5 100644 --- a/crypto/openssl/crypto/dso/dso_null.c +++ b/crypto/openssl/crypto/dso/dso_null.c @@ -78,7 +78,9 @@ static DSO_METHOD dso_meth_null = { NULL, /* dso_name_converter */ NULL, /* dso_merger */ NULL, /* init */ - NULL /* finish */ + NULL, /* finish */ + NULL, /* pathbyaddr */ + NULL /* globallookup */ }; DSO_METHOD *DSO_METHOD_null(void) diff --git a/crypto/openssl/crypto/dso/dso_openssl.c b/crypto/openssl/crypto/dso/dso_openssl.c index a4395ebffe..b17e8e8e9e 100644 --- a/crypto/openssl/crypto/dso/dso_openssl.c +++ b/crypto/openssl/crypto/dso/dso_openssl.c @@ -74,6 +74,8 @@ DSO_METHOD *DSO_METHOD_openssl(void) return(DSO_METHOD_win32()); #elif defined(DSO_VMS) return(DSO_METHOD_vms()); +#elif defined(DSO_BEOS) + return(DSO_METHOD_beos()); #else return(DSO_METHOD_null()); #endif diff --git a/crypto/openssl/crypto/dyn_lck.c b/crypto/openssl/crypto/dyn_lck.c deleted file mode 100644 index 7f82c41264..0000000000 --- a/crypto/openssl/crypto/dyn_lck.c +++ /dev/null @@ -1,428 +0,0 @@ -/* crypto/cryptlib.c */ -/* ==================================================================== - * Copyright (c) 1998-2003 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.] - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include "cryptlib.h" -#include - -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) -static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ -#endif - -DECLARE_STACK_OF(CRYPTO_dynlock) -IMPLEMENT_STACK_OF(CRYPTO_dynlock) - -/* real #defines in crypto.h, keep these upto date */ -static const char* const lock_names[CRYPTO_NUM_LOCKS] = - { - "<>", - "err", - "ex_data", - "x509", - "x509_info", - "x509_pkey", - "x509_crl", - "x509_req", - "dsa", - "rsa", - "evp_pkey", - "x509_store", - "ssl_ctx", - "ssl_cert", - "ssl_session", - "ssl_sess_cert", - "ssl", - "ssl_method", - "rand", - "rand2", - "debug_malloc", - "BIO", - "gethostbyname", - "getservbyname", - "readdir", - "RSA_blinding", - "dh", - "debug_malloc2", - "dso", - "dynlock", - "engine", - "ui", - "ecdsa", - "ec", - "ecdh", - "bn", - "ec_pre_comp", - "store", - "comp", -#ifndef OPENSSL_FIPS -# if CRYPTO_NUM_LOCKS != 39 -# error "Inconsistency between crypto.h and cryptlib.c" -# endif -#else - "fips", - "fips2", -# if CRYPTO_NUM_LOCKS != 41 -# error "Inconsistency between crypto.h and cryptlib.c" -# endif -#endif - }; - -/* This is for applications to allocate new type names in the non-dynamic - array of lock names. These are numbered with positive numbers. */ -static STACK *app_locks=NULL; - -/* For applications that want a more dynamic way of handling threads, the - following stack is used. These are externally numbered with negative - numbers. */ -static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; - - -static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) - (const char *file,int line)=NULL; -static void (MS_FAR *dynlock_lock_callback)(int mode, - struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL; -static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, - const char *file,int line)=NULL; - -int CRYPTO_get_new_lockid(char *name) - { - char *str; - int i; - -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) - /* A hack to make Visual C++ 5.0 work correctly when linking as - * a DLL using /MT. Without this, the application cannot use - * and floating point printf's. - * It also seems to be needed for Visual C 1.5 (win16) */ - SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; -#endif - - if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - if ((str=BUF_strdup(name)) == NULL) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - i=sk_push(app_locks,str); - if (!i) - OPENSSL_free(str); - else - i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ - return(i); - } - -int CRYPTO_get_new_dynlockid(void) - { - int i = 0; - CRYPTO_dynlock *pointer = NULL; - - if (dynlock_create_callback == NULL) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); - return(0); - } - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - if ((dyn_locks == NULL) - && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL)) - { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock)); - if (pointer == NULL) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - pointer->references = 1; - pointer->data = dynlock_create_callback(__FILE__,__LINE__); - if (pointer->data == NULL) - { - OPENSSL_free(pointer); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - /* First, try to find an existing empty slot */ - i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); - /* If there was none, push, thereby creating a new one */ - if (i == -1) - /* Since sk_push() returns the number of items on the - stack, not the location of the pushed item, we need - to transform the returned number into a position, - by decreasing it. */ - i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1; - else - /* If we found a place with a NULL pointer, put our pointer - in it. */ - (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (i == -1) - { - dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); - OPENSSL_free(pointer); - } - else - i += 1; /* to avoid 0 */ - return -i; - } - -void CRYPTO_destroy_dynlockid(int i) - { - CRYPTO_dynlock *pointer = NULL; - if (i) - i = -i-1; - if (dynlock_destroy_callback == NULL) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) - { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - return; - } - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer != NULL) - { - --pointer->references; -#ifdef REF_CHECK - if (pointer->references < 0) - { - fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n"); - abort(); - } - else -#endif - if (pointer->references <= 0) - { - (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); - } - else - pointer = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) - { - dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); - OPENSSL_free(pointer); - } - } - -struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) - { - CRYPTO_dynlock *pointer = NULL; - if (i) - i = -i-1; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer) - pointer->references++; - - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) - return pointer->data; - return NULL; - } - -struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) - (const char *file,int line) - { - return(dynlock_create_callback); - } - -void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, - struct CRYPTO_dynlock_value *l, const char *file,int line) - { - return(dynlock_lock_callback); - } - -void (*CRYPTO_get_dynlock_destroy_callback(void)) - (struct CRYPTO_dynlock_value *l, const char *file,int line) - { - return(dynlock_destroy_callback); - } - -void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) - (const char *file, int line)) - { - dynlock_create_callback=func; - } - -static void do_dynlock(int mode, int type, const char *file, int line) - { - if (dynlock_lock_callback != NULL) - { - struct CRYPTO_dynlock_value *pointer - = CRYPTO_get_dynlock_value(type); - - OPENSSL_assert(pointer != NULL); - - dynlock_lock_callback(mode, pointer, file, line); - - CRYPTO_destroy_dynlockid(type); - } - } - -void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, - struct CRYPTO_dynlock_value *l, const char *file, int line)) - { - /* Set callback so CRYPTO_lock() can now handle dynamic locks. - * This is OK because at this point and application shouldn't be using - * OpenSSL from multiple threads because it is setting up the locking - * callbacks. - */ - static int done = 0; - if (!done) - { - int_CRYPTO_set_do_dynlock_callback(do_dynlock); - done = 1; - } - - dynlock_lock_callback=func; - } - -void CRYPTO_set_dynlock_destroy_callback(void (*func) - (struct CRYPTO_dynlock_value *l, const char *file, int line)) - { - dynlock_destroy_callback=func; - } - -const char *CRYPTO_get_lock_name(int type) - { - if (type < 0) - return("dynamic"); - else if (type < CRYPTO_NUM_LOCKS) - return(lock_names[type]); - else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks)) - return("ERROR"); - else - return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS)); - } - diff --git a/crypto/openssl/crypto/ec/ec.h b/crypto/openssl/crypto/ec/ec.h index 8bc2a235b1..ee7078130c 100644 --- a/crypto/openssl/crypto/ec/ec.h +++ b/crypto/openssl/crypto/ec/ec.h @@ -2,8 +2,12 @@ /* * Originally written by Bodo Moeller for the OpenSSL project. */ +/** + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions + * \author Originally written by Bodo Moeller for the OpenSSL project + */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * 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 @@ -92,15 +96,21 @@ extern "C" { # endif #endif - + #ifndef OPENSSL_ECC_MAX_FIELD_BITS # define OPENSSL_ECC_MAX_FIELD_BITS 661 #endif +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ typedef enum { - /* values as defined in X9.62 (ECDSA) and elsewhere */ + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x02 */ POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ POINT_CONVERSION_HYBRID = 6 } point_conversion_form_t; @@ -121,37 +131,129 @@ typedef struct ec_group_st typedef struct ec_point_st EC_POINT; -/* EC_METHODs for curves over GF(p). - * EC_GFp_simple_method provides the basis for the optimized methods. +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object */ const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ const EC_METHOD *EC_GFp_nist_method(void); -/* EC_METHOD for curves over GF(2^m). + +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object */ const EC_METHOD *EC_GF2m_simple_method(void); -EC_GROUP *EC_GROUP_new(const EC_METHOD *); -void EC_GROUP_free(EC_GROUP *); -void EC_GROUP_clear_free(EC_GROUP *); -int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *); -EC_GROUP *EC_GROUP_dup(const EC_GROUP *); +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); -int EC_METHOD_get_field_type(const EC_METHOD *); +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); -int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); -const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); -int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); -int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); -void EC_GROUP_set_curve_name(EC_GROUP *, int nid); -int EC_GROUP_get_curve_name(const EC_GROUP *); +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); -void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag); -int EC_GROUP_get_asn1_flag(const EC_GROUP *); +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and it's order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t); point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); @@ -160,36 +262,114 @@ unsigned char *EC_GROUP_get0_seed(const EC_GROUP *); size_t EC_GROUP_get_seed_len(const EC_GROUP *); size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); -int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); -int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); -int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); -int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM with the prime number + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM for the prime number + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM for the polynomial defining the underlying field + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); -/* returns the number of bits needed to represent a field element */ -int EC_GROUP_get_degree(const EC_GROUP *); +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); -/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */ +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); -/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the - * elliptic curve is not zero, 0 otherwise */ -int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *); -/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */ -int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *); +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if both groups are equal and 1 otherwise + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); /* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() * after choosing an appropriate EC_METHOD */ -EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); -EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); -/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure - * specified by a curve name (in form of a NID) */ +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ EC_GROUP *EC_GROUP_new_by_curve_name(int nid); -/* handling of internal curves */ + + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + typedef struct { int nid; const char *comment; } EC_builtin_curve; + /* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number * of all available curves or zero if a error occurred. * In case r ist not zero nitems EC_builtin_curve structures @@ -197,39 +377,168 @@ typedef struct { size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); -/* EC_POINT functions */ +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); -EC_POINT *EC_POINT_new(const EC_GROUP *); -void EC_POINT_free(EC_POINT *); -void EC_POINT_clear_free(EC_POINT *); -int EC_POINT_copy(EC_POINT *, const EC_POINT *); -EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *); +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); -const EC_METHOD *EC_POINT_method_of(const EC_POINT *); - -int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *); -int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); -int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, - BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); -int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, const BIGNUM *y, BN_CTX *); -int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, - BIGNUM *x, BIGNUM *y, BN_CTX *); -int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, BN_CTX *); - -int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, const BIGNUM *y, BN_CTX *); -int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *, - BIGNUM *x, BIGNUM *y, BN_CTX *); -int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, BN_CTX *); - -size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *); -int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, - const unsigned char *buf, size_t len, BN_CTX *); +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); + +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); /* other interfaces to point2oct/oct2point: */ BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, @@ -241,29 +550,105 @@ char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, EC_POINT *, BN_CTX *); -int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); -int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); -int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if point if on the curve and 0 otherwise + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 0 if both points are equal and a value != 0 otherwise + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); +/** Computes r = generator * n sum_{i=0}^num p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number futher summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); -int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *); -int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *); - -/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */ -int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *); -/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */ -int EC_GROUP_have_precompute_mult(const EC_GROUP *); +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); -/* ASN1 stuff */ +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ /* EC_GROUP_get_basis_type() returns the NID of the basis type * used to represent the field elements */ @@ -293,28 +678,96 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); #endif -/* the EC_KEY stuff */ + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + typedef struct ec_key_st EC_KEY; /* some values for the encoding_flag */ #define EC_PKEY_NO_PARAMETERS 0x001 #define EC_PKEY_NO_PUBKEY 0x002 +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ EC_KEY *EC_KEY_new(void); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ EC_KEY *EC_KEY_new_by_curve_name(int nid); -void EC_KEY_free(EC_KEY *); -EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *); -EC_KEY *EC_KEY_dup(const EC_KEY *); - -int EC_KEY_up_ref(EC_KEY *); - -const EC_GROUP *EC_KEY_get0_group(const EC_KEY *); -int EC_KEY_set_group(EC_KEY *, const EC_GROUP *); -const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *); -int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *); -const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *); -int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *); -unsigned EC_KEY_get_enc_flags(const EC_KEY *); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); void EC_KEY_set_enc_flags(EC_KEY *, unsigned int); point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); @@ -325,31 +778,126 @@ void EC_KEY_insert_key_method_data(EC_KEY *, void *data, void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); /* wrapper functions for the underlying EC_GROUP object */ void EC_KEY_set_asn1_flag(EC_KEY *, int); -int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx); - -/* EC_KEY_generate_key() creates a ec private (public) key */ -int EC_KEY_generate_key(EC_KEY *); -/* EC_KEY_check_key() */ -int EC_KEY_check_key(const EC_KEY *); - -/* de- and encoding functions for SEC1 ECPrivateKey */ -EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len); -int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out); -/* de- and encoding functions for EC parameters */ -EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len); -int i2d_ECParameters(EC_KEY *a, unsigned char **out); -/* de- and encoding functions for EC public key - * (octet string, not DER -- hence 'o2i' and 'i2o') */ -EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len); -int i2o_ECPublicKey(EC_KEY *a, unsigned char **out); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec paramters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); #ifndef OPENSSL_NO_BIO -int ECParameters_print(BIO *bp, const EC_KEY *x); -int EC_KEY_print(BIO *bp, const EC_KEY *x, int off); +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + #endif #ifndef OPENSSL_NO_FP_API -int ECParameters_print_fp(FILE *fp, const EC_KEY *x); -int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off); +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + #endif #define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) @@ -362,6 +910,13 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off); # endif #endif +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + + +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -375,6 +930,14 @@ void ERR_load_EC_strings(void); #define EC_F_D2I_ECPARAMETERS 144 #define EC_F_D2I_ECPKPARAMETERS 145 #define EC_F_D2I_ECPRIVATEKEY 146 +#define EC_F_DO_EC_KEY_PRINT 221 +#define EC_F_ECKEY_PARAM2TYPE 223 +#define EC_F_ECKEY_PARAM_DECODE 212 +#define EC_F_ECKEY_PRIV_DECODE 213 +#define EC_F_ECKEY_PRIV_ENCODE 214 +#define EC_F_ECKEY_PUB_DECODE 215 +#define EC_F_ECKEY_PUB_ENCODE 216 +#define EC_F_ECKEY_TYPE2PARAM 220 #define EC_F_ECPARAMETERS_PRINT 147 #define EC_F_ECPARAMETERS_PRINT_FP 148 #define EC_F_ECPKPARAMETERS_PRINT 149 @@ -448,7 +1011,6 @@ void ERR_load_EC_strings(void); #define EC_F_EC_KEY_PRINT 180 #define EC_F_EC_KEY_PRINT_FP 181 #define EC_F_EC_POINTS_MAKE_AFFINE 136 -#define EC_F_EC_POINTS_MUL 138 #define EC_F_EC_POINT_ADD 112 #define EC_F_EC_POINT_CMP 113 #define EC_F_EC_POINT_COPY 114 @@ -479,21 +1041,31 @@ void ERR_load_EC_strings(void); #define EC_F_I2D_ECPRIVATEKEY 192 #define EC_F_I2O_ECPUBLICKEY 151 #define EC_F_O2I_ECPUBLICKEY 152 +#define EC_F_OLD_EC_PRIV_DECODE 222 +#define EC_F_PKEY_EC_CTRL 197 +#define EC_F_PKEY_EC_CTRL_STR 198 +#define EC_F_PKEY_EC_DERIVE 217 +#define EC_F_PKEY_EC_KEYGEN 199 +#define EC_F_PKEY_EC_PARAMGEN 219 +#define EC_F_PKEY_EC_SIGN 218 /* Reason codes. */ #define EC_R_ASN1_ERROR 115 #define EC_R_ASN1_UNKNOWN_FIELD 116 #define EC_R_BUFFER_TOO_SMALL 100 #define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +#define EC_R_DECODE_ERROR 142 #define EC_R_DISCRIMINANT_IS_ZERO 118 #define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 -#define EC_R_FIELD_TOO_LARGE 138 +#define EC_R_FIELD_TOO_LARGE 143 #define EC_R_GROUP2PKPARAMETERS_FAILURE 120 #define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 #define EC_R_INCOMPATIBLE_OBJECTS 101 #define EC_R_INVALID_ARGUMENT 112 #define EC_R_INVALID_COMPRESSED_POINT 110 #define EC_R_INVALID_COMPRESSION_BIT 109 +#define EC_R_INVALID_CURVE 141 +#define EC_R_INVALID_DIGEST_TYPE 138 #define EC_R_INVALID_ENCODING 102 #define EC_R_INVALID_FIELD 103 #define EC_R_INVALID_FORM 104 @@ -501,6 +1073,7 @@ void ERR_load_EC_strings(void); #define EC_R_INVALID_PENTANOMIAL_BASIS 132 #define EC_R_INVALID_PRIVATE_KEY 123 #define EC_R_INVALID_TRINOMIAL_BASIS 137 +#define EC_R_KEYS_NOT_SET 140 #define EC_R_MISSING_PARAMETERS 124 #define EC_R_MISSING_PRIVATE_KEY 125 #define EC_R_NOT_A_NIST_PRIME 135 @@ -508,6 +1081,7 @@ void ERR_load_EC_strings(void); #define EC_R_NOT_IMPLEMENTED 126 #define EC_R_NOT_INITIALIZED 111 #define EC_R_NO_FIELD_MOD 133 +#define EC_R_NO_PARAMETERS_SET 139 #define EC_R_PASSED_NULL_PARAMETER 134 #define EC_R_PKPARAMETERS2GROUP_FAILURE 127 #define EC_R_POINT_AT_INFINITY 106 diff --git a/crypto/openssl/crypto/ec/ec2_mult.c b/crypto/openssl/crypto/ec/ec2_mult.c index ff368fd7d7..ab631a50a2 100644 --- a/crypto/openssl/crypto/ec/ec2_mult.c +++ b/crypto/openssl/crypto/ec/ec2_mult.c @@ -76,7 +76,7 @@ * coordinates. * Uses algorithm Mdouble in appendix of * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). * modified to not require precomputation of c=b^{2^{m-1}}. */ static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx) @@ -107,8 +107,8 @@ static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx /* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery * projective coordinates. * Uses algorithm Madd in appendix of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). */ static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx) @@ -140,8 +140,8 @@ static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM /* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) * using Montgomery point multiplication algorithm Mxy() in appendix of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). * Returns: * 0 on error * 1 if return value should be the point at infinity @@ -209,15 +209,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIG /* Computes scalar*point and stores the result in r. * point can not equal r. * Uses algorithm 2P of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) { BIGNUM *x1, *x2, *z1, *z2; - int ret = 0, i, j; - BN_ULONG mask; + int ret = 0, i; + BN_ULONG mask,word; if (r == point) { @@ -251,22 +251,24 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */ /* find top most bit and go one past it */ - i = scalar->top - 1; j = BN_BITS2 - 1; + i = scalar->top - 1; mask = BN_TBIT; - while (!(scalar->d[i] & mask)) { mask >>= 1; j--; } - mask >>= 1; j--; + word = scalar->d[i]; + while (!(word & mask)) mask >>= 1; + mask >>= 1; /* if top most bit was at word break, go to next word */ if (!mask) { - i--; j = BN_BITS2 - 1; + i--; mask = BN_TBIT; } for (; i >= 0; i--) { - for (; j >= 0; j--) + word = scalar->d[i]; + while (mask) { - if (scalar->d[i] & mask) + if (word & mask) { if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; @@ -278,7 +280,6 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, } mask >>= 1; } - j = BN_BITS2 - 1; mask = BN_TBIT; } diff --git a/crypto/openssl/crypto/ec/ec2_smpl.c b/crypto/openssl/crypto/ec/ec2_smpl.c index 522d036ca1..cf357b462a 100644 --- a/crypto/openssl/crypto/ec/ec2_smpl.c +++ b/crypto/openssl/crypto/ec/ec2_smpl.c @@ -14,7 +14,7 @@ * */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * 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 @@ -157,6 +157,7 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) group->poly[2] = 0; group->poly[3] = 0; group->poly[4] = 0; + group->poly[5] = -1; } @@ -174,10 +175,9 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) dest->poly[2] = src->poly[2]; dest->poly[3] = src->poly[3]; dest->poly[4] = src->poly[4]; - if(bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) - return 0; - if(bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) - return 0; + dest->poly[5] = src->poly[5]; + if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0; + if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0; for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0; return 1; @@ -192,7 +192,7 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group, /* group->field */ if (!BN_copy(&group->field, p)) goto err; - i = BN_GF2m_poly2arr(&group->field, group->poly, 5); + i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1; if ((i != 5) && (i != 3)) { ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); @@ -406,18 +406,94 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_ } -/* Include patented algorithms. */ -#include "ec2_smpt.c" +/* Calculates and sets the affine coordinates of an EC_POINT from the given + * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. + * Note that the simple implementation only uses affine coordinates. + * + * The method is from the following publication: + * + * Harper, Menezes, Vanstone: + * "Public-Key Cryptosystems with Very Small Key Lengths", + * EUROCRYPT '92, Springer-Verlag LNCS 658, + * published February 1993 + * + * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe + * the same method, but claim no priority date earlier than July 29, 1994 + * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). + */ +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x_, int y_bit, BN_CTX *ctx) + { + BN_CTX *new_ctx = NULL; + BIGNUM *tmp, *x, *y, *z; + int ret = 0, z0; + + /* clear error queue */ + ERR_clear_error(); + + if (ctx == NULL) + { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + y_bit = (y_bit != 0) ? 1 : 0; + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + if (z == NULL) goto err; + + if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err; + if (BN_is_zero(x)) + { + if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err; + } + else + { + if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err; + if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err; + if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err; + if (!BN_GF2m_add(tmp, x, tmp)) goto err; + if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) + { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) + { + ERR_clear_error(); + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); + } + else + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); + goto err; + } + z0 = (BN_is_odd(z)) ? 1 : 0; + if (!group->meth->field_mul(group, y, x, z, ctx)) goto err; + if (z0 != y_bit) + { + if (!BN_GF2m_add(y, y, x)) goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; + } /* Converts an EC_POINT to an octet string. * If buf is NULL, the encoded length will be returned. * If the length len of buf is smaller than required an error will be returned. - * - * The point compression section of this function is patented by Certicom Corp. - * under US Patent 6,141,420. Point compression is disabled by default and can - * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at - * Configure-time. */ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx) @@ -428,14 +504,6 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po BIGNUM *x, *y, *yxi; size_t field_len, i, skip; -#ifndef OPENSSL_EC_BIN_PT_COMP - if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID)) - { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED); - goto err; - } -#endif - if ((form != POINT_CONVERSION_COMPRESSED) && (form != POINT_CONVERSION_UNCOMPRESSED) && (form != POINT_CONVERSION_HYBRID)) @@ -490,13 +558,11 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; buf[0] = form; -#ifdef OPENSSL_EC_BIN_PT_COMP if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) { if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; if (BN_is_odd(yxi)) buf[0]++; } -#endif i = 1; diff --git a/crypto/openssl/crypto/ec/ec2_smpt.c b/crypto/openssl/crypto/ec/ec2_smpt.c deleted file mode 100644 index 72a8d57051..0000000000 --- a/crypto/openssl/crypto/ec/ec2_smpt.c +++ /dev/null @@ -1,141 +0,0 @@ -/* crypto/ec/ec2_smpt.c */ -/* This code was originally written by Douglas Stebila - * for the OpenSSL project. - */ -/* ==================================================================== - * 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). - * - */ - - -/* Calaculates and sets the affine coordinates of an EC_POINT from the given - * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. - * Note that the simple implementation only uses affine coordinates. - * - * This algorithm is patented by Certicom Corp. under US Patent 6,141,420 - * (for licensing information, contact licensing@certicom.com). - * This function is disabled by default and can be enabled by defining the - * preprocessor macro OPENSSL_EC_BIN_PT_COMP at Configure-time. - */ -int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, - const BIGNUM *x_, int y_bit, BN_CTX *ctx) - { -#ifndef OPENSSL_EC_BIN_PT_COMP - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_DISABLED); - return 0; -#else - BN_CTX *new_ctx = NULL; - BIGNUM *tmp, *x, *y, *z; - int ret = 0, z0; - - /* clear error queue */ - ERR_clear_error(); - - if (ctx == NULL) - { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - y_bit = (y_bit != 0) ? 1 : 0; - - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - z = BN_CTX_get(ctx); - if (z == NULL) goto err; - - if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err; - if (BN_is_zero(x)) - { - if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err; - } - else - { - if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err; - if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err; - if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err; - if (!BN_GF2m_add(tmp, x, tmp)) goto err; - if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) - { - unsigned long err = ERR_peek_last_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) - { - ERR_clear_error(); - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); - } - else - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); - goto err; - } - z0 = (BN_is_odd(z)) ? 1 : 0; - if (!group->meth->field_mul(group, y, x, z, ctx)) goto err; - if (z0 != y_bit) - { - if (!BN_GF2m_add(y, y, x)) goto err; - } - } - - if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -#endif - } diff --git a/crypto/openssl/crypto/ec/ec_ameth.c b/crypto/openssl/crypto/ec/ec_ameth.c new file mode 100644 index 0000000000..c00f7d746c --- /dev/null +++ b/crypto/openssl/crypto/ec/ec_ameth.c @@ -0,0 +1,659 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_CMS +#include +#endif +#include "asn1_locl.h" + +static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) + { + const EC_GROUP *group; + int nid; + if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) + { + ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); + return 0; + } + if (EC_GROUP_get_asn1_flag(group) + && (nid = EC_GROUP_get_curve_name(group))) + /* we have a 'named curve' => just set the OID */ + { + *ppval = OBJ_nid2obj(nid); + *pptype = V_ASN1_OBJECT; + } + else /* explicit parameters */ + { + ASN1_STRING *pstr = NULL; + pstr = ASN1_STRING_new(); + if (!pstr) + return 0; + pstr->length = i2d_ECParameters(ec_key, &pstr->data); + if (pstr->length < 0) + { + ASN1_STRING_free(pstr); + ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); + return 0; + } + *ppval = pstr; + *pptype = V_ASN1_SEQUENCE; + } + return 1; + } + +static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) + { + EC_KEY *ec_key = pkey->pkey.ec; + void *pval = NULL; + int ptype; + unsigned char *penc = NULL, *p; + int penclen; + + if (!eckey_param2type(&ptype, &pval, ec_key)) + { + ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); + return 0; + } + penclen = i2o_ECPublicKey(ec_key, NULL); + if (penclen <= 0) + goto err; + penc = OPENSSL_malloc(penclen); + if (!penc) + goto err; + p = penc; + penclen = i2o_ECPublicKey(ec_key, &p); + if (penclen <= 0) + goto err; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), + ptype, pval, penc, penclen)) + return 1; + err: + if (ptype == V_ASN1_OBJECT) + ASN1_OBJECT_free(pval); + else + ASN1_STRING_free(pval); + if (penc) + OPENSSL_free(penc); + return 0; + } + +static EC_KEY *eckey_type2param(int ptype, void *pval) + { + EC_KEY *eckey = NULL; + if (ptype == V_ASN1_SEQUENCE) + { + ASN1_STRING *pstr = pval; + const unsigned char *pm = NULL; + int pmlen; + pm = pstr->data; + pmlen = pstr->length; + if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) + { + ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); + goto ecerr; + } + } + else if (ptype == V_ASN1_OBJECT) + { + ASN1_OBJECT *poid = pval; + EC_GROUP *group; + + /* type == V_ASN1_OBJECT => the parameters are given + * by an asn1 OID + */ + if ((eckey = EC_KEY_new()) == NULL) + { + ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); + goto ecerr; + } + group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); + if (group == NULL) + goto ecerr; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(eckey, group) == 0) + goto ecerr; + EC_GROUP_free(group); + } + else + { + ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); + goto ecerr; + } + + return eckey; + + ecerr: + if (eckey) + EC_KEY_free(eckey); + return NULL; + } + +static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) + { + const unsigned char *p = NULL; + void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + eckey = eckey_type2param(ptype, pval); + + if (!eckey) + { + ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); + return 0; + } + + /* We have parameters now set public key */ + if (!o2i_ECPublicKey(&eckey, &p, pklen)) + { + ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); + goto ecerr; + } + + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; + } + +static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + int r; + const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), + *pb = EC_KEY_get0_public_key(b->pkey.ec); + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) + return 1; + if (r == 1) + return 0; + return -2; + } + +static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) + { + const unsigned char *p = NULL; + void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + eckey = eckey_type2param(ptype, pval); + + if (!eckey) + goto ecliberr; + + /* We have parameters now set private key */ + if (!d2i_ECPrivateKey(&eckey, &p, pklen)) + { + ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); + goto ecerr; + } + + /* calculate public key (if necessary) */ + if (EC_KEY_get0_public_key(eckey) == NULL) + { + const BIGNUM *priv_key; + const EC_GROUP *group; + EC_POINT *pub_key; + /* the public key was not included in the SEC1 private + * key => calculate the public key */ + group = EC_KEY_get0_group(eckey); + pub_key = EC_POINT_new(group); + if (pub_key == NULL) + { + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) + { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, 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); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + if (EC_KEY_set_public_key(eckey, pub_key) == 0) + { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + EC_POINT_free(pub_key); + } + + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecliberr: + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; + } + +static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + EC_KEY *ec_key; + unsigned char *ep, *p; + int eplen, ptype; + void *pval; + unsigned int tmp_flags, old_flags; + + ec_key = pkey->pkey.ec; + + if (!eckey_param2type(&ptype, &pval, ec_key)) + { + ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); + return 0; + } + + /* set the private key */ + + /* do not include the parameters in the SEC1 private key + * see PKCS#11 12.11 */ + old_flags = EC_KEY_get_enc_flags(ec_key); + tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; + EC_KEY_set_enc_flags(ec_key, tmp_flags); + eplen = i2d_ECPrivateKey(ec_key, NULL); + if (!eplen) + { + EC_KEY_set_enc_flags(ec_key, old_flags); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); + return 0; + } + ep = (unsigned char *) OPENSSL_malloc(eplen); + if (!ep) + { + EC_KEY_set_enc_flags(ec_key, old_flags); + ECerr(EC_F_ECKEY_PRIV_ENCODE, 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); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); + } + /* restore old encoding flags */ + EC_KEY_set_enc_flags(ec_key, old_flags); + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, + ptype, pval, ep, eplen)) + return 0; + + return 1; +} + +static int int_ec_size(const EVP_PKEY *pkey) + { + return ECDSA_size(pkey->pkey.ec); + } + +static int ec_bits(const EVP_PKEY *pkey) + { + BIGNUM *order = BN_new(); + const EC_GROUP *group; + int ret; + + if (!order) + { + ERR_clear_error(); + return 0; + } + group = EC_KEY_get0_group(pkey->pkey.ec); + if (!EC_GROUP_get_order(group, order, NULL)) + { + ERR_clear_error(); + return 0; + } + + ret = BN_num_bits(order); + BN_free(order); + return ret; + } + +static int ec_missing_parameters(const EVP_PKEY *pkey) + { + if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) + return 1; + return 0; + } + +static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) + { + EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); + if (group == NULL) + return 0; + if (EC_KEY_set_group(to->pkey.ec, group) == 0) + return 0; + EC_GROUP_free(group); + return 1; + } + +static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) + { + const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), + *group_b = EC_KEY_get0_group(b->pkey.ec); + if (EC_GROUP_cmp(group_a, group_b, NULL)) + return 0; + else + return 1; + } + +static void int_ec_free(EVP_PKEY *pkey) + { + EC_KEY_free(pkey->pkey.ec); + } + +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) + { + unsigned char *buffer=NULL; + const char *ecstr; + size_t buf_len=0, i; + int ret=0, reason=ERR_R_BIO_LIB; + BIGNUM *pub_key=NULL, *order=NULL; + BN_CTX *ctx=NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) + { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (ktype > 0) + { + public_key = EC_KEY_get0_public_key(x); + if ((pub_key = EC_POINT_point2bn(group, public_key, + EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) + { + reason = ERR_R_EC_LIB; + goto err; + } + if (pub_key) + buf_len = (size_t)BN_num_bytes(pub_key); + } + + if (ktype == 2) + { + priv_key = EC_KEY_get0_private_key(x); + if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) + buf_len = i; + } + else + priv_key = NULL; + + if (ktype > 0) + { + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + } + if (ktype == 2) + ecstr = "Private-Key"; + else if (ktype == 1) + ecstr = "Public-Key"; + else + ecstr = "ECDSA-Parameters"; + + if (!BIO_indent(bp, off, 128)) + goto err; + if ((order = BN_new()) == NULL) + goto err; + if (!EC_GROUP_get_order(group, order, NULL)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, + BN_num_bits(order)) <= 0) goto err; + + if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, + buffer, off)) + goto err; + if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, + buffer, off)) + goto err; + if (!ECPKParameters_print(bp, group, off)) + goto err; + ret=1; +err: + if (!ret) + ECerr(EC_F_DO_EC_KEY_PRINT, reason); + if (pub_key) + BN_free(pub_key); + if (order) + BN_free(order); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return(ret); + } + +static int eckey_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + EC_KEY *eckey; + if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) + { + ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + } + +static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_ECParameters(pkey->pkey.ec, pder); + } + +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); + } + +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); + } + + +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); + } + +static int old_ec_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + EC_KEY *ec; + if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen))) + { + ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; + } + +static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_ECPrivateKey(pkey->pkey.ec, pder); + } + +static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) + { + switch (op) + { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, + &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 2; + + default: + return -2; + + } + + } + +const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = + { + EVP_PKEY_EC, + EVP_PKEY_EC, + 0, + "EC", + "OpenSSL EC algorithm", + + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, + eckey_pub_print, + + eckey_priv_decode, + eckey_priv_encode, + eckey_priv_print, + + int_ec_size, + ec_bits, + + eckey_param_decode, + eckey_param_encode, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + eckey_param_print, + + int_ec_free, + ec_pkey_ctrl, + old_ec_priv_decode, + old_ec_priv_encode + }; diff --git a/crypto/openssl/crypto/ec/ec_curve.c b/crypto/openssl/crypto/ec/ec_curve.c index beac20969b..23274e4031 100644 --- a/crypto/openssl/crypto/ec/ec_curve.c +++ b/crypto/openssl/crypto/ec/ec_curve.c @@ -73,926 +73,1690 @@ #include #include -typedef struct ec_curve_data_st { - int field_type; /* either NID_X9_62_prime_field or +typedef struct { + int field_type, /* either NID_X9_62_prime_field or * NID_X9_62_characteristic_two_field */ - const char *p; /* either a prime number or a polynomial */ - const char *a; - const char *b; - const char *x; /* the x coordinate of the generator */ - const char *y; /* the y coordinate of the generator */ - const char *order; /* the order of the group generated by the - * generator */ - const BN_ULONG cofactor;/* the cofactor */ - const unsigned char *seed;/* the seed (optional) */ - size_t seed_len; - const char *comment; /* a short description of the curve */ + seed_len, + param_len; + unsigned int cofactor; /* promoted to BN_ULONG */ } EC_CURVE_DATA; /* the nist prime curves */ -static const unsigned char _EC_NIST_PRIME_192_SEED[] = { - 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, - 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5}; -static const EC_CURVE_DATA _EC_NIST_PRIME_192 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - "07192b95ffc8da78631011ed6b24cdd573f977a11e794811", - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",1, - _EC_NIST_PRIME_192_SEED, 20, - "NIST/X9.62/SECG curve over a 192 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } + _EC_NIST_PRIME_192 = { + { NID_X9_62_prime_field,20,24,1 }, + { 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, /* seed */ + 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5, + + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFC, + 0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7, /* b */ + 0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC, + 0xC1,0x46,0xB9,0xB1, + 0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF, /* x */ + 0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD, + 0x82,0xFF,0x10,0x12, + 0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10, /* y */ + 0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1, + 0x1e,0x79,0x48,0x11, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1, + 0xB4,0xD2,0x28,0x31 } }; -static const unsigned char _EC_NIST_PRIME_224_SEED[] = { - 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, - 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5}; -static const EC_CURVE_DATA _EC_NIST_PRIME_224 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",1, - _EC_NIST_PRIME_224_SEED, 20, - "NIST/SECG curve over a 224 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; } + _EC_NIST_PRIME_224 = { + { NID_X9_62_prime_field,20,28,1 }, + { 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, /* seed */ + 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5, + + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */ + 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA, + 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4, + 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */ + 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22, + 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21, + 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */ + 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64, + 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E, + 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D } }; -static const unsigned char _EC_NIST_PRIME_384_SEED[] = { - 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, - 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73}; -static const EC_CURVE_DATA _EC_NIST_PRIME_384 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" - "FFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" - "FFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC6563" - "98D8A2ED19D2A85C8EDD3EC2AEF", - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F" - "25DBF55296C3A545E3872760AB7", - "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b" - "1ce1d7e819d7a431d7c90ea0e5f", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0" - "DB248B0A77AECEC196ACCC52973",1, - _EC_NIST_PRIME_384_SEED, 20, - "NIST/SECG curve over a 384 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; } + _EC_NIST_PRIME_384 = { + { NID_X9_62_prime_field,20,48,1 }, + { 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, /* seed */ + 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73, + + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC, + 0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E, /* b */ + 0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E, + 0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13, + 0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D, + 0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF, + 0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1, /* x */ + 0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62, + 0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54, + 0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C, + 0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7, + 0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e, /* y */ + 0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd, + 0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0, + 0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d, + 0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37, + 0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A, + 0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 } }; -static const unsigned char _EC_NIST_PRIME_521_SEED[] = { - 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, - 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA}; -static const EC_CURVE_DATA _EC_NIST_PRIME_521 = { - NID_X9_62_prime_field, - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156" - "193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14" - "B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c9" - "7ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51" - "868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",1, - _EC_NIST_PRIME_521_SEED, 20, - "NIST/SECG curve over a 521 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; } + _EC_NIST_PRIME_521 = { + { NID_X9_62_prime_field,20,66,1 }, + { 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, /* seed */ + 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA, + + 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, + 0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F, /* b */ + 0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA, + 0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91, + 0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E, + 0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07, + 0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45, + 0x1F,0xD4,0x6B,0x50,0x3F,0x00, + 0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD, /* x */ + 0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64, + 0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60, + 0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7, + 0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE, + 0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E, + 0x7E,0x31,0xC2,0xE5,0xBD,0x66, + 0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04, /* y */ + 0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5, + 0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17, + 0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4, + 0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61, + 0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe, + 0x94,0x76,0x9f,0xd1,0x66,0x50, + 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F, + 0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0, + 0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F, + 0xB7,0x1E,0x91,0x38,0x64,0x09 } }; + /* the x9.62 prime curves (minus the nist prime curves) */ -static const unsigned char _EC_X9_62_PRIME_192V2_SEED[] = { - 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, - 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6}; -static const EC_CURVE_DATA _EC_X9_62_PRIME_192V2 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", - "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", - "6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15", - "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",1, - _EC_X9_62_PRIME_192V2_SEED, 20, - "X9.62 curve over a 192 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } + _EC_X9_62_PRIME_192V2 = { + { NID_X9_62_prime_field,20,24,1 }, + { 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, /* seed */ + 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6, + + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFC, + 0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C, /* b */ + 0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2, + 0x16,0x68,0xD9,0x53, + 0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE, /* x */ + 0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69, + 0x6F,0x48,0x03,0x4A, + 0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b, /* y */ + 0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9, + 0x70,0xb2,0xde,0x15, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86, + 0x48,0xD8,0xDD,0x31 } }; -static const unsigned char _EC_X9_62_PRIME_192V3_SEED[] = { - 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, - 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E}; -static const EC_CURVE_DATA _EC_X9_62_PRIME_192V3 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", - "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", - "38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0", - "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",1, - _EC_X9_62_PRIME_192V3_SEED, 20, - "X9.62 curve over a 192 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } + _EC_X9_62_PRIME_192V3 = { + { NID_X9_62_prime_field,20,24,1 }, + { 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, /* seed */ + 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E, + + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFC, + 0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42, /* b */ + 0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25, + 0x6B,0xD5,0x69,0x16, + 0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78, /* x */ + 0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E, + 0x22,0x8F,0x18,0x96, + 0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49, /* y */ + 0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76, + 0x48,0xa9,0x43,0xb0, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94, + 0xF6,0x40,0xEC,0x13 } }; -static const unsigned char _EC_X9_62_PRIME_239V1_SEED[] = { - 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, - 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D}; -static const EC_CURVE_DATA _EC_X9_62_PRIME_239V1 = { - NID_X9_62_prime_field, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", - "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", - "7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",1, - _EC_X9_62_PRIME_239V1_SEED, 20, - "X9.62 curve over a 239 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_X9_62_PRIME_239V1 = { + { NID_X9_62_prime_field,20,30,1 }, + { 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, /* seed */ + 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, + 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, + 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC, + + 0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6, /* b */ + 0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2, + 0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A, + + 0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33, /* x */ + 0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57, + 0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF, + + 0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40, /* y */ + 0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18, + 0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D, + 0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B } }; -static const unsigned char _EC_X9_62_PRIME_239V2_SEED[] = { - 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, - 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16}; -static const EC_CURVE_DATA _EC_X9_62_PRIME_239V2 = { - NID_X9_62_prime_field, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", - "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", - "5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba", - "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",1, - _EC_X9_62_PRIME_239V2_SEED, 20, - "X9.62 curve over a 239 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_X9_62_PRIME_239V2 = { + { NID_X9_62_prime_field,20,30,1 }, + { 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, /* seed */ + 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, + 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, + 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC, + + 0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5, /* b */ + 0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B, + 0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C, + + 0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9, /* x */ + 0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2, + 0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7, + + 0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d, /* y */ + 0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55, + 0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43, + 0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 } }; -static const unsigned char _EC_X9_62_PRIME_239V3_SEED[] = { - 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, - 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF}; -static const EC_CURVE_DATA _EC_X9_62_PRIME_239V3 = { - NID_X9_62_prime_field, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", - "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", - "1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",1, - _EC_X9_62_PRIME_239V3_SEED, 20, - "X9.62 curve over a 239 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_X9_62_PRIME_239V3 = { + { NID_X9_62_prime_field,20,30,1 }, + { 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, /* seed */ + 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, + 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, + 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC, + + 0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4, /* b */ + 0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02, + 0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E, + + 0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00, /* x */ + 0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6, + 0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A, + + 0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d, /* y */ + 0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b, + 0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3, + + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3, + 0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 } }; -static const unsigned char _EC_X9_62_PRIME_256V1_SEED[] = { - 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, - 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90}; -static const EC_CURVE_DATA _EC_X9_62_PRIME_256V1 = { - NID_X9_62_prime_field, - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",1, - _EC_X9_62_PRIME_256V1_SEED, 20, - "X9.62/SECG curve over a 256 bit prime field" + +static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; } + _EC_X9_62_PRIME_256V1 = { + { NID_X9_62_prime_field,20,32,1 }, + { 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, /* seed */ + 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90, + + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFC, + 0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB, /* b */ + 0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0, + 0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2, + 0x60,0x4B, + 0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC, /* x */ + 0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81, + 0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98, + 0xC2,0x96, + 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7, /* y */ + 0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57, + 0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf, + 0x51,0xf5, + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD, + 0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63, + 0x25,0x51 } }; + /* the secg prime curves (minus the nist and x9.62 prime curves) */ -static const unsigned char _EC_SECG_PRIME_112R1_SEED[] = { - 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, - 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1}; -static const EC_CURVE_DATA _EC_SECG_PRIME_112R1 = { - NID_X9_62_prime_field, - "DB7C2ABF62E35E668076BEAD208B", - "DB7C2ABF62E35E668076BEAD2088", - "659EF8BA043916EEDE8911702B22", - "09487239995A5EE76B55F9C2F098", - "a89ce5af8724c0a23e0e0ff77500", - "DB7C2ABF62E35E7628DFAC6561C5",1, - _EC_SECG_PRIME_112R1_SEED, 20, - "SECG/WTLS curve over a 112 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; } + _EC_SECG_PRIME_112R1 = { + { NID_X9_62_prime_field,20,14,1 }, + { 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, /* seed */ + 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1, + + 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */ + 0xBE,0xAD,0x20,0x8B, + 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* a */ + 0xBE,0xAD,0x20,0x88, + 0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89, /* b */ + 0x11,0x70,0x2B,0x22, + 0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55, /* x */ + 0xF9,0xC2,0xF0,0x98, + 0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e, /* y */ + 0x0f,0xf7,0x75,0x00, + 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF, /* order */ + 0xAC,0x65,0x61,0xC5 } }; -static const unsigned char _EC_SECG_PRIME_112R2_SEED[] = { - 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, - 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4}; -static const EC_CURVE_DATA _EC_SECG_PRIME_112R2 = { - NID_X9_62_prime_field, - "DB7C2ABF62E35E668076BEAD208B", - "6127C24C05F38A0AAAF65C0EF02C", - "51DEF1815DB5ED74FCC34C85D709", - "4BA30AB5E892B4E1649DD0928643", - "adcd46f5882e3747def36e956e97", - "36DF0AAFD8B8D7597CA10520D04B",4, - _EC_SECG_PRIME_112R2_SEED, 20, - "SECG curve over a 112 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; } + _EC_SECG_PRIME_112R2 = { + { NID_X9_62_prime_field,20,14,4 }, + { 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, /* seed */ + 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4, + + 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */ + 0xBE,0xAD,0x20,0x8B, + 0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6, /* a */ + 0x5C,0x0E,0xF0,0x2C, + 0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3, /* b */ + 0x4C,0x85,0xD7,0x09, + 0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D, /* x */ + 0xD0,0x92,0x86,0x43, + 0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3, /* y */ + 0x6e,0x95,0x6e,0x97, + 0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1, /* order */ + 0x05,0x20,0xD0,0x4B } }; -static const unsigned char _EC_SECG_PRIME_128R1_SEED[] = { - 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, - 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79}; -static const EC_CURVE_DATA _EC_SECG_PRIME_128R1 = { - NID_X9_62_prime_field, - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", - "E87579C11079F43DD824993C2CEE5ED3", - "161FF7528B899B2D0C28607CA52C5B86", - "cf5ac8395bafeb13c02da292dded7a83", - "FFFFFFFE0000000075A30D1B9038A115",1, - _EC_SECG_PRIME_128R1_SEED, 20, - "SECG curve over a 128 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; } + _EC_SECG_PRIME_128R1 = { + { NID_X9_62_prime_field,20,16,1 }, + { 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */ + 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79, + + 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, + 0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24, /* b */ + 0x99,0x3C,0x2C,0xEE,0x5E,0xD3, + 0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28, /* x */ + 0x60,0x7C,0xA5,0x2C,0x5B,0x86, + 0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d, /* y */ + 0xa2,0x92,0xdd,0xed,0x7a,0x83, + 0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3, /* order */ + 0x0D,0x1B,0x90,0x38,0xA1,0x15 } }; -static const unsigned char _EC_SECG_PRIME_128R2_SEED[] = { - 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, - 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4}; -static const EC_CURVE_DATA _EC_SECG_PRIME_128R2 = { - NID_X9_62_prime_field, - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "D6031998D1B3BBFEBF59CC9BBFF9AEE1", - "5EEEFCA380D02919DC2C6558BB6D8A5D", - "7B6AA5D85E572983E6FB32A7CDEBC140", - "27b6916a894d3aee7106fe805fc34b44", - "3FFFFFFF7FFFFFFFBE0024720613B5A3",4, - _EC_SECG_PRIME_128R2_SEED, 20, - "SECG curve over a 128 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; } + _EC_SECG_PRIME_128R2 = { + { NID_X9_62_prime_field,20,16,4 }, + { 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, /* seed */ + 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4, + + 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59, /* a */ + 0xCC,0x9B,0xBF,0xF9,0xAE,0xE1, + 0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C, /* b */ + 0x65,0x58,0xBB,0x6D,0x8A,0x5D, + 0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB, /* x */ + 0x32,0xA7,0xCD,0xEB,0xC1,0x40, + 0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06, /* y */ + 0xfe,0x80,0x5f,0xc3,0x4b,0x44, + 0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00, /* order */ + 0x24,0x72,0x06,0x13,0xB5,0xA3 } }; -static const EC_CURVE_DATA _EC_SECG_PRIME_160K1 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "0", - "7", - "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", - "938cf935318fdced6bc28286531733c3f03c4fee", - "0100000000000000000001B8FA16DFAB9ACA16B6B3",1, - NULL, 0, - "SECG curve over a 160 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } + _EC_SECG_PRIME_160K1 = { + { NID_X9_62_prime_field,0,21,1 }, + { /* no seed */ + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC, + 0x73, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07, + 0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4, /* x */ + 0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E, + 0xBB, + 0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b, /* y */ + 0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f, + 0xee, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6, + 0xB3 } }; -static const unsigned char _EC_SECG_PRIME_160R1_SEED[] = { - 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45}; -static const EC_CURVE_DATA _EC_SECG_PRIME_160R1 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", - "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", - "4A96B5688EF573284664698968C38BB913CBFC82", - "23a628553168947d59dcc912042351377ac5fb32", - "0100000000000000000001F4C8F927AED3CA752257",1, - _EC_SECG_PRIME_160R1_SEED, 20, - "SECG curve over a 160 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } + _EC_SECG_PRIME_160R1 = { + { NID_X9_62_prime_field,20,21,1 }, + { 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45, + + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF, + 0xFF, + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF, + 0xFC, + 0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65, /* b */ + 0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA, + 0x45, + 0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46, /* x */ + 0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC, + 0x82, + 0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59, /* y */ + 0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb, + 0x32, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22, + 0x57 } }; -static const unsigned char _EC_SECG_PRIME_160R2_SEED[] = { - 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, - 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51}; -static const EC_CURVE_DATA _EC_SECG_PRIME_160R2 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", - "B4E134D3FB59EB8BAB57274904664D5AF50388BA", - "52DCB034293A117E1F4FF11B30F7199D3144CE6D", - "feaffef2e331f296e071fa0df9982cfea7d43f2e", - "0100000000000000000000351EE786A818F3A1A16B",1, - _EC_SECG_PRIME_160R2_SEED, 20, - "SECG/WTLS curve over a 160 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } + _EC_SECG_PRIME_160R2 = { + { NID_X9_62_prime_field,20,21,1 }, + { 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, /* seed */ + 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51, + + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC, + 0x73, + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC, + 0x70, + 0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB, /* b */ + 0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88, + 0xBA, + 0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F, /* x */ + 0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE, + 0x6D, + 0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0, /* y */ + 0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f, + 0x2e, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1, + 0x6B } }; -static const EC_CURVE_DATA _EC_SECG_PRIME_192K1 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", - "0", - "3", - "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", - "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", - "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",1, - NULL, 20, - "SECG curve over a 192 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; } + _EC_SECG_PRIME_192K1 = { + { NID_X9_62_prime_field,0,24,1 }, + { /* no seed */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xFF,0xFF,0xEE,0x37, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x03, + 0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0, /* x */ + 0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1, + 0xEA,0xE0,0x6C,0x7D, + 0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41, /* y */ + 0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88, + 0xd9,0x5e,0x2f,0x9d, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A, + 0x74,0xDE,0xFD,0x8D } }; -static const EC_CURVE_DATA _EC_SECG_PRIME_224K1 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", - "0", - "5", - "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", - "7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", - "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",1, - NULL, 20, - "SECG curve over a 224 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; } + _EC_SECG_PRIME_224K1 = { + { NID_X9_62_prime_field,0,29,1 }, + { /* no seed */ + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, + 0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30, /* x */ + 0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75, + 0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C, + 0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82, /* y */ + 0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd, + 0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61, + 0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 } }; -static const EC_CURVE_DATA _EC_SECG_PRIME_256K1 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - "0", - "7", - "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1, - NULL, 20, - "SECG curve over a 256 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; } + _EC_SECG_PRIME_256K1 = { + { NID_X9_62_prime_field,0,32,1 }, + { /* no seed */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF, + 0xFC,0x2F, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x07, + 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0, /* x */ + 0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB, + 0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98, + 0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4, /* y */ + 0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48, + 0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10, + 0xd4,0xb8, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6, + 0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36, + 0x41,0x41 } }; /* some wap/wtls curves */ -static const EC_CURVE_DATA _EC_WTLS_8 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFDE7", - "0", - "3", - "1", - "2", - "0100000000000001ECEA551AD837E9",1, - NULL, 20, - "WTLS curve over a 112 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; } + _EC_WTLS_8 = { + { NID_X9_62_prime_field,0,15,1 }, + { /* no seed */ + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFD,0xE7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ + 0x00,0x00,0x00,0x00,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ + 0x00,0x00,0x00,0x00,0x02, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA, /* order */ + 0x55,0x1A,0xD8,0x37,0xE9 } }; -static const EC_CURVE_DATA _EC_WTLS_9 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F", - "0", - "3", - "1", - "2", - "0100000000000000000001CDC98AE0E2DE574ABF33",1, - NULL, 20, - "WTLS curve over a 160 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } + _EC_WTLS_9 = { + { NID_X9_62_prime_field,0,21,1 }, + { /* no seed */ + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80, + 0x8F, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF, + 0x33 } }; -static const EC_CURVE_DATA _EC_WTLS_12 = { - NID_X9_62_prime_field, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1, - NULL, 0, - "WTLS curvs over a 224 bit prime field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; } + _EC_WTLS_12 = { + { NID_X9_62_prime_field,0,28,1 }, + { /* no seed */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */ + 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA, + 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4, + 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */ + 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22, + 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21, + 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */ + 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64, + 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E, + 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D } }; /* characteristic two curves */ -static const unsigned char _EC_SECG_CHAR2_113R1_SEED[] = { - 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, - 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_113R1 = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000201", - "003088250CA6E7C7FE649CE85820F7", - "00E8BEE4D3E2260744188BE0E9C723", - "009D73616F35F4AB1407D73562C10F", - "00A52830277958EE84D1315ED31886", - "0100000000000000D9CCEC8A39E56F", 2, - _EC_SECG_CHAR2_113R1_SEED, 20, - "SECG curve over a 113 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; } + _EC_SECG_CHAR2_113R1 = { + { NID_X9_62_characteristic_two_field,20,15,2 }, + { 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, /* seed */ + 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9, + + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x02,0x01, + 0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64, /* a */ + 0x9C,0xE8,0x58,0x20,0xF7, + 0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18, /* b */ + 0x8B,0xE0,0xE9,0xC7,0x23, + 0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07, /* x */ + 0xD7,0x35,0x62,0xC1,0x0F, + 0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1, /* y */ + 0x31,0x5E,0xD3,0x18,0x86, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC, /* order */ + 0xEC,0x8A,0x39,0xE5,0x6F } }; -static const unsigned char _EC_SECG_CHAR2_113R2_SEED[] = { - 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, - 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_113R2 = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000201", - "00689918DBEC7E5A0DD6DFC0AA55C7", - "0095E9A9EC9B297BD4BF36E059184F", - "01A57A6A7B26CA5EF52FCDB8164797", - "00B3ADC94ED1FE674C06E695BABA1D", - "010000000000000108789B2496AF93", 2, - _EC_SECG_CHAR2_113R2_SEED, 20, - "SECG curve over a 113 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; } + _EC_SECG_CHAR2_113R2 = { + { NID_X9_62_characteristic_two_field,20,15,2 }, + { 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, /* seed */ + 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D, + + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x02,0x01, + 0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6, /* a */ + 0xDF,0xC0,0xAA,0x55,0xC7, + 0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF, /* b */ + 0x36,0xE0,0x59,0x18,0x4F, + 0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F, /* x */ + 0xCD,0xB8,0x16,0x47,0x97, + 0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06, /* y */ + 0xE6,0x95,0xBA,0xBA,0x1D, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78, /* order */ + 0x9B,0x24,0x96,0xAF,0x93 } }; -static const unsigned char _EC_SECG_CHAR2_131R1_SEED[] = { - 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, - 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_131R1 = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000010D", - "07A11B09A76B562144418FF3FF8C2570B8", - "0217C05610884B63B9C6C7291678F9D341", - "0081BAF91FDF9833C40F9C181343638399", - "078C6E7EA38C001F73C8134B1B4EF9E150", - "0400000000000000023123953A9464B54D", 2, - _EC_SECG_CHAR2_131R1_SEED, 20, - "SECG/WTLS curve over a 131 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; } + _EC_SECG_CHAR2_131R1 = { + { NID_X9_62_characteristic_two_field,20,17,2 }, + { 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, /* seed */ + 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2, + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x01,0x0D, + 0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41, /* a */ + 0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8, + 0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6, /* b */ + 0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41, + 0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F, /* x */ + 0x9C,0x18,0x13,0x43,0x63,0x83,0x99, + 0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8, /* y */ + 0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31, /* order */ + 0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D } }; -static const unsigned char _EC_SECG_CHAR2_131R2_SEED[] = { - 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_131R2 = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000010D", - "03E5A88919D7CAFCBF415F07C2176573B2", - "04B8266A46C55657AC734CE38F018F2192", - "0356DCD8F2F95031AD652D23951BB366A8", - "0648F06D867940A5366D9E265DE9EB240F", - "0400000000000000016954A233049BA98F", 2, - _EC_SECG_CHAR2_131R2_SEED, 20, - "SECG curve over a 131 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; } + _EC_SECG_CHAR2_131R2 = { + { NID_X9_62_characteristic_two_field,20,17,2 }, + { 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3, + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x01,0x0D, + 0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41, /* a */ + 0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2, + 0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73, /* b */ + 0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92, + 0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65, /* x */ + 0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8, + 0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D, /* y */ + 0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69, /* order */ + 0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F } }; -static const EC_CURVE_DATA _EC_NIST_CHAR2_163K = { - NID_X9_62_characteristic_two_field, - "0800000000000000000000000000000000000000C9", - "1", - "1", - "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", - "0289070FB05D38FF58321F2E800536D538CCDAA3D9", - "04000000000000000000020108A2E0CC0D99F8A5EF", 2, - NULL, 0, - "NIST/SECG/WTLS curve over a 163 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } + _EC_NIST_CHAR2_163K = { + { NID_X9_62_characteristic_two_field,0,21,2 }, + { /* no seed */ + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xC9, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01, + 0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA, /* x */ + 0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE, + 0xE8, + 0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32, /* y */ + 0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3, + 0xD9, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5, + 0xEF } }; -static const unsigned char _EC_SECG_CHAR2_163R1_SEED[] = { - 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67, - 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_163R1 = { - NID_X9_62_characteristic_two_field, - "0800000000000000000000000000000000000000C9", - "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", - "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", - "0369979697AB43897789566789567F787A7876A654", - "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", - "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2, +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } + _EC_SECG_CHAR2_163R1 = { + { NID_X9_62_characteristic_two_field,0,21,2 }, + { /* no seed */ +#if 0 /* The algorithm used to derive the curve parameters from * the seed used here is slightly different than the - * algorithm described in X9.62 . - */ -#if 0 - _EC_SECG_CHAR2_163R1_SEED, 20, -#else - NULL, 0, + * algorithm described in X9.62 . */ + 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67, + 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C, #endif - "SECG curve over a 163 bit binary field" + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xC9, + 0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54, /* a */ + 0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A, + 0xE2, + 0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94, /* b */ + 0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF, + 0xD9, + 0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89, /* x */ + 0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6, + 0x54, + 0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D, /* y */ + 0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8, + 0x83, + 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27, + 0x9B } }; -static const unsigned char _EC_NIST_CHAR2_163B_SEED[] = { - 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12, - 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68}; -static const EC_CURVE_DATA _EC_NIST_CHAR2_163B ={ - NID_X9_62_characteristic_two_field, - "0800000000000000000000000000000000000000C9", - "1", - "020A601907B8C953CA1481EB10512F78744A3205FD", - "03F0EBA16286A2D57EA0991168D4994637E8343E36", - "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", - "040000000000000000000292FE77E70C12A4234C33", 2, -/* The seed here was used to created the curve parameters in normal - * basis representation (and not the polynomial representation used here) - */ +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } + _EC_NIST_CHAR2_163B = { + { NID_X9_62_characteristic_two_field,0,21,2 }, + { /* no seed */ #if 0 - _EC_NIST_CHAR2_163B_SEED, 20, -#else - NULL, 0, +/* The seed here was used to created the curve parameters in normal + * basis representation (and not the polynomial representation used here) */ + 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12, + 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68, #endif - "NIST/SECG curve over a 163 bit binary field" + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xC9, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01, + 0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14, /* b */ + 0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05, + 0xFD, + 0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0, /* x */ + 0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E, + 0x36, + 0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2, /* y */ + 0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24, + 0xF1, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C, + 0x33 } }; -static const unsigned char _EC_SECG_CHAR2_193R1_SEED[] = { - 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, - 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_193R1 = { - NID_X9_62_characteristic_two_field, - "02000000000000000000000000000000000000000000008001", - "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", - "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", - "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", - "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", - "01000000000000000000000000C7F34A778F443ACC920EBA49", 2, - _EC_SECG_CHAR2_193R1_SEED, 20, - "SECG curve over a 193 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; } + _EC_SECG_CHAR2_193R1 = { + { NID_X9_62_characteristic_two_field,20,25,2 }, + { 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, /* seed */ + 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30, + + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x01, + 0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69, /* a */ + 0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8, + 0xA9,0x11,0xDF,0x7B,0x01, + 0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC, /* b */ + 0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5, + 0xD8,0x31,0x47,0x88,0x14, + 0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD, /* x */ + 0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53, + 0x72,0xD8,0xC0,0xC5,0xE1, + 0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3, /* y */ + 0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B, + 0x6A,0xF7,0xCE,0x1B,0x05, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A, + 0xCC,0x92,0x0E,0xBA,0x49 } }; -static const unsigned char _EC_SECG_CHAR2_193R2_SEED[] = { - 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, - 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11}; -static const EC_CURVE_DATA _EC_SECG_CHAR2_193R2 = { - NID_X9_62_characteristic_two_field, - "02000000000000000000000000000000000000000000008001", - "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", - "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", - "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", - "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", - "010000000000000000000000015AAB561B005413CCD4EE99D5", 2, - _EC_SECG_CHAR2_193R2_SEED, 20, - "SECG curve over a 193 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; } + _EC_SECG_CHAR2_193R2 = { + { NID_X9_62_characteristic_two_field,20,25,2 }, + { 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, /* seed */ + 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11, + + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x01, + 0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6, /* a */ + 0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69, + 0x97,0x77,0x02,0x70,0x9B, + 0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37, /* b */ + 0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7, + 0xF6,0x1D,0x43,0x16,0xAE, + 0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03, /* x */ + 0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35, + 0x0A,0xAE,0x61,0x7E,0x8F, + 0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29, /* y */ + 0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27, + 0x22,0x4C,0xDE,0xCF,0x6C, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13, + 0xCC,0xD4,0xEE,0x99,0xD5 } }; -static const EC_CURVE_DATA _EC_NIST_CHAR2_233K = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000000000000000004000000000000000001", - "0", - "1", - "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", - "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", - "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4, - NULL, 0, - "NIST/SECG/WTLS curve over a 233 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; } + _EC_NIST_CHAR2_233K = { + { NID_X9_62_characteristic_two_field,0,30,4 }, + { /* no seed */ + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1, /* x */ + 0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2, + 0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26, + + 0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F, /* y */ + 0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A, + 0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3, + + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15, + 0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF } }; -static const unsigned char _EC_NIST_CHAR2_233B_SEED[] = { - 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, - 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3}; -static const EC_CURVE_DATA _EC_NIST_CHAR2_233B = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000000000000000004000000000000000001", - "000000000000000000000000000000000000000000000000000000000001", - "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", - "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", - "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", - "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2, - _EC_NIST_CHAR2_233B_SEED, 20, - "NIST/SECG/WTLS curve over a 233 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_NIST_CHAR2_233B = { + { NID_X9_62_characteristic_two_field,20,30,2 }, + { 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, /* seed */ + 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3, + + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C, /* b */ + 0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9, + 0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD, + + 0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21, /* x */ + 0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F, + 0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B, + + 0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78, /* y */ + 0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67, + 0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52, + + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F, + 0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 } }; -static const EC_CURVE_DATA _EC_SECG_CHAR2_239K1 = { - NID_X9_62_characteristic_two_field, - "800000000000000000004000000000000000000000000000000000000001", - "0", - "1", - "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", - "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", - "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4, - NULL, 0, - "SECG curve over a 239 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; } + _EC_SECG_CHAR2_239K1 = { + { NID_X9_62_characteristic_two_field,0,30,4 }, + { /* no seed */ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09, /* x */ + 0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C, + 0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC, + + 0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01, /* y */ + 0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75, + 0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA, + + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C, + 0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 } }; -static const EC_CURVE_DATA _EC_NIST_CHAR2_283K = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000000000000000000000000000000000000000001" - "0A1", - "0", - "1", - "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492" - "836", - "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2" - "259", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163" - "C61", 4, - NULL, 20, - "NIST/SECG curve over a 283 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; } + _EC_NIST_CHAR2_283K = { + { NID_X9_62_characteristic_two_field,0,36,4 }, + { /* no seed */ + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x10,0xA1, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01, + 0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A, /* x */ + 0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F, + 0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2, + 0xAC,0x24,0x58,0x49,0x28,0x36, + 0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90, /* y */ + 0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0, + 0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34, + 0x11,0x61,0x77,0xDD,0x22,0x59, + 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE, + 0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45, + 0x1E,0x06,0x1E,0x16,0x3C,0x61 } }; -static const unsigned char _EC_NIST_CHAR2_283B_SEED[] = { - 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, - 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE}; -static const EC_CURVE_DATA _EC_NIST_CHAR2_283B = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000000000000000000000000000000000000000001" - "0A1", - "000000000000000000000000000000000000000000000000000000000000000000000" - "001", - "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A" - "2F5", - "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12" - "053", - "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE811" - "2F4", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB" - "307", 2, - _EC_NIST_CHAR2_283B_SEED, 20, - "NIST/SECG curve over a 283 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; } + _EC_NIST_CHAR2_283B = { + { NID_X9_62_characteristic_two_field,20,36,2 }, + { 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, /* no seed */ + 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE, + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x10,0xA1, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01, + 0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4, /* b */ + 0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76, + 0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26, + 0x3E,0x31,0x3B,0x79,0xA2,0xF5, + 0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93, /* x */ + 0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8, + 0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD, + 0xBE,0xCD,0x86,0xB1,0x20,0x53, + 0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F, /* y */ + 0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02, + 0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0, + 0xDF,0x45,0xBE,0x81,0x12,0xF4, + 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90, + 0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04, + 0x2A,0x7C,0xEF,0xAD,0xB3,0x07 } }; -static const EC_CURVE_DATA _EC_NIST_CHAR2_409K = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000000000000000000000000000000000000000000000" - "00000000000008000000000000000000001", - "0", - "1", - "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C4601" - "89EB5AAAA62EE222EB1B35540CFE9023746", - "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6" - "C42E9C55215AA9CA27A5863EC48D8E0286B", - "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400" - "EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4, - NULL, 0, - "NIST/SECG curve over a 409 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; } + _EC_NIST_CHAR2_409K = { + { NID_X9_62_characteristic_two_field,0,52,4 }, + { /* no seed */ + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01, + 0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A, /* x */ + 0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87, + 0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6, + 0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62, + 0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02, + 0x37,0x46, + 0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA, /* y */ + 0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F, + 0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA, + 0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15, + 0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0, + 0x28,0x6B, + 0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2, + 0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3, + 0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E, + 0x5F,0xCF } }; -static const unsigned char _EC_NIST_CHAR2_409B_SEED[] = { - 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, - 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B}; -static const EC_CURVE_DATA _EC_NIST_CHAR2_409B = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000000000000000000000000000000000000000000000" - "00000000000008000000000000000000001", - "000000000000000000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000001", - "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A19" - "7B272822F6CD57A55AA4F50AE317B13545F", - "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255" - "A868A1180515603AEAB60794E54BB7996A7", - "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514" - "F1FDF4B4F40D2181B3681C364BA0273C706", - "010000000000000000000000000000000000000000000000000001E2AAD6A612F3330" - "7BE5FA47C3C9E052F838164CD37D9A21173", 2, - _EC_NIST_CHAR2_409B_SEED, 20, - "NIST/SECG curve over a 409 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; } + _EC_NIST_CHAR2_409B = { + { NID_X9_62_characteristic_two_field,20,52,2 }, + { 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, /* seed */ + 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B, + + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01, + 0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B, /* b */ + 0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E, + 0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC, + 0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C, + 0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13, + 0x54,0x5F, + 0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B, /* x */ + 0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A, + 0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5, + 0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51, + 0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79, + 0x96,0xA7, + 0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF, /* y */ + 0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5, + 0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88, + 0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40, + 0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73, + 0xC7,0x06, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6, + 0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C, + 0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2, + 0x11,0x73 } }; -static const EC_CURVE_DATA _EC_NIST_CHAR2_571K = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000" - "00425", - "0", - "1", - "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709" - "58493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A0" - "1C8972", - "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D497" - "9C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143E" - "F1C7A3", - "020000000000000000000000000000000000000000000000000000000000000000000" - "000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F63" - "7C1001", 4, - NULL, 0, - "NIST/SECG curve over a 571 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; } + _EC_NIST_CHAR2_571K = { + { NID_X9_62_characteristic_two_field,0,72,4 }, + { /* no seed */ + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x25, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01, + 0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18, /* x */ + 0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97, + 0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84, + 0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6, + 0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1, + 0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17, + 0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C, + 0x89,0x72, + 0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A, /* y */ + 0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC, + 0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D, + 0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7, + 0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20, + 0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8, + 0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1, + 0xC7,0xA3, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1, + 0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F, + 0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38, + 0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C, + 0x10,0x01 } }; -static const unsigned char _EC_NIST_CHAR2_571B_SEED[] = { - 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, - 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10}; -static const EC_CURVE_DATA _EC_NIST_CHAR2_571B = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000" - "00425", - "000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000" - "000001", - "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFA" - "BBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F29" - "55727A", - "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53" - "950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8E" - "EC2D19", - "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423" - "E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B" - "8AC15B", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2F" - "E84E47", 2, - _EC_NIST_CHAR2_571B_SEED, 20, - "NIST/SECG curve over a 571 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; } + _EC_NIST_CHAR2_571B = { + { NID_X9_62_characteristic_two_field,20,72,2 }, + { 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, /* seed */ + 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10, + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x25, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01, + 0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29, /* b */ + 0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF, + 0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A, + 0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33, + 0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD, + 0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7, + 0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55, + 0x72,0x7A, + 0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16, /* x */ + 0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2, + 0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B, + 0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93, + 0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE, + 0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4, + 0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC, + 0x2D,0x19, + 0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC, /* y */ + 0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6, + 0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21, + 0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57, + 0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53, + 0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51, + 0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A, + 0xC1,0x5B, + 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18, + 0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23, + 0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D, + 0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8, + 0x4E,0x47 } }; -static const unsigned char _EC_X9_62_CHAR2_163V1_SEED[] = { - 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, - 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V1 = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000000000000107", - "072546B5435234A422E0789675F432C89435DE5242", - "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", - "07AF69989546103D79329FCC3D74880F33BBE803CB", - "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", - "0400000000000000000001E60FC8821CC74DAEAFC1", 2, - _EC_X9_62_CHAR2_163V1_SEED, 20, - "X9.62 curve over a 163 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } + _EC_X9_62_CHAR2_163V1 = { + { NID_X9_62_characteristic_two_field,20,21,2 }, + { 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, + 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54, /* seed */ + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x07, + 0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0, /* a */ + 0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52, + 0x42, + 0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF, /* b */ + 0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4, + 0xD9, + 0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32, /* x */ + 0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03, + 0xCB, + 0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D, /* y */ + 0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA, + 0x9F, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF, + 0xC1 } }; -static const unsigned char _EC_X9_62_CHAR2_163V2_SEED[] = { - 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V2 = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000000000000107", - "0108B39E77C4B108BED981ED0E890E117C511CF072", - "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", - "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", - "079F684DDF6684C5CD258B3890021B2386DFD19FC5", - "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2, - _EC_X9_62_CHAR2_163V2_SEED, 20, - "X9.62 curve over a 163 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } + _EC_X9_62_CHAR2_163V2 = { + { NID_X9_62_characteristic_two_field,20,21,2 }, + { 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD, + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x07, + 0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9, /* a */ + 0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0, + 0x72, + 0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40, /* b */ + 0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF, + 0x20, + 0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96, /* x */ + 0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C, + 0xC5, + 0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25, /* y */ + 0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F, + 0xC5, + 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10, + 0xA7 } }; -static const unsigned char _EC_X9_62_CHAR2_163V3_SEED[] = { - 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, - 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V3 = { - NID_X9_62_characteristic_two_field, - "080000000000000000000000000000000000000107", - "07A526C63D3E25A256A007699F5447E32AE456B50E", - "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", - "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", - "05B935590C155E17EA48EB3FF3718B893DF59A05D0", - "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2, - _EC_X9_62_CHAR2_163V3_SEED, 20, - "X9.62 curve over a 163 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } + _EC_X9_62_CHAR2_163V3 = { + { NID_X9_62_characteristic_two_field,20,21,2 }, + { 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, /* seed */ + 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8, + + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x07, + 0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0, /* a */ + 0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5, + 0x0E, + 0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD, /* b */ + 0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25, + 0x2B, + 0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF, /* x */ + 0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD, + 0xCB, + 0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48, /* y */ + 0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05, + 0xD0, + 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13, + 0x09 } }; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_176V1 = { - NID_X9_62_characteristic_two_field, - "0100000000000000000000000000000000080000000007", - "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", - "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", - "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", - "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", - "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E, - NULL, 0, - "X9.62 curve over a 176 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; } + _EC_X9_62_CHAR2_176V1 = { + { NID_X9_62_characteristic_two_field,0,23,0xFF6E }, + { /* no seed */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00, + 0x00,0x00,0x07, + 0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D, /* a */ + 0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8, + 0xE9,0xC9,0x0B, + 0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E, /* b */ + 0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A, + 0xE0,0xFF,0xF2, + 0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9, /* x */ + 0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0, + 0x4A,0x57,0x98, + 0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA, /* y */ + 0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1, + 0x6A,0x56,0x2C, + 0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4, /* order */ + 0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06, + 0xFE,0x26,0xAD } }; -static const unsigned char _EC_X9_62_CHAR2_191V1_SEED[] = { - 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V1 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000201", - "2866537B676752636A68F56554E12640276B649EF7526267", - "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", - "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", - "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", - "40000000000000000000000004A20E90C39067C893BBB9A5", 2, - _EC_X9_62_CHAR2_191V1_SEED, 20, - "X9.62 curve over a 191 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } + _EC_X9_62_CHAR2_191V1 = { + { NID_X9_62_characteristic_two_field,20,24,2 }, + { 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x02,0x01, + 0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68, /* a */ + 0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E, + 0xF7,0x52,0x62,0x67, + 0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0, /* b */ + 0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE, + 0x0A,0xA1,0x85,0xEC, + 0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2, /* x */ + 0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8, + 0x4A,0xE1,0xAA,0x0D, + 0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29, /* y */ + 0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E, + 0xF9,0x80,0x18,0xFB, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8, + 0x93,0xBB,0xB9,0xA5 } }; -static const unsigned char _EC_X9_62_CHAR2_191V2_SEED[] = { - 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V2 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000201", - "401028774D7777C7B7666D1366EA432071274F89FF01E718", - "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", - "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", - "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", - "20000000000000000000000050508CB89F652824E06B8173", 4, - _EC_X9_62_CHAR2_191V2_SEED, 20, - "X9.62 curve over a 191 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } + _EC_X9_62_CHAR2_191V2 = { + { NID_X9_62_characteristic_two_field,20,24,4 }, + { 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x02,0x01, + 0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66, /* a */ + 0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89, + 0xFF,0x01,0xE7,0x18, + 0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24, /* b */ + 0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3, + 0x62,0xC4,0x6A,0x01, + 0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87, /* x */ + 0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2, + 0xC9,0xE3,0xBF,0x10, + 0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0, /* y */ + 0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC, + 0x43,0x7D,0x66,0x8A, + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24, + 0xE0,0x6B,0x81,0x73 } }; -static const unsigned char _EC_X9_62_CHAR2_191V3_SEED[] = { - 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V3 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000201", - "6C01074756099122221056911C77D77E77A777E7E7E77FCB", - "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", - "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", - "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", - "155555555555555555555555610C0B196812BFB6288A3EA3", 6, - _EC_X9_62_CHAR2_191V3_SEED, 20, - "X9.62 curve over a 191 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } + _EC_X9_62_CHAR2_191V3 = { + { NID_X9_62_characteristic_two_field,20,24,6 }, + { 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x02,0x01, + 0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10, /* a */ + 0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7, + 0xE7,0xE7,0x7F,0xCB, + 0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF, /* b */ + 0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32, + 0xAD,0x3F,0x15,0xE8, + 0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE, /* x */ + 0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E, + 0x38,0xA9,0x26,0xDD, + 0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59, /* y */ + 0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7, + 0x12,0x7B,0x06,0xBE, + 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */ + 0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6, + 0x28,0x8A,0x3E,0xA3 } }; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_208W1 = { - NID_X9_62_characteristic_two_field, - "010000000000000000000000000000000800000000000000000007", - "0000000000000000000000000000000000000000000000000000", - "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", - "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", - "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", - "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48, - NULL, 0, - "X9.62 curve over a 208 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; } + _EC_X9_62_CHAR2_208W1 = { + { NID_X9_62_characteristic_two_field,0,27,0xFE48 }, + { /* no seed */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E, /* b */ + 0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA, + 0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E, + 0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95, /* x */ + 0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27, + 0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A, + 0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3, /* y */ + 0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE, + 0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3, + 0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5, /* order */ + 0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88, + 0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D } }; -static const unsigned char _EC_X9_62_CHAR2_239V1_SEED[] = { - 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, - 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V1 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000001000000001", - "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", - "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", - "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", - "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", - "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4, - _EC_X9_62_CHAR2_239V1_SEED, 20, - "X9.62 curve over a 239 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_X9_62_CHAR2_239V1 = { + { NID_X9_62_characteristic_two_field,20,30,4 }, + { 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */ + 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01, + + 0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A, /* a */ + 0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E, + 0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76, + + 0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12, /* b */ + 0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C, + 0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16, + + 0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96, /* x */ + 0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56, + 0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D, + + 0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1, /* y */ + 0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E, + 0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05, + + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ + 0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1, + 0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 } }; -static const unsigned char _EC_X9_62_CHAR2_239V2_SEED[] = { - 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V2 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000001000000001", - "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", - "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", - "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", - "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", - "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6, - _EC_X9_62_CHAR2_239V2_SEED, 20, - "X9.62 curve over a 239 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_X9_62_CHAR2_239V2 = { + { NID_X9_62_characteristic_two_field,20,30,6 }, + { 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01, + + 0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23, /* a */ + 0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF, + 0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F, + + 0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82, /* b */ + 0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52, + 0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B, + + 0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47, /* x */ + 0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7, + 0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05, + + 0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B, /* y */ + 0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56, + 0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33, + + 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */ + 0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25, + 0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D } }; -static const unsigned char _EC_X9_62_CHAR2_239V3_SEED[] = { - 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, - 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V3 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000001000000001", - "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", - "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", - "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", - "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", - "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA, - _EC_X9_62_CHAR2_239V3_SEED, 20, - "X9.62 curve over a 239 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } + _EC_X9_62_CHAR2_239V3 = { + { NID_X9_62_characteristic_two_field,20,30,0xA }, + { 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */ + 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01, + + 0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66, /* a */ + 0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66, + 0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F, + + 0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99, /* b */ + 0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5, + 0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40, + + 0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91, /* x */ + 0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42, + 0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92, + + 0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00, /* y */ + 0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08, + 0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61, + + 0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, /* order */ + 0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9, + 0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF } }; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_272W1 = { - NID_X9_62_characteristic_two_field, - "010000000000000000000000000000000000000000000000000000010000000000000" - "B", - "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", - "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", - "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", - "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", - "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", - 0xFF06, - NULL, 0, - "X9.62 curve over a 272 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; } + _EC_X9_62_CHAR2_272W1 = { + { NID_X9_62_characteristic_two_field,0,35,0xFF06 }, + { /* no seed */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0x0B, + 0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2, /* a */ + 0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71, + 0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA, + 0xCD,0xB5,0x86,0xFB,0x20, + 0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C, /* b */ + 0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03, + 0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC, + 0x84,0x82,0xE5,0x40,0xF7, + 0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87, /* x */ + 0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77, + 0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D, + 0x10,0xD1,0x71,0xDD,0x8D, + 0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B, /* y */ + 0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8, + 0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02, + 0x00,0x5D,0xDE,0x9D,0x23, + 0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3, /* order */ + 0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16, + 0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B, + 0x8F,0x1E,0x62,0x95,0x21 } }; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_304W1 = { - NID_X9_62_characteristic_two_field, - "010000000000000000000000000000000000000000000000000000000000000000000" - "000000807", - "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A039" - "6C8E681", - "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E558" - "27340BE", - "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F7" - "40A2614", - "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1" - "B92C03B", - "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164" - "443051D", 0xFE2E, - NULL, 0, - "X9.62 curve over a 304 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; } + _EC_X9_62_CHAR2_304W1 = { + { NID_X9_62_characteristic_two_field,0,39,0xFE2E }, + { /* no seed */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07, + 0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51, /* a */ + 0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88, + 0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28, + 0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81, + 0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E, /* b */ + 0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F, + 0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1, + 0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE, + 0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A, /* x */ + 0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E, + 0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD, + 0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14, + 0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51, /* y */ + 0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10, + 0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80, + 0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B, + 0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC, /* order */ + 0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80, + 0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5, + 0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D } }; -static const unsigned char _EC_X9_62_CHAR2_359V1_SEED[] = { - 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, - 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6}; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_359V1 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000000000000000000000000" - "000100000000000000001", - "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05" - "656FB549016A96656A557", - "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC34562608968" - "7742B6329E70680231988", - "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE9" - "8E8E707C07A2239B1B097", - "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E" - "4AE2DE211305A407104BD", - "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB9" - "64FE7719E74F490758D3B", 0x4C, - _EC_X9_62_CHAR2_359V1_SEED, 20, - "X9.62 curve over a 359 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; } + _EC_X9_62_CHAR2_359V1 = { + { NID_X9_62_characteristic_two_field,20,45,0x4C }, + { 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, /* seed */ + 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6, + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01, + 0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35, /* a */ + 0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67, + 0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67, + 0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16, + 0xA9,0x66,0x56,0xA5,0x57, + 0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F, /* b */ + 0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D, + 0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34, + 0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7, + 0x06,0x80,0x23,0x19,0x88, + 0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0, /* x */ + 0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A, + 0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF, + 0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A, + 0x22,0x39,0xB1,0xB0,0x97, + 0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E, /* y */ + 0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48, + 0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC, + 0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30, + 0x5A,0x40,0x71,0x04,0xBD, + 0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1, /* order */ + 0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF, + 0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89, + 0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74, + 0xF4,0x90,0x75,0x8D,0x3B } }; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_368W1 = { - NID_X9_62_characteristic_two_field, - "010000000000000000000000000000000000000000000000000000000000000000000" - "0002000000000000000000007", - "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62" - "F0AB7519CCD2A1A906AE30D", - "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112" - "D84D164F444F8F74786046A", - "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E78" - "9E927BE216F02E1FB136A5F", - "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855" - "ADAA81E2A0750B80FDA2310", - "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E90" - "9AE40A6F131E9CFCE5BD967", 0xFF70, - NULL, 0, - "X9.62 curve over a 368 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; } + _EC_X9_62_CHAR2_368W1 = { + { NID_X9_62_characteristic_two_field,0,47,0xFF70 }, + { /* no seed */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07, + 0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2, /* a */ + 0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0, + 0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9, + 0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C, + 0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D, + 0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C, /* b */ + 0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B, + 0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5, + 0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4, + 0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A, + 0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3, /* x */ + 0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82, + 0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B, + 0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21, + 0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F, + 0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8, /* y */ + 0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C, + 0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE, + 0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A, + 0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10, + 0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72, /* order */ + 0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53, + 0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A, + 0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1, + 0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 } }; -static const EC_CURVE_DATA _EC_X9_62_CHAR2_431R1 = { - NID_X9_62_characteristic_two_field, - "800000000000000000000000000000000000000000000000000000000000000000000" - "000000001000000000000000000000000000001", - "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0E" - "B9906D0957F6C6FEACD615468DF104DE296CD8F", - "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B6" - "26D4E50A8DD731B107A9962381FB5D807BF2618", - "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C2" - "1E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", - "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6" - "ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", - "0340340340340340340340340340340340340340340340340340340323C313FAB5058" - "9703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760, - NULL, 0, - "X9.62 curve over a 431 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; } + _EC_X9_62_CHAR2_431R1 = { + { NID_X9_62_characteristic_two_field,0,54,0x2760 }, + { /* no seed */ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01, + 0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C, /* a */ + 0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23, + 0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9, + 0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F, + 0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D, + 0xE2,0x96,0xCD,0x8F, + 0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43, /* b */ + 0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB, + 0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67, + 0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD, + 0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8, + 0x07,0xBF,0x26,0x18, + 0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61, /* x */ + 0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4, + 0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2, + 0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65, + 0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB, + 0xD7,0x0C,0xE6,0xB7, + 0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2, /* y */ + 0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93, + 0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B, + 0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C, + 0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A, + 0x59,0x8B,0x37,0x60, + 0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34, /* order */ + 0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03, + 0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23, + 0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6, + 0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49, + 0xC1,0xAD,0x4A,0x91 } }; -static const EC_CURVE_DATA _EC_WTLS_1 = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000201", - "1", - "1", - "01667979A40BA497E5D5C270780617", - "00F44B4AF1ECC2630E08785CEBCC15", - "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2, - NULL, 0, - "WTLS curve over a 113 bit binary field" +static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; } + _EC_WTLS_1 = { + { NID_X9_62_characteristic_two_field,0,15,2 }, + { /* no seed */ + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x02,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x01, + 0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5, /* x */ + 0xC2,0x70,0x78,0x06,0x17, + 0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08, /* y */ + 0x78,0x5C,0xEB,0xCC,0x15, + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF, /* order */ + 0x91,0xAF,0x6D,0xEA,0x73 } }; /* IPSec curves */ @@ -1001,17 +1765,27 @@ static const EC_CURVE_DATA _EC_WTLS_1 = { * As the group order is not a prime this curve is not suitable * for ECDSA. */ -static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = { - NID_X9_62_characteristic_two_field, - "0800000000000000000000004000000000000001", - "0", - "07338f", - "7b", - "1c8", - "2AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C",3, - NULL, 0, - "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" - "\tNot suitable for ECDSA.\n\tQuestionable extension field!" +static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; } + _EC_IPSEC_155_ID3 = { + { NID_X9_62_characteristic_two_field,0,20,3 }, + { /* no seed */ + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8, + + 0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /* order */ + 0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C } }; /* NOTE: The of curves over a extension field of non prime degree @@ -1019,106 +1793,118 @@ static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = { * As the group order is not a prime this curve is not suitable * for ECDSA. */ -static const EC_CURVE_DATA _EC_IPSEC_185_ID4 = { - NID_X9_62_characteristic_two_field, - "020000000000000000000000000000200000000000000001", - "0", - "1ee9", - "18", - "0d", - "FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E",2, - NULL, 0, - "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" - "\tNot suitable for ECDSA.\n\tQuestionable extension field!" +static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; } + _EC_IPSEC_185_ID4 = { + { NID_X9_62_characteristic_two_field,0,24,2 }, + { /* no seed */ + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1e,0xe9, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x18, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x0d, + 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ + 0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20, + 0xBA,0xFC,0xA7,0x5E } }; typedef struct _ec_list_element_st { int nid; const EC_CURVE_DATA *data; + const char *comment; } ec_list_element; static const ec_list_element curve_list[] = { /* prime field curves */ /* secg curves */ - { NID_secp112r1, &_EC_SECG_PRIME_112R1}, - { NID_secp112r2, &_EC_SECG_PRIME_112R2}, - { NID_secp128r1, &_EC_SECG_PRIME_128R1}, - { NID_secp128r2, &_EC_SECG_PRIME_128R2}, - { NID_secp160k1, &_EC_SECG_PRIME_160K1}, - { NID_secp160r1, &_EC_SECG_PRIME_160R1}, - { NID_secp160r2, &_EC_SECG_PRIME_160R2}, + { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"}, + { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"}, + { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"}, + { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"}, + { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"}, + { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"}, + { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"}, /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ - { NID_secp192k1, &_EC_SECG_PRIME_192K1}, - { NID_secp224k1, &_EC_SECG_PRIME_224K1}, - { NID_secp224r1, &_EC_NIST_PRIME_224}, - { NID_secp256k1, &_EC_SECG_PRIME_256K1}, + { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"}, + { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"}, + { NID_secp224r1, &_EC_NIST_PRIME_224.h, "NIST/SECG curve over a 224 bit prime field"}, + { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"}, /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ - { NID_secp384r1, &_EC_NIST_PRIME_384}, - { NID_secp521r1, &_EC_NIST_PRIME_521}, + { NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"}, + { NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"}, /* X9.62 curves */ - { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192}, - { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2}, - { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3}, - { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1}, - { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2}, - { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3}, - { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1}, + { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"}, + { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"}, + { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"}, + { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"}, + { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"}, + { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"}, + { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"}, /* characteristic two field curves */ /* NIST/SECG curves */ - { NID_sect113r1, &_EC_SECG_CHAR2_113R1}, - { NID_sect113r2, &_EC_SECG_CHAR2_113R2}, - { NID_sect131r1, &_EC_SECG_CHAR2_131R1}, - { NID_sect131r2, &_EC_SECG_CHAR2_131R2}, - { NID_sect163k1, &_EC_NIST_CHAR2_163K }, - { NID_sect163r1, &_EC_SECG_CHAR2_163R1}, - { NID_sect163r2, &_EC_NIST_CHAR2_163B }, - { NID_sect193r1, &_EC_SECG_CHAR2_193R1}, - { NID_sect193r2, &_EC_SECG_CHAR2_193R2}, - { NID_sect233k1, &_EC_NIST_CHAR2_233K }, - { NID_sect233r1, &_EC_NIST_CHAR2_233B }, - { NID_sect239k1, &_EC_SECG_CHAR2_239K1}, - { NID_sect283k1, &_EC_NIST_CHAR2_283K }, - { NID_sect283r1, &_EC_NIST_CHAR2_283B }, - { NID_sect409k1, &_EC_NIST_CHAR2_409K }, - { NID_sect409r1, &_EC_NIST_CHAR2_409B }, - { NID_sect571k1, &_EC_NIST_CHAR2_571K }, - { NID_sect571r1, &_EC_NIST_CHAR2_571B }, + { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"}, + { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"}, + { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"}, + { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"}, + { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field" }, + { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"}, + { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, "NIST/SECG curve over a 163 bit binary field" }, + { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"}, + { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"}, + { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field" }, + { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field" }, + { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"}, + { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, "NIST/SECG curve over a 283 bit binary field" }, + { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, "NIST/SECG curve over a 283 bit binary field" }, + { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, "NIST/SECG curve over a 409 bit binary field" }, + { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, "NIST/SECG curve over a 409 bit binary field" }, + { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, "NIST/SECG curve over a 571 bit binary field" }, + { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, "NIST/SECG curve over a 571 bit binary field" }, /* X9.62 curves */ - { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1}, - { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2}, - { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3}, - { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1}, - { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1}, - { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2}, - { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3}, - { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1}, - { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1}, - { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2}, - { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3}, - { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1}, - { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1}, - { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1}, - { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1}, - { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1}, + { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"}, + { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"}, + { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"}, + { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"}, + { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"}, + { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"}, + { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"}, + { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"}, + { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"}, + { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"}, + { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"}, + { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"}, + { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"}, + { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"}, + { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"}, + { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"}, /* the WAP/WTLS curves * [unlike SECG, spec has its own OIDs for curves from X9.62] */ - { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1}, - { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K}, - { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1}, - { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1}, - { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1}, - { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2}, - { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8}, - { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9 }, - { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K}, - { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B}, - { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12}, + { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"}, + { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field"}, + { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"}, + { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"}, + { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"}, + { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"}, + { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"}, + { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" }, + { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"}, + { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"}, + { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"}, /* IPSec curves */ - { NID_ipsec3, &_EC_IPSEC_155_ID3}, - { NID_ipsec4, &_EC_IPSEC_185_ID4}, + { NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, + { NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, }; -static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element); +#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) { @@ -1127,22 +1913,23 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) BN_CTX *ctx=NULL; BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; int ok=0; + int seed_len,param_len; + const unsigned char *params; if ((ctx = BN_CTX_new()) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } - if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || - (b = BN_new()) == NULL || (x = BN_new()) == NULL || - (y = BN_new()) == NULL || (order = BN_new()) == NULL) - { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a) - || !BN_hex2bn(&b, data->b)) + + seed_len = data->seed_len; + param_len = data->param_len; + params = (const unsigned char *)(data+1); /* skip header */ + params += seed_len; /* skip seed */ + + 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))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; @@ -1156,8 +1943,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) goto err; } } - else - { /* field_type == NID_X9_62_characteristic_two_field */ + else /* field_type == NID_X9_62_characteristic_two_field */ + { if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); @@ -1171,7 +1958,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) goto err; } - if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y)) + if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL)) + || !(y = BN_bin2bn(params+4*param_len, param_len, NULL))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; @@ -1181,7 +1969,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } - if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor)) + if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL)) + || !BN_set_word(x, (BN_ULONG)data->cofactor)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; @@ -1191,9 +1980,9 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } - if (data->seed) + if (seed_len) { - if (!EC_GROUP_set_seed(group, data->seed, data->seed_len)) + if (!EC_GROUP_set_seed(group, params-seed_len, seed_len)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; @@ -1263,7 +2052,7 @@ size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) for (i = 0; i < min; i++) { r[i].nid = curve_list[i].nid; - r[i].comment = curve_list[i].data->comment; + r[i].comment = curve_list[i].comment; } return curve_list_length; diff --git a/crypto/openssl/crypto/ec/ec_err.c b/crypto/openssl/crypto/ec/ec_err.c index d04c895560..84b4833371 100644 --- a/crypto/openssl/crypto/ec/ec_err.c +++ b/crypto/openssl/crypto/ec/ec_err.c @@ -74,6 +74,14 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"}, +{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"}, +{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"}, +{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"}, +{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"}, +{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"}, +{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"}, +{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"}, +{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"}, {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"}, {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"}, {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"}, @@ -147,7 +155,6 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, -{ERR_FUNC(EC_F_EC_POINTS_MUL), "EC_POINTs_mul"}, {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, @@ -178,6 +185,13 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"}, +{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"}, +{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"}, +{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"}, +{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"}, +{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"}, +{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"}, +{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"}, {0,NULL} }; @@ -187,6 +201,7 @@ static ERR_STRING_DATA EC_str_reasons[]= {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"}, {ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"}, {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"}, +{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"}, {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"}, {ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"}, @@ -196,6 +211,8 @@ static ERR_STRING_DATA EC_str_reasons[]= {ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"}, {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"}, {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"}, +{ERR_REASON(EC_R_INVALID_CURVE) ,"invalid curve"}, +{ERR_REASON(EC_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, {ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"}, {ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"}, {ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"}, @@ -203,6 +220,7 @@ static ERR_STRING_DATA EC_str_reasons[]= {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"}, {ERR_REASON(EC_R_INVALID_PRIVATE_KEY) ,"invalid private key"}, {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"}, +{ERR_REASON(EC_R_KEYS_NOT_SET) ,"keys not set"}, {ERR_REASON(EC_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(EC_R_MISSING_PRIVATE_KEY) ,"missing private key"}, {ERR_REASON(EC_R_NOT_A_NIST_PRIME) ,"not a NIST prime"}, @@ -210,6 +228,7 @@ static ERR_STRING_DATA EC_str_reasons[]= {ERR_REASON(EC_R_NOT_IMPLEMENTED) ,"not implemented"}, {ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"}, {ERR_REASON(EC_R_NO_FIELD_MOD) ,"no field mod"}, +{ERR_REASON(EC_R_NO_PARAMETERS_SET) ,"no parameters set"}, {ERR_REASON(EC_R_PASSED_NULL_PARAMETER) ,"passed null parameter"}, {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"}, {ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"}, diff --git a/crypto/openssl/crypto/ec/ec_lcl.h b/crypto/openssl/crypto/ec/ec_lcl.h index fdd7aa2755..3e2c34b0bc 100644 --- a/crypto/openssl/crypto/ec/ec_lcl.h +++ b/crypto/openssl/crypto/ec/ec_lcl.h @@ -205,11 +205,14 @@ struct ec_group_st { * irreducible polynomial defining the field. */ - unsigned int poly[5]; /* Field specification for curves over GF(2^m). - * The irreducible f(t) is then of the form: - * t^poly[0] + t^poly[1] + ... + t^poly[k] - * where m = poly[0] > poly[1] > ... > poly[k] = 0. - */ + int poly[6]; /* Field specification for curves over GF(2^m). + * The irreducible f(t) is then of the form: + * t^poly[0] + t^poly[1] + ... + t^poly[k] + * where m = poly[0] > poly[1] > ... > poly[k] = 0. + * The array is terminated with poly[k+1]=-1. + * All elliptic curve irreducibles have at most 5 + * non-zero terms. + */ BIGNUM a, b; /* Curve coefficients. * (Here the assumption is that BIGNUMs can be used diff --git a/crypto/openssl/crypto/ec/ec_lib.c b/crypto/openssl/crypto/ec/ec_lib.c index 5af84376c6..dd7da0fcf9 100644 --- a/crypto/openssl/crypto/ec/ec_lib.c +++ b/crypto/openssl/crypto/ec/ec_lib.c @@ -79,7 +79,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) if (meth == NULL) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER); + ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); return NULL; } if (meth->group_init == 0) @@ -740,7 +740,7 @@ void EC_POINT_clear_free(EC_POINT *point) if (point->meth->point_clear_finish != 0) point->meth->point_clear_finish(point); - else if (point->meth != NULL && point->meth->point_finish != 0) + else if (point->meth->point_finish != 0) point->meth->point_finish(point); OPENSSL_cleanse(point, sizeof *point); OPENSSL_free(point); diff --git a/crypto/openssl/crypto/ec/ec_mult.c b/crypto/openssl/crypto/ec/ec_mult.c index 2ba173ef36..f05df5332e 100644 --- a/crypto/openssl/crypto/ec/ec_mult.c +++ b/crypto/openssl/crypto/ec/ec_mult.c @@ -224,6 +224,12 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) sign = -1; } + if (scalar->d == NULL || scalar->top == 0) + { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + len = BN_num_bits(scalar); r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation * (*ret_len will be set to the actual length, i.e. at most @@ -233,12 +239,6 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); goto err; } - - if (scalar->d == NULL || scalar->top == 0) - { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } window_val = scalar->d[0] & mask; j = 0; while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */ @@ -419,7 +419,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, if (numblocks > pre_comp->numblocks) numblocks = pre_comp->numblocks; - pre_points_per_block = 1u << (pre_comp->w - 1); + pre_points_per_block = (size_t)1 << (pre_comp->w - 1); /* check that pre_comp looks sane */ if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) @@ -461,7 +461,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); wsize[i] = EC_window_bits_for_scalar_size(bits); - num_val += 1u << (wsize[i] - 1); + num_val += (size_t)1 << (wsize[i] - 1); wNAF[i + 1] = NULL; /* make sure we always have a pivot */ wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]); if (wNAF[i] == NULL) @@ -600,7 +600,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, for (i = 0; i < num + num_scalar; i++) { val_sub[i] = v; - for (j = 0; j < (1u << (wsize[i] - 1)); j++) + for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { *v = EC_POINT_new(group); if (*v == NULL) goto err; @@ -636,7 +636,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, if (wsize[i] > 1) { if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err; - for (j = 1; j < (1u << (wsize[i] - 1)); j++) + for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err; } @@ -820,7 +820,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */ - pre_points_per_block = 1u << (w - 1); + pre_points_per_block = (size_t)1 << (w - 1); num = pre_points_per_block * numblocks; /* number of points to compute and store */ points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1)); diff --git a/crypto/openssl/crypto/ec/ec_pmeth.c b/crypto/openssl/crypto/ec/ec_pmeth.c new file mode 100644 index 0000000000..f433076ca1 --- /dev/null +++ b/crypto/openssl/crypto/ec/ec_pmeth.c @@ -0,0 +1,340 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "evp_locl.h" + +/* EC pkey context structure */ + +typedef struct + { + /* Key and paramgen group */ + EC_GROUP *gen_group; + /* message digest */ + const EVP_MD *md; + } EC_PKEY_CTX; + +static int pkey_ec_init(EVP_PKEY_CTX *ctx) + { + EC_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); + if (!dctx) + return 0; + dctx->gen_group = NULL; + dctx->md = NULL; + + ctx->data = dctx; + + return 1; + } + +static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + EC_PKEY_CTX *dctx, *sctx; + if (!pkey_ec_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + if (sctx->gen_group) + { + dctx->gen_group = EC_GROUP_dup(sctx->gen_group); + if (!dctx->gen_group) + return 0; + } + dctx->md = sctx->md; + return 1; + } + +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) + { + EC_PKEY_CTX *dctx = ctx->data; + if (dctx) + { + if (dctx->gen_group) + EC_GROUP_free(dctx->gen_group); + OPENSSL_free(dctx); + } + } + +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) + { + int ret, 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)) + { + ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + + ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); + + if (ret <= 0) + return ret; + *siglen = (size_t)sltmp; + return 1; + } + +static int pkey_ec_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) + { + int ret, type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); + + return ret; + } + +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) + { + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + if (!ctx->pkey || !ctx->peerkey) + { + ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); + return 0; + } + + if (!key) + { + const EC_GROUP *group; + group = EC_KEY_get0_group(ctx->pkey->pkey.ec); + *keylen = (EC_GROUP_get_degree(group) + 7)/8; + return 1; + } + + pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is + * not an error, the result is truncated. + */ + + outlen = *keylen; + + ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0); + if (ret < 0) + return ret; + *keylen = ret; + return 1; + } + +static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + EC_PKEY_CTX *dctx = ctx->data; + EC_GROUP *group; + switch (type) + { + case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: + group = EC_GROUP_new_by_curve_name(p1); + if (group == NULL) + { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); + return 0; + } + if (dctx->gen_group) + EC_GROUP_free(dctx->gen_group); + dctx->gen_group = group; + return 1; + + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + 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) + { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + default: + return -2; + + } + } + +static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!strcmp(type, "ec_paramgen_curve")) + { + int nid; + nid = OBJ_sn2nid(value); + if (nid == NID_undef) + nid = OBJ_ln2nid(value); + if (nid == NID_undef) + { + ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); + return 0; + } + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); + } + return -2; + } + +static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + EC_KEY *ec = NULL; + EC_PKEY_CTX *dctx = ctx->data; + int ret = 0; + if (dctx->gen_group == NULL) + { + ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + ret = EC_KEY_set_group(ec, dctx->gen_group); + if (ret) + EVP_PKEY_assign_EC_KEY(pkey, ec); + else + EC_KEY_free(ec); + return ret; + } + +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + EC_KEY *ec = NULL; + if (ctx->pkey == NULL) + { + ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + EVP_PKEY_assign_EC_KEY(pkey, ec); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return EC_KEY_generate_key(pkey->pkey.ec); + } + +const EVP_PKEY_METHOD ec_pkey_meth = + { + EVP_PKEY_EC, + 0, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, + + 0, + pkey_ec_paramgen, + + 0, + pkey_ec_keygen, + + 0, + pkey_ec_sign, + + 0, + pkey_ec_verify, + + 0,0, + + 0,0,0,0, + + 0,0, + + 0,0, + + 0, + pkey_ec_derive, + + pkey_ec_ctrl, + pkey_ec_ctrl_str + + }; diff --git a/crypto/openssl/crypto/ec/eck_prn.c b/crypto/openssl/crypto/ec/eck_prn.c new file mode 100644 index 0000000000..7d3e175ae7 --- /dev/null +++ b/crypto/openssl/crypto/ec/eck_prn.c @@ -0,0 +1,391 @@ +/* crypto/ec/eck_prn.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +#ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECPKParameters_print(b, x, off); + BIO_free(b); + return(ret); + } + +int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); + return(0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = EC_KEY_print(b, x, off); + BIO_free(b); + return(ret); + } + +int ECParameters_print_fp(FILE *fp, const EC_KEY *x) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); + return(0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECParameters_print(b, x); + BIO_free(b); + return(ret); + } +#endif + +int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) + { + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; + } + +int ECParameters_print(BIO *bp, const EC_KEY *x) + { + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) + return 0; + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + EVP_PKEY_free(pk); + return ret; + } + +static int print_bin(BIO *fp, const char *str, const unsigned char *num, + size_t len, int off); + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) + { + unsigned char *buffer=NULL; + size_t buf_len=0, i; + int ret=0, reason=ERR_R_BIO_LIB; + BN_CTX *ctx=NULL; + const EC_POINT *point=NULL; + BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL, + *order=NULL, *cofactor=NULL; + const unsigned char *seed; + size_t seed_len=0; + + static const char *gen_compressed = "Generator (compressed):"; + static const char *gen_uncompressed = "Generator (uncompressed):"; + static const char *gen_hybrid = "Generator (hybrid):"; + + if (!x) + { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (EC_GROUP_get_asn1_flag(x)) + { + /* the curve parameter are given by an asn1 OID */ + int nid; + + if (!BIO_indent(bp, off, 128)) + goto err; + + nid = EC_GROUP_get_curve_name(x); + if (nid == 0) + goto err; + + if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) + goto err; + if (BIO_printf(bp, "\n") <= 0) + goto err; + } + else + { + /* explicit parameters */ + int is_char_two = 0; + point_conversion_form_t form; + int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); + + if (tmp_nid == NID_X9_62_characteristic_two_field) + is_char_two = 1; + + if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || + (b = BN_new()) == NULL || (order = BN_new()) == NULL || + (cofactor = BN_new()) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (is_char_two) + { + if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) + { + reason = ERR_R_EC_LIB; + goto err; + } + } + else /* prime field */ + { + if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) + { + reason = ERR_R_EC_LIB; + goto err; + } + } + + if ((point = EC_GROUP_get0_generator(x)) == NULL) + { + reason = ERR_R_EC_LIB; + goto err; + } + if (!EC_GROUP_get_order(x, order, NULL) || + !EC_GROUP_get_cofactor(x, cofactor, NULL)) + { + reason = ERR_R_EC_LIB; + goto err; + } + + form = EC_GROUP_get_point_conversion_form(x); + + if ((gen = EC_POINT_point2bn(x, point, + form, NULL, ctx)) == NULL) + { + reason = ERR_R_EC_LIB; + goto err; + } + + buf_len = (size_t)BN_num_bytes(p); + if (buf_len < (i = (size_t)BN_num_bytes(a))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(b))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(gen))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(order))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) + buf_len = i; + + if ((seed = EC_GROUP_get0_seed(x)) != NULL) + seed_len = EC_GROUP_get_seed_len(x); + + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (!BIO_indent(bp, off, 128)) + goto err; + + /* print the 'short name' of the field type */ + if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) + <= 0) + goto err; + + if (is_char_two) + { + /* print the 'short name' of the base type OID */ + int basis_type = EC_GROUP_get_basis_type(x); + if (basis_type == 0) + goto err; + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (BIO_printf(bp, "Basis Type: %s\n", + OBJ_nid2sn(basis_type)) <= 0) + goto err; + + /* print the polynomial */ + if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, + off)) + goto err; + } + else + { + if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off)) + goto err; + } + if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) + goto err; + if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) + goto err; + if (form == POINT_CONVERSION_COMPRESSED) + { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, + buffer, off)) + goto err; + } + else if (form == POINT_CONVERSION_UNCOMPRESSED) + { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, + buffer, off)) + goto err; + } + else /* form == POINT_CONVERSION_HYBRID */ + { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, + buffer, off)) + goto err; + } + if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, + buffer, off)) goto err; + if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, + buffer, off)) goto err; + if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) + goto err; + } + ret=1; +err: + if (!ret) + ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (gen) + BN_free(gen); + if (order) + BN_free(order); + if (cofactor) + BN_free(cofactor); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return(ret); + } + +static int print_bin(BIO *fp, const char *name, const unsigned char *buf, + size_t len, int off) + { + size_t i; + char str[128]; + + if (buf == NULL) + return 1; + if (off) + { + if (off > 128) + off=128; + memset(str,' ',off); + if (BIO_write(fp, str, off) <= 0) + return 0; + } + + if (BIO_printf(fp,"%s", name) <= 0) + return 0; + + for (i=0; ifield_mod_func = src->field_mod_func; @@ -139,34 +135,12 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) group->field_mod_func = BN_nist_mod_192; else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) - { -#ifndef NO_32_BIT_TYPE group->field_mod_func = BN_nist_mod_224; -#else - ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME); - goto err; -#endif - } else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) - { -#ifndef NO_32_BIT_TYPE group->field_mod_func = BN_nist_mod_256; -#else - ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME); - goto err; -#endif - } else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) - { -#ifndef NO_32_BIT_TYPE group->field_mod_func = BN_nist_mod_384; -#else - ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME); - goto err; -#endif - } else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) - /* this one works in the NO_32_BIT_TYPE case */ group->field_mod_func = BN_nist_mod_521; else { diff --git a/crypto/openssl/crypto/ecdh/ech_err.c b/crypto/openssl/crypto/ecdh/ech_err.c index 4d2ede75bd..6f4b0c9953 100644 --- a/crypto/openssl/crypto/ecdh/ech_err.c +++ b/crypto/openssl/crypto/ecdh/ech_err.c @@ -1,6 +1,6 @@ /* crypto/ecdh/ech_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -71,7 +71,7 @@ static ERR_STRING_DATA ECDH_str_functs[]= { {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, -{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_NEW_METHOD"}, +{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/ecdsa/ecdsa.h b/crypto/openssl/crypto/ecdsa/ecdsa.h index f20c8ee738..e61c539812 100644 --- a/crypto/openssl/crypto/ecdsa/ecdsa.h +++ b/crypto/openssl/crypto/ecdsa/ecdsa.h @@ -4,7 +4,7 @@ * \author Written by Nils Larsch for the OpenSSL project */ /* ==================================================================== - * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-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 @@ -81,156 +81,143 @@ typedef struct ECDSA_SIG_st BIGNUM *s; } ECDSA_SIG; -/** ECDSA_SIG *ECDSA_SIG_new(void) - * allocates and initialize a ECDSA_SIG structure - * \return pointer to a ECDSA_SIG structure or NULL if an error occurred +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred */ ECDSA_SIG *ECDSA_SIG_new(void); -/** ECDSA_SIG_free - * frees a ECDSA_SIG structure - * \param a pointer to the ECDSA_SIG structure +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure */ -void ECDSA_SIG_free(ECDSA_SIG *a); +void ECDSA_SIG_free(ECDSA_SIG *sig); -/** i2d_ECDSA_SIG - * DER encode content of ECDSA_SIG object (note: this function modifies *pp - * (*pp += length of the DER encoded signature)). - * \param a pointer to the ECDSA_SIG object - * \param pp pointer to a unsigned char pointer for the output or NULL - * \return the length of the DER encoded ECDSA_SIG object or 0 +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 */ -int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp); +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); -/** d2i_ECDSA_SIG - * decodes a DER encoded ECDSA signature (note: this function changes *pp - * (*pp += len)). - * \param v pointer to ECDSA_SIG pointer (may be NULL) - * \param pp buffer with the DER encoded signature - * \param len bufferlength - * \return pointer to the decoded ECDSA_SIG structure (or NULL) +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) */ -ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len); +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); -/** ECDSA_do_sign - * computes the ECDSA signature of the given hash value using - * the supplied private key and returns the created signature. - * \param dgst pointer to the hash value - * \param dgst_len length of the hash value - * \param eckey pointer to the EC_KEY object containing a private EC key - * \return pointer to a ECDSA_SIG structure or NULL +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred */ ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); -/** ECDSA_do_sign_ex - * computes ECDSA signature of a given hash value using the supplied - * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). - * \param dgst pointer to the hash value to sign - * \param dgstlen length of the hash value - * \param kinv optional pointer to a pre-computed inverse k - * \param rp optional pointer to the pre-computed rp value (see - * ECDSA_sign_setup - * \param eckey pointer to the EC_KEY object containing a private EC key - * \return pointer to a ECDSA_SIG structure or NULL +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred */ ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); -/** ECDSA_do_verify - * verifies that the supplied signature is a valid ECDSA - * signature of the supplied hash value using the supplied public key. - * \param dgst pointer to the hash value - * \param dgst_len length of the hash value - * \param sig pointer to the ECDSA_SIG structure - * \param eckey pointer to the EC_KEY object containing a public EC key - * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error */ int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY* eckey); const ECDSA_METHOD *ECDSA_OpenSSL(void); -/** ECDSA_set_default_method - * sets the default ECDSA method - * \param meth the new default ECDSA_METHOD +/** Sets the default ECDSA method + * \param meth new default ECDSA_METHOD */ void ECDSA_set_default_method(const ECDSA_METHOD *meth); -/** ECDSA_get_default_method - * returns the default ECDSA method - * \return pointer to ECDSA_METHOD structure containing the default method +/** Returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method */ const ECDSA_METHOD *ECDSA_get_default_method(void); -/** ECDSA_set_method - * sets method to be used for the ECDSA operations - * \param eckey pointer to the EC_KEY object - * \param meth pointer to the new method - * \return 1 on success and 0 otherwise +/** Sets method to be used for the ECDSA operations + * \param eckey EC_KEY object + * \param meth new method + * \return 1 on success and 0 otherwise */ int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); -/** ECDSA_size - * returns the maximum length of the DER encoded signature - * \param eckey pointer to a EC_KEY object - * \return numbers of bytes required for the DER encoded signature +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature */ int ECDSA_size(const EC_KEY *eckey); -/** ECDSA_sign_setup - * precompute parts of the signing operation. - * \param eckey pointer to the EC_KEY object containing a private EC key - * \param ctx pointer to a BN_CTX object (may be NULL) - * \param kinv pointer to a BIGNUM pointer for the inverse of k - * \param rp pointer to a BIGNUM pointer for x coordinate of k * generator - * \return 1 on success and 0 otherwise +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise */ int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); -/** ECDSA_sign - * computes ECDSA signature of a given hash value using the supplied - * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). - * \param type this parameter is ignored - * \param dgst pointer to the hash value to sign - * \param dgstlen length of the hash value - * \param sig buffer to hold the DER encoded signature - * \param siglen pointer to the length of the returned signature - * \param eckey pointer to the EC_KEY object containing a private EC key - * \return 1 on success and 0 otherwise +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise */ int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); -/** ECDSA_sign_ex - * computes ECDSA signature of a given hash value using the supplied - * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). - * \param type this parameter is ignored - * \param dgst pointer to the hash value to sign - * \param dgstlen length of the hash value - * \param sig buffer to hold the DER encoded signature - * \param siglen pointer to the length of the returned signature - * \param kinv optional pointer to a pre-computed inverse k - * \param rp optional pointer to the pre-computed rp value (see - * ECDSA_sign_setup - * \param eckey pointer to the EC_KEY object containing a private EC key - * \return 1 on success and 0 otherwise +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise */ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); -/** ECDSA_verify - * verifies that the given signature is valid ECDSA signature - * of the supplied hash value using the specified public key. - * \param type this parameter is ignored - * \param dgst pointer to the hash value - * \param dgstlen length of the hash value - * \param sig pointer to the DER encoded signature - * \param siglen length of the DER encoded signature - * \param eckey pointer to the EC_KEY object containing a public EC key - * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error */ int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, const unsigned char *sig, int siglen, EC_KEY *eckey); diff --git a/crypto/openssl/crypto/ecdsa/ecs_err.c b/crypto/openssl/crypto/ecdsa/ecs_err.c index d2a53730ea..98e38d537f 100644 --- a/crypto/openssl/crypto/ecdsa/ecs_err.c +++ b/crypto/openssl/crypto/ecdsa/ecs_err.c @@ -1,6 +1,6 @@ /* crypto/ecdsa/ecs_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/engine/eng_all.c b/crypto/openssl/crypto/engine/eng_all.c index d29cd57dc2..22c120454f 100644 --- a/crypto/openssl/crypto/engine/eng_all.c +++ b/crypto/openssl/crypto/engine/eng_all.c @@ -61,15 +61,15 @@ void ENGINE_load_builtin_engines(void) { +#if 0 /* There's no longer any need for an "openssl" ENGINE unless, one day, * it is the *only* way for standard builtin implementations to be be * accessed (ie. it would be possible to statically link binaries with * *no* builtin implementations). */ -#if 0 ENGINE_load_openssl(); #endif -#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) - ENGINE_load_padlock(); +#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) + ENGINE_load_cryptodev(); #endif ENGINE_load_dynamic(); #ifndef OPENSSL_NO_STATIC_ENGINE @@ -98,14 +98,15 @@ void ENGINE_load_builtin_engines(void) #ifndef OPENSSL_NO_HW_UBSEC ENGINE_load_ubsec(); #endif +#ifndef OPENSSL_NO_HW_PADLOCK + ENGINE_load_padlock(); #endif -#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP) - ENGINE_load_gmp(); #endif +#ifndef OPENSSL_NO_GOST + ENGINE_load_gost(); #endif -#ifndef OPENSSL_NO_HW -#if defined(__OpenBSD__) || defined(__FreeBSD__) - ENGINE_load_cryptodev(); +#ifndef OPENSSL_NO_GMP + ENGINE_load_gmp(); #endif #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) ENGINE_load_capi(); @@ -113,7 +114,7 @@ void ENGINE_load_builtin_engines(void) #endif } -#if defined(__OpenBSD__) || defined(__FreeBSD__) +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) void ENGINE_setup_bsd_cryptodev(void) { static int bsd_cryptodev_default_loaded = 0; if (!bsd_cryptodev_default_loaded) { diff --git a/crypto/openssl/crypto/engine/eng_cryptodev.c b/crypto/openssl/crypto/engine/eng_cryptodev.c index 1a1e1c2655..52f4ca3901 100644 --- a/crypto/openssl/crypto/engine/eng_cryptodev.c +++ b/crypto/openssl/crypto/engine/eng_cryptodev.c @@ -30,10 +30,6 @@ #include #include #include -#include -#include -#include -#include #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ (defined(OpenBSD) || defined(__FreeBSD__)) @@ -59,6 +55,10 @@ ENGINE_load_cryptodev(void) #include #include +#include +#include +#include +#include #include #include #include @@ -72,6 +72,16 @@ ENGINE_load_cryptodev(void) struct dev_crypto_state { struct session_op d_sess; int d_fd; + +#ifdef USE_CRYPTODEV_DIGESTS + char dummy_mac_key[HASH_MAX_LEN]; + + unsigned char digest_res[HASH_MAX_LEN]; + char *mac_data; + int mac_len; + + int copy; +#endif }; static u_int32_t cryptodev_asymfeat = 0; @@ -79,15 +89,14 @@ static u_int32_t cryptodev_asymfeat = 0; static int get_asym_dev_crypto(void); static int open_dev_crypto(void); static int get_dev_crypto(void); -static int cryptodev_max_iv(int cipher); -static int cryptodev_key_length_valid(int cipher, int len); -static int cipher_nid_to_cryptodev(int nid); static int get_cryptodev_ciphers(const int **cnids); -/*static int get_cryptodev_digests(const int **cnids);*/ +#ifdef USE_CRYPTODEV_DIGESTS +static int get_cryptodev_digests(const int **cnids); +#endif static int cryptodev_usable_ciphers(const int **nids); static int cryptodev_usable_digests(const int **nids); static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl); + const unsigned char *in, size_t inl); static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); @@ -121,7 +130,7 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f)()); + void (*f)(void)); void ENGINE_load_cryptodev(void); static const ENGINE_CMD_DEFN cryptodev_defns[] = { @@ -134,27 +143,32 @@ static struct { int ivmax; int keylen; } ciphers[] = { + { CRYPTO_ARC4, NID_rc4, 0, 16, }, { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, + { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, }, + { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, }, { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, { 0, NID_undef, 0, 0, }, }; -#if 0 +#ifdef USE_CRYPTODEV_DIGESTS static struct { int id; int nid; + int keylen; } digests[] = { - { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, }, - { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, }, - { CRYPTO_MD5_KPDK, NID_undef, }, - { CRYPTO_SHA1_KPDK, NID_undef, }, - { CRYPTO_MD5, NID_md5, }, - { CRYPTO_SHA1, NID_undef, }, - { 0, NID_undef, }, + { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16}, + { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20}, + { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/}, + { CRYPTO_MD5_KPDK, NID_undef, 0}, + { CRYPTO_SHA1_KPDK, NID_undef, 0}, + { CRYPTO_MD5, NID_md5, 16}, + { CRYPTO_SHA1, NID_sha1, 20}, + { 0, NID_undef, 0}, }; #endif @@ -208,50 +222,6 @@ get_asym_dev_crypto(void) return fd; } -/* - * XXXX this needs to be set for each alg - and determined from - * a running card. - */ -static int -cryptodev_max_iv(int cipher) -{ - int i; - - for (i = 0; ciphers[i].id; i++) - if (ciphers[i].id == cipher) - return (ciphers[i].ivmax); - return (0); -} - -/* - * XXXX this needs to be set for each alg - and determined from - * a running card. For now, fake it out - but most of these - * for real devices should return 1 for the supported key - * sizes the device can handle. - */ -static int -cryptodev_key_length_valid(int cipher, int len) -{ - int i; - - for (i = 0; ciphers[i].id; i++) - if (ciphers[i].id == cipher) - return (ciphers[i].keylen == len); - return (0); -} - -/* convert libcrypto nids to cryptodev */ -static int -cipher_nid_to_cryptodev(int nid) -{ - int i; - - for (i = 0; ciphers[i].id; i++) - if (ciphers[i].nid == nid) - return (ciphers[i].id); - return (0); -} - /* * Find out what ciphers /dev/crypto will let us have a session for. * XXX note, that some of these openssl doesn't deal with yet! @@ -270,7 +240,7 @@ get_cryptodev_ciphers(const int **cnids) return (0); } memset(&sess, 0, sizeof(sess)); - sess.key = (caddr_t)"123456781234567812345678"; + sess.key = (caddr_t)"123456789abcdefghijklmno"; for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { if (ciphers[i].nid == NID_undef) @@ -291,7 +261,7 @@ get_cryptodev_ciphers(const int **cnids) return (count); } -#if 0 /* unused */ +#ifdef USE_CRYPTODEV_DIGESTS /* * Find out what digests /dev/crypto will let us have a session for. * XXX note, that some of these openssl doesn't deal with yet! @@ -310,10 +280,12 @@ get_cryptodev_digests(const int **cnids) return (0); } memset(&sess, 0, sizeof(sess)); + sess.mackey = (caddr_t)"123456789abcdefghijklmno"; for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { if (digests[i].nid == NID_undef) continue; sess.mac = digests[i].id; + sess.mackeylen = digests[i].keylen; sess.cipher = 0; if (ioctl(fd, CIOCGSESSION, &sess) != -1 && ioctl(fd, CIOCFSESSION, &sess.ses) != -1) @@ -327,8 +299,7 @@ get_cryptodev_digests(const int **cnids) *cnids = NULL; return (count); } - -#endif +#endif /* 0 */ /* * Find the useable ciphers|digests from dev/crypto - this is the first @@ -360,6 +331,9 @@ cryptodev_usable_ciphers(const int **nids) static int cryptodev_usable_digests(const int **nids) { +#ifdef USE_CRYPTODEV_DIGESTS + return (get_cryptodev_digests(nids)); +#else /* * XXXX just disable all digests for now, because it sucks. * we need a better way to decide this - i.e. I may not @@ -374,11 +348,12 @@ cryptodev_usable_digests(const int **nids) */ *nids = NULL; return (0); +#endif } static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { struct crypt_op cryp; struct dev_crypto_state *state = ctx->cipher_data; @@ -436,23 +411,27 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, { struct dev_crypto_state *state = ctx->cipher_data; struct session_op *sess = &state->d_sess; - int cipher; - - if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) - return (0); + int cipher = -1, i; - if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) - return (0); + for (i = 0; ciphers[i].id; i++) + if (ctx->cipher->nid == ciphers[i].nid && + ctx->cipher->iv_len <= ciphers[i].ivmax && + ctx->key_len == ciphers[i].keylen) { + cipher = ciphers[i].id; + break; + } - if (!cryptodev_key_length_valid(cipher, ctx->key_len)) + if (!ciphers[i].id) { + state->d_fd = -1; return (0); + } memset(sess, 0, sizeof(struct session_op)); if ((state->d_fd = get_dev_crypto()) < 0) return (0); - sess->key = (char *)key; + sess->key = (caddr_t)key; sess->keylen = ctx->key_len; sess->cipher = cipher; @@ -505,6 +484,20 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) * gets called when libcrypto requests a cipher NID. */ +/* RC4 */ +const EVP_CIPHER cryptodev_rc4 = { + NID_rc4, + 1, 16, 0, + EVP_CIPH_VARIABLE_LENGTH, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + NULL, + NULL, + NULL +}; + /* DES CBC EVP */ const EVP_CIPHER cryptodev_des_cbc = { NID_des_cbc, @@ -572,6 +565,32 @@ const EVP_CIPHER cryptodev_aes_cbc = { NULL }; +const EVP_CIPHER cryptodev_aes_192_cbc = { + NID_aes_192_cbc, + 16, 24, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_256_cbc = { + NID_aes_256_cbc, + 16, 32, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + /* * Registered by the ENGINE when used to find out how to deal with * a particular NID in the ENGINE. this says what we'll do at the @@ -585,6 +604,9 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, return (cryptodev_usable_ciphers(nids)); switch (nid) { + case NID_rc4: + *cipher = &cryptodev_rc4; + break; case NID_des_ede3_cbc: *cipher = &cryptodev_3des_cbc; break; @@ -600,6 +622,12 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, case NID_aes_128_cbc: *cipher = &cryptodev_aes_cbc; break; + case NID_aes_192_cbc: + *cipher = &cryptodev_aes_192_cbc; + break; + case NID_aes_256_cbc: + *cipher = &cryptodev_aes_256_cbc; + break; default: *cipher = NULL; break; @@ -607,6 +635,234 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, return (*cipher != NULL); } + +#ifdef USE_CRYPTODEV_DIGESTS + +/* convert digest type to cryptodev */ +static int +digest_nid_to_cryptodev(int nid) +{ + int i; + + for (i = 0; digests[i].id; i++) + if (digests[i].nid == nid) + return (digests[i].id); + return (0); +} + + +static int +digest_key_length(int nid) +{ + int i; + + for (i = 0; digests[i].id; i++) + if (digests[i].nid == nid) + return digests[i].keylen; + return (0); +} + + +static int cryptodev_digest_init(EVP_MD_CTX *ctx) +{ + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + int digest; + + if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){ + printf("cryptodev_digest_init: Can't get digest \n"); + return (0); + } + + memset(state, 0, sizeof(struct dev_crypto_state)); + + if ((state->d_fd = get_dev_crypto()) < 0) { + printf("cryptodev_digest_init: Can't get Dev \n"); + return (0); + } + + sess->mackey = state->dummy_mac_key; + sess->mackeylen = digest_key_length(ctx->digest->type); + sess->mac = digest; + + if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { + close(state->d_fd); + state->d_fd = -1; + printf("cryptodev_digest_init: Open session failed\n"); + return (0); + } + + return (1); +} + +static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, + size_t count) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + if (!data || state->d_fd < 0) { + printf("cryptodev_digest_update: illegal inputs \n"); + return (0); + } + + if (!count) { + return (0); + } + + if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + /* if application doesn't support one buffer */ + state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); + + if (!state->mac_data) { + printf("cryptodev_digest_update: realloc failed\n"); + return (0); + } + + memcpy(state->mac_data + state->mac_len, data, count); + state->mac_len += count; + + return (1); + } + + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = count; + cryp.src = (caddr_t) data; + cryp.dst = NULL; + cryp.mac = (caddr_t) state->digest_res; + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { + printf("cryptodev_digest_update: digest failed\n"); + return (0); + } + return (1); +} + + +static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + int ret = 1; + + if (!md || state->d_fd < 0) { + printf("cryptodev_digest_final: illegal input\n"); + return(0); + } + + if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) { + /* if application doesn't support one buffer */ + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = state->mac_len; + cryp.src = state->mac_data; + cryp.dst = NULL; + cryp.mac = (caddr_t)md; + + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { + printf("cryptodev_digest_final: digest failed\n"); + return (0); + } + + return 1; + } + + memcpy(md, state->digest_res, ctx->digest->md_size); + + return (ret); +} + + +static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) +{ + int ret = 1; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + if (state->d_fd < 0) { + printf("cryptodev_digest_cleanup: illegal input\n"); + return (0); + } + + if (state->mac_data) { + OPENSSL_free(state->mac_data); + state->mac_data = NULL; + state->mac_len = 0; + } + + if (state->copy) + return 1; + + if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { + printf("cryptodev_digest_cleanup: failed to close session\n"); + ret = 0; + } else { + ret = 1; + } + close(state->d_fd); + state->d_fd = -1; + + return (ret); +} + +static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) +{ + struct dev_crypto_state *fstate = from->md_data; + struct dev_crypto_state *dstate = to->md_data; + + memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); + + if (fstate->mac_len != 0) { + dstate->mac_data = OPENSSL_malloc(fstate->mac_len); + memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); + } + + dstate->copy = 1; + + return 1; +} + + +const EVP_MD cryptodev_sha1 = { + NID_sha1, + NID_undef, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_ONESHOT, + cryptodev_digest_init, + cryptodev_digest_update, + cryptodev_digest_final, + cryptodev_digest_copy, + cryptodev_digest_cleanup, + EVP_PKEY_NULL_method, + SHA_CBLOCK, + sizeof(struct dev_crypto_state), +}; + +const EVP_MD cryptodev_md5 = { + NID_md5, + NID_undef, + 16 /* MD5_DIGEST_LENGTH */, + EVP_MD_FLAG_ONESHOT, + cryptodev_digest_init, + cryptodev_digest_update, + cryptodev_digest_final, + cryptodev_digest_copy, + cryptodev_digest_cleanup, + EVP_PKEY_NULL_method, + 64 /* MD5_CBLOCK */, + sizeof(struct dev_crypto_state), +}; + +#endif /* USE_CRYPTODEV_DIGESTS */ + + static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid) @@ -615,10 +871,15 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, return (cryptodev_usable_digests(nids)); switch (nid) { +#ifdef USE_CRYPTODEV_DIGESTS case NID_md5: - *digest = NULL; /* need to make a clean md5 critter */ + *digest = &cryptodev_md5; break; + case NID_sha1: + *digest = &cryptodev_sha1; + break; default: +#endif /* USE_CRYPTODEV_DIGESTS */ *digest = NULL; break; } @@ -646,8 +907,9 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) b = malloc(bytes); if (b == NULL) return (1); + memset(b, 0, bytes); - crp->crp_p = (char *)b; + crp->crp_p = (caddr_t) b; crp->crp_nbits = bits; for (i = 0, j = 0; i < a->top; i++) { @@ -690,7 +952,7 @@ zapparams(struct crypt_kop *kop) { int i; - for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) { + for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { if (kop->crk_param[i].crp_p) free(kop->crk_param[i].crp_p); kop->crk_param[i].crp_p = NULL; @@ -755,10 +1017,18 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, goto err; kop.crk_iparams = 3; - if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) { + if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF asym process failed, Running in software\n"); + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + + } else if (ECANCELED == kop.crk_status) { const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF hardware operation cancelled. Running in Software\n"); ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); } + /* else cryptodev operation worked ok ==> ret = 1*/ + err: zapparams(&kop); return (ret); @@ -768,8 +1038,9 @@ static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { int r; - + ctx = BN_CTX_new(); r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); + BN_CTX_free(ctx); return (r); } @@ -801,10 +1072,18 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) goto err; kop.crk_iparams = 6; - if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { + if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF asym process failed, running in Software\n"); + ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); + + } else if (ECANCELED == kop.crk_status) { const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF hardware operation cancelled. Running in Software\n"); ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); } + /* else cryptodev operation worked ok ==> ret = 1*/ + err: zapparams(&kop); return (ret); @@ -940,7 +1219,8 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, kop.crk_iparams = 7; if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { - dsaret = kop.crk_status; +/*OCF success value is 0, if not zero, change dsaret to fail*/ + if(0 != kop.crk_status) dsaret = 0; } else { const DSA_METHOD *meth = DSA_OpenSSL(); @@ -1000,7 +1280,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) goto err; kop.crk_iparams = 3; - kop.crk_param[3].crp_p = (char *)key; + kop.crk_param[3].crp_p = (caddr_t) key; kop.crk_param[3].crp_nbits = keylen * 8; kop.crk_oparams = 1; @@ -1031,7 +1311,7 @@ static DH_METHOD cryptodev_dh = { * but I expect we'll want some options soon. */ static int -cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) +cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) { #ifdef HAVE_SYSLOG_R struct syslog_data sd = SYSLOG_DATA_INIT; diff --git a/crypto/openssl/crypto/engine/eng_dyn.c b/crypto/openssl/crypto/engine/eng_dyn.c index acb30c34d8..807da7a5eb 100644 --- a/crypto/openssl/crypto/engine/eng_dyn.c +++ b/crypto/openssl/crypto/engine/eng_dyn.c @@ -146,14 +146,14 @@ struct st_dynamic_data_ctx * 'dirs' for loading. Default is to use 'dirs' as a fallback. */ int dir_load; /* A stack of directories from which ENGINEs could be loaded */ - STACK *dirs; + STACK_OF(OPENSSL_STRING) *dirs; }; /* This is the "ex_data" index we obtain and reserve for use with our context * structure. */ static int dynamic_ex_data_idx = -1; -static void int_free_str(void *s) { OPENSSL_free(s); } +static void int_free_str(char *s) { OPENSSL_free(s); } /* Because our ex_data element may or may not get allocated depending on whether * a "first-use" occurs before the ENGINE is freed, we have a memory leak * problem to solve. We can't declare a "new" handler for the ex_data as we @@ -174,7 +174,7 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr, if(ctx->engine_id) OPENSSL_free((void*)ctx->engine_id); if(ctx->dirs) - sk_pop_free(ctx->dirs, int_free_str); + sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str); OPENSSL_free(ctx); } } @@ -203,7 +203,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) c->DYNAMIC_F1 = "v_check"; c->DYNAMIC_F2 = "bind_engine"; c->dir_load = 1; - c->dirs = sk_new_null(); + c->dirs = sk_OPENSSL_STRING_new_null(); if(!c->dirs) { ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); @@ -393,7 +393,7 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) ERR_R_MALLOC_FAILURE); return 0; } - sk_insert(ctx->dirs, tmp_str, -1); + sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1); } return 1; default: @@ -411,11 +411,11 @@ static int int_load(dynamic_data_ctx *ctx) ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL) return 1; /* If we're not allowed to use 'dirs' or we have none, fail */ - if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1)) + if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1) return 0; for(loop = 0; loop < num; loop++) { - const char *s = sk_value(ctx->dirs, loop); + const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop); char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); if(!merge) return 0; diff --git a/crypto/openssl/crypto/engine/eng_err.c b/crypto/openssl/crypto/engine/eng_err.c index ac74dd127a..81c70acfa8 100644 --- a/crypto/openssl/crypto/engine/eng_err.c +++ b/crypto/openssl/crypto/engine/eng_err.c @@ -86,6 +86,8 @@ static ERR_STRING_DATA ENGINE_str_functs[]= {ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"}, +{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"}, +{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"}, {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"}, {ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"}, {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"}, @@ -151,6 +153,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]= {ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"}, {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"}, {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"}, +{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"}, {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/engine/eng_fat.c b/crypto/openssl/crypto/engine/eng_fat.c index 27c1662f62..db66e62350 100644 --- a/crypto/openssl/crypto/engine/eng_fat.c +++ b/crypto/openssl/crypto/engine/eng_fat.c @@ -89,6 +89,12 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags) #endif if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) return 0; + if((flags & ENGINE_METHOD_PKEY_METHS) + && !ENGINE_set_default_pkey_meths(e)) + return 0; + if((flags & ENGINE_METHOD_PKEY_ASN1_METHS) + && !ENGINE_set_default_pkey_asn1_meths(e)) + return 0; return 1; } @@ -115,6 +121,13 @@ static int int_def_cb(const char *alg, int len, void *arg) *pflags |= ENGINE_METHOD_CIPHERS; else if (!strncmp(alg, "DIGESTS", len)) *pflags |= ENGINE_METHOD_DIGESTS; + else if (!strncmp(alg, "PKEY", len)) + *pflags |= + ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS; + else if (!strncmp(alg, "PKEY_CRYPTO", len)) + *pflags |= ENGINE_METHOD_PKEY_METHS; + else if (!strncmp(alg, "PKEY_ASN1", len)) + *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS; else return 0; return 1; @@ -154,6 +167,7 @@ int ENGINE_register_complete(ENGINE *e) ENGINE_register_ECDSA(e); #endif ENGINE_register_RAND(e); + ENGINE_register_pkey_meths(e); return 1; } diff --git a/crypto/openssl/crypto/engine/eng_int.h b/crypto/openssl/crypto/engine/eng_int.h index a66f107a44..451ef8feb8 100644 --- a/crypto/openssl/crypto/engine/eng_int.h +++ b/crypto/openssl/crypto/engine/eng_int.h @@ -127,6 +127,8 @@ ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l); #define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) #endif +typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg); +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg); /* Internal versions of API functions that have control over locking. These are * used between C files when functionality needs to be shared but the caller may @@ -143,6 +145,11 @@ void engine_set_all_null(ENGINE *e); /* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed * in engine.h. */ +/* Free up dynamically allocated public key methods associated with ENGINE */ + +void engine_pkey_meths_free(ENGINE *e); +void engine_pkey_asn1_meths_free(ENGINE *e); + /* This is a structure for storing implementations of various crypto * algorithms and functions. */ struct engine_st @@ -160,7 +167,10 @@ struct engine_st ENGINE_CIPHERS_PTR ciphers; /* Digest handling is via this callback */ ENGINE_DIGESTS_PTR digests; - + /* Public key handling via this callback */ + ENGINE_PKEY_METHS_PTR pkey_meths; + /* ASN1 public key handling via this callback */ + ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths; ENGINE_GEN_INT_FUNC_PTR destroy; diff --git a/crypto/openssl/crypto/engine/eng_lib.c b/crypto/openssl/crypto/engine/eng_lib.c index 5815b867f4..18a6664645 100644 --- a/crypto/openssl/crypto/engine/eng_lib.c +++ b/crypto/openssl/crypto/engine/eng_lib.c @@ -125,6 +125,9 @@ int engine_free_util(ENGINE *e, int locked) abort(); } #endif + /* Free up any dynamically allocated public key methods */ + engine_pkey_meths_free(e); + engine_pkey_asn1_meths_free(e); /* Give the ENGINE a chance to do any structural cleanup corresponding * to allocation it did in its constructor (eg. unload error strings) */ if(e->destroy) diff --git a/crypto/openssl/crypto/engine/eng_list.c b/crypto/openssl/crypto/engine/eng_list.c index bd511944ba..27846edb1e 100644 --- a/crypto/openssl/crypto/engine/eng_list.c +++ b/crypto/openssl/crypto/engine/eng_list.c @@ -336,6 +336,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src) dest->store_meth = src->store_meth; dest->ciphers = src->ciphers; dest->digests = src->digests; + dest->pkey_meths = src->pkey_meths; dest->destroy = src->destroy; dest->init = src->init; dest->finish = src->finish; @@ -412,6 +413,7 @@ ENGINE *ENGINE_by_id(const char *id) return iterator; } notfound: + ENGINE_free(iterator); ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE); ERR_add_error_data(2, "id=", id); return NULL; diff --git a/crypto/openssl/crypto/engine/eng_openssl.c b/crypto/openssl/crypto/engine/eng_openssl.c index 7c139ae2ef..9abb95cc22 100644 --- a/crypto/openssl/crypto/engine/eng_openssl.c +++ b/crypto/openssl/crypto/engine/eng_openssl.c @@ -238,7 +238,7 @@ static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; } static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { #ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); diff --git a/crypto/openssl/crypto/engine/eng_table.c b/crypto/openssl/crypto/engine/eng_table.c index 8fc47b3399..4fde948185 100644 --- a/crypto/openssl/crypto/engine/eng_table.c +++ b/crypto/openssl/crypto/engine/eng_table.c @@ -70,12 +70,22 @@ typedef struct st_engine_pile int uptodate; } ENGINE_PILE; +DECLARE_LHASH_OF(ENGINE_PILE); + /* The type exposed in eng_int.h */ struct st_engine_table { - LHASH piles; + LHASH_OF(ENGINE_PILE) piles; }; /* ENGINE_TABLE */ + +typedef struct st_engine_pile_doall + { + engine_table_doall_cb *cb; + void *arg; + } ENGINE_PILE_DOALL; + + /* Global flags (ENGINE_TABLE_FLAG_***). */ static unsigned int table_flags = 0; @@ -84,6 +94,7 @@ unsigned int ENGINE_get_table_flags(void) { return table_flags; } + void ENGINE_set_table_flags(unsigned int flags) { table_flags = flags; @@ -94,19 +105,21 @@ static unsigned long engine_pile_hash(const ENGINE_PILE *c) { return c->nid; } + static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) { return a->nid - b->nid; } -static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) -static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) +static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE) +static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE) + static int int_table_check(ENGINE_TABLE **t, int create) { - LHASH *lh; + LHASH_OF(ENGINE_PILE) *lh; + if(*t) return 1; if(!create) return 0; - if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), - LHASH_COMP_FN(engine_pile_cmp))) == NULL) + if((lh = lh_ENGINE_PILE_new()) == NULL) return 0; *t = (ENGINE_TABLE *)lh; return 1; @@ -130,7 +143,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, while(num_nids--) { tmplate.nid = *nids; - fnd = lh_retrieve(&(*table)->piles, &tmplate); + fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); if(!fnd) { fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); @@ -144,7 +157,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, goto end; } fnd->funct = NULL; - lh_insert(&(*table)->piles, fnd); + (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); } /* A registration shouldn't add duplciate entries */ (void)sk_ENGINE_delete_ptr(fnd->sk, e); @@ -173,7 +186,7 @@ end: CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return ret; } -static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) +static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e) { int n; /* Iterate the 'c->sk' stack removing any occurance of 'e' */ @@ -188,31 +201,35 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) pile->funct = NULL; } } -static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE) + void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) { CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if(int_table_check(table, 0)) - lh_doall_arg(&(*table)->piles, - LHASH_DOALL_ARG_FN(int_unregister_cb), e); + lh_ENGINE_PILE_doall_arg(&(*table)->piles, + LHASH_DOALL_ARG_FN(int_unregister_cb), + ENGINE, e); CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); } -static void int_cleanup_cb(ENGINE_PILE *p) +static void int_cleanup_cb_doall(ENGINE_PILE *p) { sk_ENGINE_free(p->sk); if(p->funct) engine_unlocked_finish(p->funct, 0); OPENSSL_free(p); } -static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) +static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE) + void engine_table_cleanup(ENGINE_TABLE **table) { CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if(*table) { - lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); - lh_free(&(*table)->piles); + lh_ENGINE_PILE_doall(&(*table)->piles, + LHASH_DOALL_FN(int_cleanup_cb)); + lh_ENGINE_PILE_free(&(*table)->piles); *table = NULL; } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); @@ -243,7 +260,7 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in * operations. But don't worry about a fprintf(stderr). */ if(!int_table_check(table, 0)) goto end; tmplate.nid = nid; - fnd = lh_retrieve(&(*table)->piles, &tmplate); + fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); if(!fnd) goto end; if(fnd->funct && engine_unlocked_init(fnd->funct)) { @@ -314,3 +331,21 @@ end: ERR_pop_to_mark(); return ret; } + +/* Table enumeration */ + +static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) + { + dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); + } +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL) + +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, + void *arg) + { + ENGINE_PILE_DOALL dall; + dall.cb = cb; + dall.arg = arg; + lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb), + ENGINE_PILE_DOALL, &dall); + } diff --git a/crypto/openssl/crypto/engine/engine.h b/crypto/openssl/crypto/engine/engine.h index d4bc1efc79..7fbd95f634 100644 --- a/crypto/openssl/crypto/engine/engine.h +++ b/crypto/openssl/crypto/engine/engine.h @@ -88,16 +88,15 @@ #include #endif #include -#include #include #include #endif -#include - #include #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -113,6 +112,8 @@ extern "C" { #define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 #define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 #define ENGINE_METHOD_STORE (unsigned int)0x0100 +#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 /* Obvious all-or-nothing cases. */ #define ENGINE_METHOD_ALL (unsigned int)0xFFFF #define ENGINE_METHOD_NONE (unsigned int)0x0000 @@ -297,7 +298,8 @@ typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl, * parameter is non-NULL it is set to the size of the returned array. */ typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int); typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); - +typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int); /* STRUCTURE functions ... all of these functions deal with pointers to ENGINE * structures where the pointers have a "structural reference". This means that * their reference is to allowed access to the structure but it does not imply @@ -329,21 +331,20 @@ void ENGINE_load_aep(void); void ENGINE_load_atalla(void); void ENGINE_load_chil(void); void ENGINE_load_cswift(void); -#ifndef OPENSSL_NO_GMP -void ENGINE_load_gmp(void); -#endif void ENGINE_load_nuron(void); void ENGINE_load_sureware(void); void ENGINE_load_ubsec(void); -#endif -void ENGINE_load_cryptodev(void); void ENGINE_load_padlock(void); -void ENGINE_load_builtin_engines(void); -#ifdef OPENSSL_SYS_WIN32 -#ifndef OPENSSL_NO_CAPIENG void ENGINE_load_capi(void); +#ifndef OPENSSL_NO_GMP +void ENGINE_load_gmp(void); +#endif +#ifndef OPENSSL_NO_GOST +void ENGINE_load_gost(void); #endif #endif +void ENGINE_load_cryptodev(void); +void ENGINE_load_builtin_engines(void); /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation * "registry" handling. */ @@ -394,6 +395,14 @@ int ENGINE_register_digests(ENGINE *e); void ENGINE_unregister_digests(ENGINE *e); void ENGINE_register_all_digests(void); +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + /* These functions register all support from the above categories. Note, use of * these functions can result in static linkage of code your application may not * need. If you only need a subset of functionality, consider using more @@ -473,6 +482,8 @@ int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, ENGINE_SSL_CLIENT_CERT_PTR loadssl_f); int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); int ENGINE_set_flags(ENGINE *e, int flags); int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); /* These functions allow control over any per-structure ENGINE data. */ @@ -509,8 +520,16 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, int len); const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); int ENGINE_get_flags(const ENGINE *e); @@ -562,6 +581,8 @@ ENGINE *ENGINE_get_default_RAND(void); * ciphering or digesting corresponding to "nid". */ ENGINE *ENGINE_get_cipher_engine(int nid); ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); /* This sets a new default ENGINE structure for performing RSA * operations. If the result is non-zero (success) then the ENGINE @@ -577,6 +598,8 @@ int ENGINE_set_default_DH(ENGINE *e); int ENGINE_set_default_RAND(ENGINE *e); int ENGINE_set_default_ciphers(ENGINE *e); int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); /* The combination "set" - the flags are bitwise "OR"d from the * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" @@ -705,7 +728,7 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id, * values. */ void *ENGINE_get_static_state(void); -#if defined(__OpenBSD__) || defined(__FreeBSD__) +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) void ENGINE_setup_bsd_cryptodev(void); #endif @@ -734,13 +757,15 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 #define ENGINE_F_ENGINE_GET_DIGEST 186 #define ENGINE_F_ENGINE_GET_NEXT 115 +#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +#define ENGINE_F_ENGINE_GET_PKEY_METH 192 #define ENGINE_F_ENGINE_GET_PREV 116 #define ENGINE_F_ENGINE_INIT 119 #define ENGINE_F_ENGINE_LIST_ADD 120 #define ENGINE_F_ENGINE_LIST_REMOVE 121 #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 -#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 192 +#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 #define ENGINE_F_ENGINE_NEW 122 #define ENGINE_F_ENGINE_REMOVE 123 #define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 @@ -769,7 +794,7 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_R_DSO_FAILURE 104 #define ENGINE_R_DSO_NOT_FOUND 132 #define ENGINE_R_ENGINES_SECTION_ERROR 148 -#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 101 +#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 #define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 #define ENGINE_R_ENGINE_SECTION_ERROR 149 #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 @@ -796,6 +821,7 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_R_RSA_NOT_IMPLEMENTED 141 #define ENGINE_R_UNIMPLEMENTED_CIPHER 146 #define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 #define ENGINE_R_VERSION_INCOMPATIBILITY 145 #ifdef __cplusplus diff --git a/crypto/openssl/crypto/engine/tb_asnmth.c b/crypto/openssl/crypto/engine/tb_asnmth.c new file mode 100644 index 0000000000..75090339f7 --- /dev/null +++ b/crypto/openssl/crypto/engine/tb_asnmth.c @@ -0,0 +1,246 @@ +/* ==================================================================== + * Copyright (c) 2006 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 "eng_int.h" +#include "asn1_locl.h" +#include + +/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the + * function that is used by EVP to hook in pkey_asn1_meth code and cache + * defaults (etc), will display brief debugging summaries to stderr with the + * 'nid'. */ +/* #define ENGINE_PKEY_ASN1_METH_DEBUG */ + +static ENGINE_TABLE *pkey_asn1_meth_table = NULL; + +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e) + { + engine_table_unregister(&pkey_asn1_meth_table, e); + } + +static void engine_unregister_all_pkey_asn1_meths(void) + { + engine_table_cleanup(&pkey_asn1_meth_table); + } + +int ENGINE_register_pkey_asn1_meths(ENGINE *e) + { + if(e->pkey_asn1_meths) + { + const int *nids; + int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&pkey_asn1_meth_table, + engine_unregister_all_pkey_asn1_meths, e, nids, + num_nids, 0); + } + return 1; + } + +void ENGINE_register_all_pkey_asn1_meths(void) + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_pkey_asn1_meths(e); + } + +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e) + { + if(e->pkey_asn1_meths) + { + const int *nids; + int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&pkey_asn1_meth_table, + engine_unregister_all_pkey_asn1_meths, e, nids, + num_nids, 1); + } + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given pkey_asn1_meth 'nid' */ +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid) + { + return engine_table_select(&pkey_asn1_meth_table, nid); + } + +/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */ +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid) + { + EVP_PKEY_ASN1_METHOD *ret; + ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e); + if(!fn || !fn(e, &ret, NULL, nid)) + { + ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + return NULL; + } + return ret; + } + +/* Gets the pkey_asn1_meth callback from an ENGINE structure */ +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e) + { + return e->pkey_asn1_meths; + } + +/* Sets the pkey_asn1_meth callback in an ENGINE structure */ +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f) + { + e->pkey_asn1_meths = f; + return 1; + } + +/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an + * ENGINE is destroyed + */ + +void engine_pkey_asn1_meths_free(ENGINE *e) + { + int i; + EVP_PKEY_ASN1_METHOD *pkm; + if (e->pkey_asn1_meths) + { + const int *pknids; + int npknids; + npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) + { + if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) + { + EVP_PKEY_asn1_free(pkm); + } + } + } + } + +/* Find a method based on a string. This does a linear search through + * all implemented algorithms. This is OK in practice because only + * a small number of algorithms are likely to be implemented in an engine + * and it is not used for speed critical operations. + */ + +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, int len) + { + int i, nidcount; + const int *nids; + EVP_PKEY_ASN1_METHOD *ameth; + if (!e->pkey_asn1_meths) + return NULL; + if (len == -1) + len = strlen(str); + nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0); + for (i = 0; i < nidcount; i++) + { + e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; + } + +typedef struct + { + ENGINE *e; + const EVP_PKEY_ASN1_METHOD *ameth; + const char *str; + int len; + } ENGINE_FIND_STR; + +static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) + { + ENGINE_FIND_STR *lk = arg; + int i; + if (lk->ameth) + return; + for (i = 0; i < sk_ENGINE_num(sk); i++) + { + ENGINE *e = sk_ENGINE_value(sk, i); + EVP_PKEY_ASN1_METHOD *ameth; + e->pkey_asn1_meths(e, &ameth, NULL, nid); + if (((int)strlen(ameth->pem_str) == lk->len) && + !strncasecmp(ameth->pem_str, lk->str, lk->len)) + { + lk->e = e; + lk->ameth = ameth; + return; + } + } + } + +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, int len) + { + ENGINE_FIND_STR fstr; + fstr.e = NULL; + fstr.ameth = NULL; + fstr.str = str; + fstr.len = len; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); + /* If found obtain a structural reference to engine */ + if (fstr.e) + { + fstr.e->struct_ref++; + engine_ref_debug(fstr.e, 0, 1) + } + *pe = fstr.e; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return fstr.ameth; + } diff --git a/crypto/openssl/crypto/x509/x509cset.c b/crypto/openssl/crypto/engine/tb_pkmeth.c similarity index 50% copy from crypto/openssl/crypto/x509/x509cset.c copy to crypto/openssl/crypto/engine/tb_pkmeth.c index 7f4004b291..1cdb967f25 100644 --- a/crypto/openssl/crypto/x509/x509cset.c +++ b/crypto/openssl/crypto/engine/tb_pkmeth.c @@ -1,9 +1,5 @@ -/* crypto/x509/x509cset.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. - */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -56,115 +52,116 @@ * */ -#include -#include "cryptlib.h" -#include -#include +#include "eng_int.h" #include -#include -int X509_CRL_set_version(X509_CRL *x, long version) +/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function + * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_PKEY_METH_DEBUG */ + +static ENGINE_TABLE *pkey_meth_table = NULL; + +void ENGINE_unregister_pkey_meths(ENGINE *e) { - if (x == NULL) return(0); - if (x->crl->version == NULL) - { - if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL) - return(0); - } - return(ASN1_INTEGER_set(x->crl->version,version)); + engine_table_unregister(&pkey_meth_table, e); } -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +static void engine_unregister_all_pkey_meths(void) { - if ((x == NULL) || (x->crl == NULL)) return(0); - return(X509_NAME_set(&x->crl->issuer,name)); + engine_table_cleanup(&pkey_meth_table); } - -int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) +int ENGINE_register_pkey_meths(ENGINE *e) { - ASN1_TIME *in; - - if (x == NULL) return(0); - in=x->crl->lastUpdate; - if (in != tm) + if(e->pkey_meths) { - in=M_ASN1_TIME_dup(tm); - if (in != NULL) - { - M_ASN1_TIME_free(x->crl->lastUpdate); - x->crl->lastUpdate=in; - } + const int *nids; + int num_nids = e->pkey_meths(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&pkey_meth_table, + engine_unregister_all_pkey_meths, e, nids, + num_nids, 0); } - return(in != NULL); + return 1; } -int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) +void ENGINE_register_all_pkey_meths() { - ASN1_TIME *in; + ENGINE *e; - if (x == NULL) return(0); - in=x->crl->nextUpdate; - if (in != tm) - { - in=M_ASN1_TIME_dup(tm); - if (in != NULL) - { - M_ASN1_TIME_free(x->crl->nextUpdate); - x->crl->nextUpdate=in; - } - } - return(in != NULL); + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_pkey_meths(e); } -int X509_CRL_sort(X509_CRL *c) +int ENGINE_set_default_pkey_meths(ENGINE *e) { - int i; - X509_REVOKED *r; - /* sort the data so it will be written in serial - * number order */ - sk_X509_REVOKED_sort(c->crl->revoked); - for (i=0; icrl->revoked); i++) + if(e->pkey_meths) { - r=sk_X509_REVOKED_value(c->crl->revoked,i); - r->sequence=i; + const int *nids; + int num_nids = e->pkey_meths(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&pkey_meth_table, + engine_unregister_all_pkey_meths, e, nids, + num_nids, 1); } - c->crl->enc.modified = 1; return 1; } -int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given pkey_meth 'nid' */ +ENGINE *ENGINE_get_pkey_meth_engine(int nid) { - ASN1_TIME *in; + return engine_table_select(&pkey_meth_table, nid); + } - if (x == NULL) return(0); - in=x->revocationDate; - if (in != tm) +/* Obtains a pkey_meth implementation from an ENGINE functional reference */ +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) + { + EVP_PKEY_METHOD *ret; + ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); + if(!fn || !fn(e, &ret, NULL, nid)) { - in=M_ASN1_TIME_dup(tm); - if (in != NULL) - { - M_ASN1_TIME_free(x->revocationDate); - x->revocationDate=in; - } + ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH, + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + return NULL; } - return(in != NULL); + return ret; + } + +/* Gets the pkey_meth callback from an ENGINE structure */ +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e) + { + return e->pkey_meths; } -int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) +/* Sets the pkey_meth callback in an ENGINE structure */ +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) { - ASN1_INTEGER *in; + e->pkey_meths = f; + return 1; + } - if (x == NULL) return(0); - in=x->serialNumber; - if (in != serial) +/* Internal function to free up EVP_PKEY_METHOD structures before an + * ENGINE is destroyed + */ + +void engine_pkey_meths_free(ENGINE *e) + { + int i; + EVP_PKEY_METHOD *pkm; + if (e->pkey_meths) { - in=M_ASN1_INTEGER_dup(serial); - if (in != NULL) + const int *pknids; + int npknids; + npknids = e->pkey_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) { - M_ASN1_INTEGER_free(x->serialNumber); - x->serialNumber=in; + if (e->pkey_meths(e, &pkm, NULL, pknids[i])) + { + EVP_PKEY_meth_free(pkm); + } } } - return(in != NULL); } diff --git a/crypto/openssl/crypto/err/err.c b/crypto/openssl/crypto/err/err.c index 292404a2fb..69713a6e2f 100644 --- a/crypto/openssl/crypto/err/err.c +++ b/crypto/openssl/crypto/err/err.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -119,9 +119,507 @@ #include #include -static unsigned long get_error_values(int inc,int top, - const char **file,int *line, - const char **data,int *flags); +DECLARE_LHASH_OF(ERR_STRING_DATA); +DECLARE_LHASH_OF(ERR_STATE); + +static void err_load_strings(int lib, ERR_STRING_DATA *str); + +static void ERR_STATE_free(ERR_STATE *s); +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA ERR_str_libraries[]= + { +{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"}, +{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"}, +{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"}, +{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"}, +{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"}, +{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"}, +{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"}, +{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"}, +{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"}, +{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"}, +{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"}, +{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"}, +{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"}, +{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"}, +{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"}, +{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"}, +{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"}, +{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"}, +{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"}, +{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"}, +{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"}, +{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"}, +{ERR_PACK(ERR_LIB_TS,0,0) ,"time stamp routines"}, +{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"}, +{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"}, +{ERR_PACK(ERR_LIB_FIPS,0,0) ,"FIPS routines"}, +{ERR_PACK(ERR_LIB_CMS,0,0) ,"CMS routines"}, +{ERR_PACK(ERR_LIB_HMAC,0,0) ,"HMAC routines"}, +{0,NULL}, + }; + +static ERR_STRING_DATA ERR_str_functs[]= + { + {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"}, + {ERR_PACK(0,SYS_F_CONNECT,0), "connect"}, + {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"}, + {ERR_PACK(0,SYS_F_SOCKET,0), "socket"}, + {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"}, + {ERR_PACK(0,SYS_F_BIND,0), "bind"}, + {ERR_PACK(0,SYS_F_LISTEN,0), "listen"}, + {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"}, +#ifdef OPENSSL_SYS_WINDOWS + {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"}, +#endif + {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"}, + {ERR_PACK(0,SYS_F_FREAD,0), "fread"}, + {0,NULL}, + }; + +static ERR_STRING_DATA ERR_str_reasons[]= + { +{ERR_R_SYS_LIB ,"system lib"}, +{ERR_R_BN_LIB ,"BN lib"}, +{ERR_R_RSA_LIB ,"RSA lib"}, +{ERR_R_DH_LIB ,"DH lib"}, +{ERR_R_EVP_LIB ,"EVP lib"}, +{ERR_R_BUF_LIB ,"BUF lib"}, +{ERR_R_OBJ_LIB ,"OBJ lib"}, +{ERR_R_PEM_LIB ,"PEM lib"}, +{ERR_R_DSA_LIB ,"DSA lib"}, +{ERR_R_X509_LIB ,"X509 lib"}, +{ERR_R_ASN1_LIB ,"ASN1 lib"}, +{ERR_R_CONF_LIB ,"CONF lib"}, +{ERR_R_CRYPTO_LIB ,"CRYPTO lib"}, +{ERR_R_EC_LIB ,"EC lib"}, +{ERR_R_SSL_LIB ,"SSL lib"}, +{ERR_R_BIO_LIB ,"BIO lib"}, +{ERR_R_PKCS7_LIB ,"PKCS7 lib"}, +{ERR_R_X509V3_LIB ,"X509V3 lib"}, +{ERR_R_PKCS12_LIB ,"PKCS12 lib"}, +{ERR_R_RAND_LIB ,"RAND lib"}, +{ERR_R_DSO_LIB ,"DSO lib"}, +{ERR_R_ENGINE_LIB ,"ENGINE lib"}, +{ERR_R_OCSP_LIB ,"OCSP lib"}, +{ERR_R_TS_LIB ,"TS lib"}, + +{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"}, +{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"}, +{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"}, +{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"}, +{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"}, +{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"}, + +{ERR_R_FATAL ,"fatal"}, +{ERR_R_MALLOC_FAILURE ,"malloc failure"}, +{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"}, +{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"}, +{ERR_R_INTERNAL_ERROR ,"internal error"}, +{ERR_R_DISABLED ,"called a function that was disabled at compile-time"}, + +{0,NULL}, + }; +#endif + + +/* Define the predeclared (but externally opaque) "ERR_FNS" type */ +struct st_ERR_FNS + { + /* Works on the "error_hash" string table */ + LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create); + void (*cb_err_del)(void); + ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *); + /* Works on the "thread_hash" error-state table */ + LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create); + void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash); + ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *); + ERR_STATE *(*cb_thread_set_item)(ERR_STATE *); + void (*cb_thread_del_item)(const ERR_STATE *); + /* Returns the next available error "library" numbers */ + int (*cb_get_next_lib)(void); + }; + +/* Predeclarations of the "err_defaults" functions */ +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create); +static void int_err_del(void); +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); +static LHASH_OF(ERR_STATE) *int_thread_get(int create); +static void int_thread_release(LHASH_OF(ERR_STATE) **hash); +static ERR_STATE *int_thread_get_item(const ERR_STATE *); +static ERR_STATE *int_thread_set_item(ERR_STATE *); +static void int_thread_del_item(const ERR_STATE *); +static int int_err_get_next_lib(void); +/* The static ERR_FNS table using these defaults functions */ +static const ERR_FNS err_defaults = + { + int_err_get, + int_err_del, + int_err_get_item, + int_err_set_item, + int_err_del_item, + int_thread_get, + int_thread_release, + int_thread_get_item, + int_thread_set_item, + int_thread_del_item, + int_err_get_next_lib + }; + +/* The replacable table of ERR_FNS functions we use at run-time */ +static const ERR_FNS *err_fns = NULL; + +/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ +#define ERRFN(a) err_fns->cb_##a + +/* The internal state used by "err_defaults" - as such, the setting, reading, + * creating, and deleting of this data should only be permitted via the + * "err_defaults" functions. This way, a linked module can completely defer all + * ERR state operation (together with requisite locking) to the implementations + * and state in the loading application. */ +static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; +static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; +static int int_thread_hash_references = 0; +static int int_err_library_number= ERR_LIB_USER; + +/* Internal function that checks whether "err_fns" is set and if not, sets it to + * the defaults. */ +static void err_fns_check(void) + { + if (err_fns) return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!err_fns) + err_fns = &err_defaults; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + } + +/* API functions to get or set the underlying ERR functions. */ + +const ERR_FNS *ERR_get_implementation(void) + { + err_fns_check(); + return err_fns; + } + +int ERR_set_implementation(const ERR_FNS *fns) + { + int ret = 0; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + /* It's too late if 'err_fns' is non-NULL. BTW: not much point setting + * an error is there?! */ + if (!err_fns) + { + err_fns = fns; + ret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; + } + +/* These are the callbacks provided to "lh_new()" when creating the LHASH tables + * internal to the "err_defaults" implementation. */ + +static unsigned long get_error_values(int inc,int top,const char **file,int *line, + const char **data,int *flags); + +/* The internal functions used in the "err_defaults" implementation */ + +static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) + { + unsigned long ret,l; + + l=a->error; + ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l); + return(ret^ret%19*13); + } +static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA) + +static int err_string_data_cmp(const ERR_STRING_DATA *a, + const ERR_STRING_DATA *b) + { + return (int)(a->error - b->error); + } +static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA) + +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create) + { + LHASH_OF(ERR_STRING_DATA) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_error_hash && create) + { + CRYPTO_push_info("int_err_get (err.c)"); + int_error_hash = lh_ERR_STRING_DATA_new(); + CRYPTO_pop_info(); + } + if (int_error_hash) + ret = int_error_hash; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; + } + +static void int_err_del(void) + { + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (int_error_hash) + { + lh_ERR_STRING_DATA_free(int_error_hash); + int_error_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + } + +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) + { + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get)(0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + return p; + } + +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) + { + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get)(1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; + } + +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) + { + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get)(0); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_delete(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; + } + +static unsigned long err_state_hash(const ERR_STATE *a) + { + return CRYPTO_THREADID_hash(&a->tid) * 13; + } +static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE) + +static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) + { + return CRYPTO_THREADID_cmp(&a->tid, &b->tid); + } +static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE) + +static LHASH_OF(ERR_STATE) *int_thread_get(int create) + { + LHASH_OF(ERR_STATE) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_thread_hash && create) + { + CRYPTO_push_info("int_thread_get (err.c)"); + int_thread_hash = lh_ERR_STATE_new(); + CRYPTO_pop_info(); + } + if (int_thread_hash) + { + int_thread_hash_references++; + ret = int_thread_hash; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; + } + +static void int_thread_release(LHASH_OF(ERR_STATE) **hash) + { + int i; + + if (hash == NULL || *hash == NULL) + return; + + i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); + +#ifdef REF_PRINT + fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR"); +#endif + if (i > 0) return; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"int_thread_release, bad reference count\n"); + abort(); /* ok */ + } +#endif + *hash = NULL; + } + +static ERR_STATE *int_thread_get_item(const ERR_STATE *d) + { + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get)(0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release)(&hash); + return p; + } + +static ERR_STATE *int_thread_set_item(ERR_STATE *d) + { + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get)(1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release)(&hash); + return p; + } + +static void int_thread_del_item(const ERR_STATE *d) + { + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get)(0); + if (!hash) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_delete(hash, d); + /* make sure we don't leak memory */ + if (int_thread_hash_references == 1 + && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) + { + lh_ERR_STATE_free(int_thread_hash); + int_thread_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release)(&hash); + if (p) + ERR_STATE_free(p); + } + +static int int_err_get_next_lib(void) + { + int ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + ret = int_err_library_number++; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; + } + + +#ifndef OPENSSL_NO_ERR +#define NUM_SYS_STR_REASONS 127 +#define LEN_SYS_STR_REASON 32 + +static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; +/* SYS_str_reasons is filled with copies of strerror() results at + * initialization. + * 'errno' values up to 127 should cover all usual errors, + * others will be displayed numerically by ERR_error_string. + * It is crucial that we have something for each reason code + * that occurs in ERR_str_reasons, or bogus reason strings + * will be returned for SYSerr(), which always gets an errno + * value and never one of those 'standard' reason codes. */ + +static void build_SYS_str_reasons(void) + { + /* OPENSSL_malloc cannot be used here, use static storage instead */ + static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; + int i; + static int init = 1; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + if (!init) + { + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + return; + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!init) + { + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return; + } + + for (i = 1; i <= NUM_SYS_STR_REASONS; i++) + { + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; + + str->error = (unsigned long)i; + if (str->string == NULL) + { + char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]); + char *src = strerror(i); + if (src != NULL) + { + strncpy(*dest, src, sizeof *dest); + (*dest)[sizeof *dest - 1] = '\0'; + str->string = *dest; + } + } + if (str->string == NULL) + str->string = "unknown"; + } + + /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, + * as required by ERR_load_strings. */ + + init = 0; + + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + } +#endif #define err_clear_data(p,i) \ do { \ @@ -143,6 +641,68 @@ static unsigned long get_error_values(int inc,int top, (p)->err_line[i]= -1; \ } while(0) +static void ERR_STATE_free(ERR_STATE *s) + { + int i; + + if (s == NULL) + return; + + for (i=0; ierror) + { + if (lib) + str->error|=ERR_PACK(lib,0,0); + ERRFN(err_set_item)(str); + str++; + } + } + +void ERR_load_strings(int lib, ERR_STRING_DATA *str) + { + ERR_load_ERR_strings(); + err_load_strings(lib, str); + } + +void ERR_unload_strings(int lib, ERR_STRING_DATA *str) + { + while (str->error) + { + if (lib) + str->error|=ERR_PACK(lib,0,0); + ERRFN(err_del_item)(str); + str++; + } + } + +void ERR_free_strings(void) + { + err_fns_check(); + ERRFN(err_del)(); + } + +/********************************************************/ + void ERR_put_error(int lib, int func, int reason, const char *file, int line) { @@ -297,6 +857,196 @@ static unsigned long get_error_values(int inc, int top, const char **file, int * return ret; } +void ERR_error_string_n(unsigned long e, char *buf, size_t len) + { + char lsbuf[64], fsbuf[64], rsbuf[64]; + const char *ls,*fs,*rs; + unsigned long l,f,r; + + l=ERR_GET_LIB(e); + f=ERR_GET_FUNC(e); + r=ERR_GET_REASON(e); + + ls=ERR_lib_error_string(e); + fs=ERR_func_error_string(e); + rs=ERR_reason_error_string(e); + + if (ls == NULL) + BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); + if (fs == NULL) + BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); + if (rs == NULL) + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); + + BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, + fs?fs:fsbuf, rs?rs:rsbuf); + if (strlen(buf) == len-1) + { + /* output may be truncated; make sure we always have 5 + * colon-separated fields, i.e. 4 colons ... */ +#define NUM_COLONS 4 + if (len > NUM_COLONS) /* ... if possible */ + { + int i; + char *s = buf; + + for (i = 0; i < NUM_COLONS; i++) + { + char *colon = strchr(s, ':'); + if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i) + { + /* set colon no. i at last possible position + * (buf[len-1] is the terminating 0)*/ + colon = &buf[len-1] - NUM_COLONS + i; + *colon = ':'; + } + s = colon + 1; + } + } + } + } + +/* BAD for multi-threading: uses a local buffer if ret == NULL */ +/* ERR_error_string_n should be used instead for ret != NULL + * as ERR_error_string cannot know how large the buffer is */ +char *ERR_error_string(unsigned long e, char *ret) + { + static char buf[256]; + + if (ret == NULL) ret=buf; + ERR_error_string_n(e, ret, 256); + + return ret; + } + +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void) + { + err_fns_check(); + return ERRFN(err_get)(0); + } + +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void) + { + err_fns_check(); + return ERRFN(thread_get)(0); + } + +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash) + { + err_fns_check(); + ERRFN(thread_release)(hash); + } + +const char *ERR_lib_error_string(unsigned long e) + { + ERR_STRING_DATA d,*p; + unsigned long l; + + err_fns_check(); + l=ERR_GET_LIB(e); + d.error=ERR_PACK(l,0,0); + p=ERRFN(err_get_item)(&d); + return((p == NULL)?NULL:p->string); + } + +const char *ERR_func_error_string(unsigned long e) + { + ERR_STRING_DATA d,*p; + unsigned long l,f; + + err_fns_check(); + l=ERR_GET_LIB(e); + f=ERR_GET_FUNC(e); + d.error=ERR_PACK(l,f,0); + p=ERRFN(err_get_item)(&d); + return((p == NULL)?NULL:p->string); + } + +const char *ERR_reason_error_string(unsigned long e) + { + ERR_STRING_DATA d,*p=NULL; + unsigned long l,r; + + err_fns_check(); + l=ERR_GET_LIB(e); + r=ERR_GET_REASON(e); + d.error=ERR_PACK(l,0,r); + p=ERRFN(err_get_item)(&d); + if (!p) + { + d.error=ERR_PACK(0,0,r); + p=ERRFN(err_get_item)(&d); + } + return((p == NULL)?NULL:p->string); + } + +void ERR_remove_thread_state(const CRYPTO_THREADID *id) + { + ERR_STATE tmp; + + if (id) + CRYPTO_THREADID_cpy(&tmp.tid, id); + else + CRYPTO_THREADID_current(&tmp.tid); + err_fns_check(); + /* thread_del_item automatically destroys the LHASH if the number of + * items reaches zero. */ + ERRFN(thread_del_item)(&tmp); + } + +#ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid) + { + ERR_remove_thread_state(NULL); + } +#endif + +ERR_STATE *ERR_get_state(void) + { + static ERR_STATE fallback; + ERR_STATE *ret,tmp,*tmpp=NULL; + int i; + CRYPTO_THREADID tid; + + err_fns_check(); + CRYPTO_THREADID_current(&tid); + CRYPTO_THREADID_cpy(&tmp.tid, &tid); + ret=ERRFN(thread_get_item)(&tmp); + + /* ret == the error state, if NULL, make a new one */ + if (ret == NULL) + { + ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); + if (ret == NULL) return(&fallback); + CRYPTO_THREADID_cpy(&ret->tid, &tid); + ret->top=0; + ret->bottom=0; + for (i=0; ierr_data[i]=NULL; + ret->err_data_flags[i]=0; + } + tmpp = ERRFN(thread_set_item)(ret); + /* To check if insertion failed, do a get. */ + if (ERRFN(thread_get_item)(ret) != ret) + { + ERR_STATE_free(ret); /* could not insert it */ + return(&fallback); + } + /* If a race occured in this function and we came second, tmpp + * is the first one that we just replaced. */ + if (tmpp) + ERR_STATE_free(tmpp); + } + return ret; + } + +int ERR_get_next_error_library(void) + { + err_fns_check(); + return ERRFN(get_next_lib)(); + } + void ERR_set_error_data(char *data, int flags) { ERR_STATE *es; @@ -383,34 +1133,3 @@ int ERR_pop_to_mark(void) es->err_flags[es->top]&=~ERR_FLAG_MARK; return 1; } - -#ifdef OPENSSL_FIPS - -static ERR_STATE *fget_state(void) - { - static ERR_STATE fstate; - return &fstate; - } - -ERR_STATE *(*get_state_func)(void) = fget_state; -void (*remove_state_func)(unsigned long pid); - -ERR_STATE *ERR_get_state(void) - { - return get_state_func(); - } - -void int_ERR_set_state_func(ERR_STATE *(*get_func)(void), - void (*remove_func)(unsigned long pid)) - { - get_state_func = get_func; - remove_state_func = remove_func; - } - -void ERR_remove_state(unsigned long pid) - { - if (remove_state_func) - remove_state_func(pid); - } - -#endif diff --git a/crypto/openssl/crypto/err/err.h b/crypto/openssl/crypto/err/err.h index dcac415231..b9f8c16d47 100644 --- a/crypto/openssl/crypto/err/err.h +++ b/crypto/openssl/crypto/err/err.h @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 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). + * + */ #ifndef HEADER_ERR_H #define HEADER_ERR_H @@ -94,7 +147,7 @@ extern "C" { #define ERR_NUM_ERRORS 16 typedef struct err_state_st { - unsigned long pid; + CRYPTO_THREADID tid; int err_flags[ERR_NUM_ERRORS]; unsigned long err_buffer[ERR_NUM_ERRORS]; char *err_data[ERR_NUM_ERRORS]; @@ -142,7 +195,9 @@ typedef struct err_state_st #define ERR_LIB_STORE 44 #define ERR_LIB_FIPS 45 #define ERR_LIB_CMS 46 -#define ERR_LIB_JPAKE 47 +#define ERR_LIB_TS 47 +#define ERR_LIB_HMAC 48 +#define ERR_LIB_JPAKE 49 #define ERR_LIB_USER 128 @@ -176,6 +231,8 @@ typedef struct err_state_st #define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) #define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) #define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) #define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) /* Borland C seems too stupid to be able to shift and do longs in @@ -232,6 +289,7 @@ typedef struct err_state_st #define ERR_R_ECDSA_LIB ERR_LIB_ECDSA /* 42 */ #define ERR_R_ECDH_LIB ERR_LIB_ECDH /* 43 */ #define ERR_R_STORE_LIB ERR_LIB_STORE /* 44 */ +#define ERR_R_TS_LIB ERR_LIB_TS /* 45 */ #define ERR_R_NESTED_ASN1_ERROR 58 #define ERR_R_BAD_ASN1_OBJECT_HEADER 59 @@ -294,13 +352,16 @@ void ERR_load_ERR_strings(void); void ERR_load_crypto_strings(void); void ERR_free_strings(void); +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +#ifndef OPENSSL_NO_DEPRECATED void ERR_remove_state(unsigned long pid); /* if zero we look it up */ +#endif ERR_STATE *ERR_get_state(void); #ifndef OPENSSL_NO_LHASH -LHASH *ERR_get_string_table(void); -LHASH *ERR_get_err_state_table(void); -void ERR_release_err_state_table(LHASH **hash); +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); #endif int ERR_get_next_error_library(void); @@ -308,12 +369,6 @@ int ERR_get_next_error_library(void); int ERR_set_mark(void); int ERR_pop_to_mark(void); -#ifdef OPENSSL_FIPS -void int_ERR_set_state_func(ERR_STATE *(*get_func)(void), - void (*remove_func)(unsigned long pid)); -void int_ERR_lib_init(void); -#endif - /* Already defined in ossl_typ.h */ /* typedef struct st_ERR_FNS ERR_FNS; */ /* An application can use this function and provide the return value to loaded diff --git a/crypto/openssl/crypto/err/err_all.c b/crypto/openssl/crypto/err/err_all.c index 39796f7cc8..fc049e8e88 100644 --- a/crypto/openssl/crypto/err/err_all.c +++ b/crypto/openssl/crypto/err/err_all.c @@ -64,6 +64,7 @@ #endif #include #include +#include #ifndef OPENSSL_NO_RSA #include #endif @@ -94,10 +95,7 @@ #include #include #include -#ifdef OPENSSL_FIPS -#include -#endif - +#include #ifndef OPENSSL_NO_CMS #include #endif @@ -128,6 +126,7 @@ void ERR_load_crypto_strings(void) ERR_load_ASN1_strings(); ERR_load_CONF_strings(); ERR_load_CRYPTO_strings(); + ERR_load_COMP_strings(); #ifndef OPENSSL_NO_EC ERR_load_EC_strings(); #endif @@ -144,14 +143,12 @@ void ERR_load_crypto_strings(void) ERR_load_PKCS12_strings(); ERR_load_RAND_strings(); ERR_load_DSO_strings(); + ERR_load_TS_strings(); #ifndef OPENSSL_NO_ENGINE ERR_load_ENGINE_strings(); #endif ERR_load_OCSP_strings(); ERR_load_UI_strings(); -#ifdef OPENSSL_FIPS - ERR_load_FIPS_strings(); -#endif #ifndef OPENSSL_NO_CMS ERR_load_CMS_strings(); #endif diff --git a/crypto/openssl/crypto/err/err_def.c b/crypto/openssl/crypto/err/err_def.c deleted file mode 100644 index 7ed3d84955..0000000000 --- a/crypto/openssl/crypto/err/err_def.c +++ /dev/null @@ -1,665 +0,0 @@ -/* crypto/err/err_def.c */ -/* 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-2001 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 -#include -#include -#include "cryptlib.h" -#include -#include -#include -#include -#include - -#define err_clear_data(p,i) \ - do { \ - if (((p)->err_data[i] != NULL) && \ - (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ - { \ - OPENSSL_free((p)->err_data[i]); \ - (p)->err_data[i]=NULL; \ - } \ - (p)->err_data_flags[i]=0; \ - } while(0) - -#define err_clear(p,i) \ - do { \ - (p)->err_flags[i]=0; \ - (p)->err_buffer[i]=0; \ - err_clear_data(p,i); \ - (p)->err_file[i]=NULL; \ - (p)->err_line[i]= -1; \ - } while(0) - -static void err_load_strings(int lib, ERR_STRING_DATA *str); - -static void ERR_STATE_free(ERR_STATE *s); - -/* Define the predeclared (but externally opaque) "ERR_FNS" type */ -struct st_ERR_FNS - { - /* Works on the "error_hash" string table */ - LHASH *(*cb_err_get)(int create); - void (*cb_err_del)(void); - ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *); - ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *); - ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *); - /* Works on the "thread_hash" error-state table */ - LHASH *(*cb_thread_get)(int create); - void (*cb_thread_release)(LHASH **hash); - ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *); - ERR_STATE *(*cb_thread_set_item)(ERR_STATE *); - void (*cb_thread_del_item)(const ERR_STATE *); - /* Returns the next available error "library" numbers */ - int (*cb_get_next_lib)(void); - }; - -/* Predeclarations of the "err_defaults" functions */ -static LHASH *int_err_get(int create); -static void int_err_del(void); -static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); -static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); -static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); -static LHASH *int_thread_get(int create); -static void int_thread_release(LHASH **hash); -static ERR_STATE *int_thread_get_item(const ERR_STATE *); -static ERR_STATE *int_thread_set_item(ERR_STATE *); -static void int_thread_del_item(const ERR_STATE *); -static int int_err_get_next_lib(void); -/* The static ERR_FNS table using these defaults functions */ -static const ERR_FNS err_defaults = - { - int_err_get, - int_err_del, - int_err_get_item, - int_err_set_item, - int_err_del_item, - int_thread_get, - int_thread_release, - int_thread_get_item, - int_thread_set_item, - int_thread_del_item, - int_err_get_next_lib - }; - -/* The replacable table of ERR_FNS functions we use at run-time */ -static const ERR_FNS *err_fns = NULL; - -/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ -#define ERRFN(a) err_fns->cb_##a - -/* The internal state used by "err_defaults" - as such, the setting, reading, - * creating, and deleting of this data should only be permitted via the - * "err_defaults" functions. This way, a linked module can completely defer all - * ERR state operation (together with requisite locking) to the implementations - * and state in the loading application. */ -static LHASH *int_error_hash = NULL; -static LHASH *int_thread_hash = NULL; -static int int_thread_hash_references = 0; -static int int_err_library_number= ERR_LIB_USER; - -/* Internal function that checks whether "err_fns" is set and if not, sets it to - * the defaults. */ -static void err_fns_check(void) - { - if (err_fns) return; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!err_fns) - err_fns = &err_defaults; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - } - -/* API functions to get or set the underlying ERR functions. */ - -const ERR_FNS *ERR_get_implementation(void) - { - err_fns_check(); - return err_fns; - } - -int ERR_set_implementation(const ERR_FNS *fns) - { - int ret = 0; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - /* It's too late if 'err_fns' is non-NULL. BTW: not much point setting - * an error is there?! */ - if (!err_fns) - { - err_fns = fns; - ret = 1; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return ret; - } - -/* These are the callbacks provided to "lh_new()" when creating the LHASH tables - * internal to the "err_defaults" implementation. */ - -/* static unsigned long err_hash(ERR_STRING_DATA *a); */ -static unsigned long err_hash(const void *a_void); -/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */ -static int err_cmp(const void *a_void, const void *b_void); -/* static unsigned long pid_hash(ERR_STATE *pid); */ -static unsigned long pid_hash(const void *pid_void); -/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */ -static int pid_cmp(const void *a_void,const void *pid_void); - -/* The internal functions used in the "err_defaults" implementation */ - -static LHASH *int_err_get(int create) - { - LHASH *ret = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!int_error_hash && create) - { - CRYPTO_push_info("int_err_get (err.c)"); - int_error_hash = lh_new(err_hash, err_cmp); - CRYPTO_pop_info(); - } - if (int_error_hash) - ret = int_error_hash; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return ret; - } - -static void int_err_del(void) - { - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (int_error_hash) - { - lh_free(int_error_hash); - int_error_hash = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - } - -static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) - { - ERR_STRING_DATA *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(err_get)(0); - if (!hash) - return NULL; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - p = (ERR_STRING_DATA *)lh_retrieve(hash, d); - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - - return p; - } - -static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) - { - ERR_STRING_DATA *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(err_get)(1); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STRING_DATA *)lh_insert(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return p; - } - -static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) - { - ERR_STRING_DATA *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(err_get)(0); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STRING_DATA *)lh_delete(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return p; - } - -static LHASH *int_thread_get(int create) - { - LHASH *ret = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!int_thread_hash && create) - { - CRYPTO_push_info("int_thread_get (err.c)"); - int_thread_hash = lh_new(pid_hash, pid_cmp); - CRYPTO_pop_info(); - } - if (int_thread_hash) - { - int_thread_hash_references++; - ret = int_thread_hash; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return ret; - } - -static void int_thread_release(LHASH **hash) - { - int i; - - if (hash == NULL || *hash == NULL) - return; - - i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); - -#ifdef REF_PRINT - fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR"); -#endif - if (i > 0) return; -#ifdef REF_CHECK - if (i < 0) - { - fprintf(stderr,"int_thread_release, bad reference count\n"); - abort(); /* ok */ - } -#endif - *hash = NULL; - } - -static ERR_STATE *int_thread_get_item(const ERR_STATE *d) - { - ERR_STATE *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(thread_get)(0); - if (!hash) - return NULL; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - p = (ERR_STATE *)lh_retrieve(hash, d); - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release)(&hash); - return p; - } - -static ERR_STATE *int_thread_set_item(ERR_STATE *d) - { - ERR_STATE *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(thread_get)(1); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STATE *)lh_insert(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release)(&hash); - return p; - } - -static void int_thread_del_item(const ERR_STATE *d) - { - ERR_STATE *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(thread_get)(0); - if (!hash) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STATE *)lh_delete(hash, d); - /* make sure we don't leak memory */ - if (int_thread_hash_references == 1 - && int_thread_hash && (lh_num_items(int_thread_hash) == 0)) - { - lh_free(int_thread_hash); - int_thread_hash = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release)(&hash); - if (p) - ERR_STATE_free(p); - } - -static int int_err_get_next_lib(void) - { - int ret; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - ret = int_err_library_number++; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return ret; - } - -static void ERR_STATE_free(ERR_STATE *s) - { - int i; - - if (s == NULL) - return; - - for (i=0; ierror) - { - if (lib) - str->error|=ERR_PACK(lib,0,0); - ERRFN(err_set_item)(str); - str++; - } - } - -void ERR_load_strings(int lib, ERR_STRING_DATA *str) - { - err_fns_check(); - err_load_strings(lib, str); - } - -void ERR_unload_strings(int lib, ERR_STRING_DATA *str) - { - while (str->error) - { - if (lib) - str->error|=ERR_PACK(lib,0,0); - ERRFN(err_del_item)(str); - str++; - } - } - -void ERR_free_strings(void) - { - err_fns_check(); - ERRFN(err_del)(); - } - -LHASH *ERR_get_string_table(void) - { - err_fns_check(); - return ERRFN(err_get)(0); - } - -LHASH *ERR_get_err_state_table(void) - { - err_fns_check(); - return ERRFN(thread_get)(0); - } - -void ERR_release_err_state_table(LHASH **hash) - { - err_fns_check(); - ERRFN(thread_release)(hash); - } - -const char *ERR_lib_error_string(unsigned long e) - { - ERR_STRING_DATA d,*p; - unsigned long l; - - err_fns_check(); - l=ERR_GET_LIB(e); - d.error=ERR_PACK(l,0,0); - p=ERRFN(err_get_item)(&d); - return((p == NULL)?NULL:p->string); - } - -const char *ERR_func_error_string(unsigned long e) - { - ERR_STRING_DATA d,*p; - unsigned long l,f; - - err_fns_check(); - l=ERR_GET_LIB(e); - f=ERR_GET_FUNC(e); - d.error=ERR_PACK(l,f,0); - p=ERRFN(err_get_item)(&d); - return((p == NULL)?NULL:p->string); - } - -const char *ERR_reason_error_string(unsigned long e) - { - ERR_STRING_DATA d,*p=NULL; - unsigned long l,r; - - err_fns_check(); - l=ERR_GET_LIB(e); - r=ERR_GET_REASON(e); - d.error=ERR_PACK(l,0,r); - p=ERRFN(err_get_item)(&d); - if (!p) - { - d.error=ERR_PACK(0,0,r); - p=ERRFN(err_get_item)(&d); - } - return((p == NULL)?NULL:p->string); - } - -/* static unsigned long err_hash(ERR_STRING_DATA *a) */ -static unsigned long err_hash(const void *a_void) - { - unsigned long ret,l; - - l=((const ERR_STRING_DATA *)a_void)->error; - ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l); - return(ret^ret%19*13); - } - -/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */ -static int err_cmp(const void *a_void, const void *b_void) - { - return((int)(((const ERR_STRING_DATA *)a_void)->error - - ((const ERR_STRING_DATA *)b_void)->error)); - } - -/* static unsigned long pid_hash(ERR_STATE *a) */ -static unsigned long pid_hash(const void *a_void) - { - return(((const ERR_STATE *)a_void)->pid*13); - } - -/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */ -static int pid_cmp(const void *a_void, const void *b_void) - { - return((int)((long)((const ERR_STATE *)a_void)->pid - - (long)((const ERR_STATE *)b_void)->pid)); - } -#ifdef OPENSSL_FIPS -static void int_err_remove_state(unsigned long pid) -#else -void ERR_remove_state(unsigned long pid) -#endif - { - ERR_STATE tmp; - - err_fns_check(); - if (pid == 0) - pid=(unsigned long)CRYPTO_thread_id(); - tmp.pid=pid; - /* thread_del_item automatically destroys the LHASH if the number of - * items reaches zero. */ - ERRFN(thread_del_item)(&tmp); - } - -#ifdef OPENSSL_FIPS - static ERR_STATE *int_err_get_state(void) -#else -ERR_STATE *ERR_get_state(void) -#endif - { - static ERR_STATE fallback; - ERR_STATE *ret,tmp,*tmpp=NULL; - int i; - unsigned long pid; - - err_fns_check(); - pid=(unsigned long)CRYPTO_thread_id(); - tmp.pid=pid; - ret=ERRFN(thread_get_item)(&tmp); - - /* ret == the error state, if NULL, make a new one */ - if (ret == NULL) - { - ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); - if (ret == NULL) return(&fallback); - ret->pid=pid; - ret->top=0; - ret->bottom=0; - for (i=0; ierr_data[i]=NULL; - ret->err_data_flags[i]=0; - } - tmpp = ERRFN(thread_set_item)(ret); - /* To check if insertion failed, do a get. */ - if (ERRFN(thread_get_item)(ret) != ret) - { - ERR_STATE_free(ret); /* could not insert it */ - return(&fallback); - } - /* If a race occured in this function and we came second, tmpp - * is the first one that we just replaced. */ - if (tmpp) - ERR_STATE_free(tmpp); - } - return ret; - } - -#ifdef OPENSSL_FIPS -void int_ERR_lib_init(void) - { - int_ERR_set_state_func(int_err_get_state, int_err_remove_state); - } -#endif - -int ERR_get_next_error_library(void) - { - err_fns_check(); - return ERRFN(get_next_lib)(); - } diff --git a/crypto/openssl/crypto/err/err_prn.c b/crypto/openssl/crypto/err/err_prn.c index 4cdf342fa6..a0168ac8ed 100644 --- a/crypto/openssl/crypto/err/err_prn.c +++ b/crypto/openssl/crypto/err/err_prn.c @@ -72,21 +72,29 @@ void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), const char *file,*data; int line,flags; unsigned long es; + CRYPTO_THREADID cur; - es=CRYPTO_thread_id(); + CRYPTO_THREADID_current(&cur); + es=CRYPTO_THREADID_hash(&cur); while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) { ERR_error_string_n(l, buf, sizeof buf); BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf, file, line, (flags & ERR_TXT_STRING) ? data : ""); - cb(buf2, strlen(buf2), u); + if (cb(buf2, strlen(buf2), u) <= 0) + break; /* abort outputting the error report */ } } #ifndef OPENSSL_NO_FP_API static int print_fp(const char *str, size_t len, void *fp) { - return fwrite(str, 1, len, fp); + BIO bio; + + BIO_set(&bio,BIO_s_file()); + BIO_set_fp(&bio,fp,BIO_NOCLOSE); + + return BIO_printf(&bio, "%s", str); } void ERR_print_errors_fp(FILE *fp) { @@ -94,64 +102,13 @@ void ERR_print_errors_fp(FILE *fp) } #endif -void ERR_error_string_n(unsigned long e, char *buf, size_t len) +static int print_bio(const char *str, size_t len, void *bp) { - char lsbuf[64], fsbuf[64], rsbuf[64]; - const char *ls,*fs,*rs; - unsigned long l,f,r; - - l=ERR_GET_LIB(e); - f=ERR_GET_FUNC(e); - r=ERR_GET_REASON(e); - - ls=ERR_lib_error_string(e); - fs=ERR_func_error_string(e); - rs=ERR_reason_error_string(e); - - if (ls == NULL) - BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); - if (fs == NULL) - BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); - if (rs == NULL) - BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); - - BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, - fs?fs:fsbuf, rs?rs:rsbuf); - if (strlen(buf) == len-1) - { - /* output may be truncated; make sure we always have 5 - * colon-separated fields, i.e. 4 colons ... */ -#define NUM_COLONS 4 - if (len > NUM_COLONS) /* ... if possible */ - { - int i; - char *s = buf; - - for (i = 0; i < NUM_COLONS; i++) - { - char *colon = strchr(s, ':'); - if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i) - { - /* set colon no. i at last possible position - * (buf[len-1] is the terminating 0)*/ - colon = &buf[len-1] - NUM_COLONS + i; - *colon = ':'; - } - s = colon + 1; - } - } - } + return BIO_write((BIO *)bp, str, len); } - -/* BAD for multi-threading: uses a local buffer if ret == NULL */ -/* ERR_error_string_n should be used instead for ret != NULL - * as ERR_error_string cannot know how large the buffer is */ -char *ERR_error_string(unsigned long e, char *ret) +void ERR_print_errors(BIO *bp) { - static char buf[256]; - - if (ret == NULL) ret=buf; - ERR_error_string_n(e, ret, 256); - - return ret; + ERR_print_errors_cb(print_bio, bp); } + + diff --git a/crypto/openssl/crypto/err/err_str.c b/crypto/openssl/crypto/err/err_str.c deleted file mode 100644 index d39040888d..0000000000 --- a/crypto/openssl/crypto/err/err_str.c +++ /dev/null @@ -1,295 +0,0 @@ -/* crypto/err/err_str.c */ -/* 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-2001 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 -#include -#include -#include "cryptlib.h" -#include -#include -#include -#include -#include - -#ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA ERR_str_libraries[]= - { -{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"}, -{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"}, -{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"}, -{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"}, -{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"}, -{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"}, -{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"}, -{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"}, -{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"}, -{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"}, -{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"}, -{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"}, -{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"}, -{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"}, -{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"}, -{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"}, -{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"}, -{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"}, -{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"}, -{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"}, -{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"}, -{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"}, -{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"}, -{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"}, -{ERR_PACK(ERR_LIB_FIPS,0,0) ,"FIPS routines"}, -{ERR_PACK(ERR_LIB_CMS,0,0) ,"CMS routines"}, -{ERR_PACK(ERR_LIB_JPAKE,0,0) ,"JPAKE routines"}, -{0,NULL}, - }; - -static ERR_STRING_DATA ERR_str_functs[]= - { - {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"}, - {ERR_PACK(0,SYS_F_CONNECT,0), "connect"}, - {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"}, - {ERR_PACK(0,SYS_F_SOCKET,0), "socket"}, - {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"}, - {ERR_PACK(0,SYS_F_BIND,0), "bind"}, - {ERR_PACK(0,SYS_F_LISTEN,0), "listen"}, - {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"}, -#ifdef OPENSSL_SYS_WINDOWS - {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"}, -#endif - {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"}, - {ERR_PACK(0,SYS_F_FREAD,0), "fread"}, - {0,NULL}, - }; - -static ERR_STRING_DATA ERR_str_reasons[]= - { -{ERR_R_SYS_LIB ,"system lib"}, -{ERR_R_BN_LIB ,"BN lib"}, -{ERR_R_RSA_LIB ,"RSA lib"}, -{ERR_R_DH_LIB ,"DH lib"}, -{ERR_R_EVP_LIB ,"EVP lib"}, -{ERR_R_BUF_LIB ,"BUF lib"}, -{ERR_R_OBJ_LIB ,"OBJ lib"}, -{ERR_R_PEM_LIB ,"PEM lib"}, -{ERR_R_DSA_LIB ,"DSA lib"}, -{ERR_R_X509_LIB ,"X509 lib"}, -{ERR_R_ASN1_LIB ,"ASN1 lib"}, -{ERR_R_CONF_LIB ,"CONF lib"}, -{ERR_R_CRYPTO_LIB ,"CRYPTO lib"}, -{ERR_R_EC_LIB ,"EC lib"}, -{ERR_R_SSL_LIB ,"SSL lib"}, -{ERR_R_BIO_LIB ,"BIO lib"}, -{ERR_R_PKCS7_LIB ,"PKCS7 lib"}, -{ERR_R_X509V3_LIB ,"X509V3 lib"}, -{ERR_R_PKCS12_LIB ,"PKCS12 lib"}, -{ERR_R_RAND_LIB ,"RAND lib"}, -{ERR_R_DSO_LIB ,"DSO lib"}, -{ERR_R_ENGINE_LIB ,"ENGINE lib"}, -{ERR_R_OCSP_LIB ,"OCSP lib"}, - -{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"}, -{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"}, -{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"}, -{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"}, -{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"}, -{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"}, - -{ERR_R_FATAL ,"fatal"}, -{ERR_R_MALLOC_FAILURE ,"malloc failure"}, -{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"}, -{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"}, -{ERR_R_INTERNAL_ERROR ,"internal error"}, -{ERR_R_DISABLED ,"called a function that was disabled at compile-time"}, - -{0,NULL}, - }; -#endif - -#ifndef OPENSSL_NO_ERR -#define NUM_SYS_STR_REASONS 127 -#define LEN_SYS_STR_REASON 32 - -static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; -/* SYS_str_reasons is filled with copies of strerror() results at - * initialization. - * 'errno' values up to 127 should cover all usual errors, - * others will be displayed numerically by ERR_error_string. - * It is crucial that we have something for each reason code - * that occurs in ERR_str_reasons, or bogus reason strings - * will be returned for SYSerr, which always gets an errno - * value and never one of those 'standard' reason codes. */ - -static void build_SYS_str_reasons(void) - { - /* OPENSSL_malloc cannot be used here, use static storage instead */ - static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; - int i; - static int init = 1; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - if (!init) - { - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - return; - } - - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!init) - { - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return; - } - - for (i = 1; i <= NUM_SYS_STR_REASONS; i++) - { - ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; - - str->error = (unsigned long)i; - if (str->string == NULL) - { - char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]); - char *src = strerror(i); - if (src != NULL) - { - strncpy(*dest, src, sizeof *dest); - (*dest)[sizeof *dest - 1] = '\0'; - str->string = *dest; - } - } - if (str->string == NULL) - str->string = "unknown"; - } - - /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, - * as required by ERR_load_strings. */ - - init = 0; - - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - } -#endif - -void ERR_load_ERR_strings(void) - { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ERR_str_functs[0].error) == NULL) - { - ERR_load_strings(0,ERR_str_libraries); - ERR_load_strings(0,ERR_str_reasons); - ERR_load_strings(ERR_LIB_SYS,ERR_str_functs); - build_SYS_str_reasons(); - ERR_load_strings(ERR_LIB_SYS,SYS_str_reasons); - } -#endif - } - diff --git a/crypto/openssl/crypto/evp/bio_b64.c b/crypto/openssl/crypto/evp/bio_b64.c index fa5cbc7eb1..72a2a67277 100644 --- a/crypto/openssl/crypto/evp/bio_b64.c +++ b/crypto/openssl/crypto/evp/bio_b64.c @@ -64,7 +64,7 @@ static int b64_write(BIO *h, const char *buf, int num); static int b64_read(BIO *h, char *buf, int size); -/*static int b64_puts(BIO *h, const char *str); */ +static int b64_puts(BIO *h, const char *str); /*static int b64_gets(BIO *h, char *str, int size); */ static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int b64_new(BIO *h); @@ -96,7 +96,7 @@ static BIO_METHOD methods_b64= BIO_TYPE_BASE64,"base64 encoding", b64_write, b64_read, - NULL, /* b64_puts, */ + b64_puts, NULL, /* b64_gets, */ b64_ctrl, b64_new, @@ -127,6 +127,7 @@ static int b64_new(BIO *bi) bi->init=1; bi->ptr=(char *)ctx; bi->flags=0; + bi->num = 0; return(1); } @@ -151,6 +152,8 @@ static int b64_read(BIO *b, char *out, int outl) if ((ctx == NULL) || (b->next_bio == NULL)) return(0); + BIO_clear_retry_flags(b); + if (ctx->encode != B64_DECODE) { ctx->encode=B64_DECODE; @@ -163,6 +166,7 @@ static int b64_read(BIO *b, char *out, int outl) /* First check if there are bytes decoded/encoded */ if (ctx->buf_len > 0) { + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); i=ctx->buf_len-ctx->buf_off; if (i > outl) i=outl; OPENSSL_assert(ctx->buf_off+i < (int)sizeof(ctx->buf)); @@ -184,7 +188,6 @@ static int b64_read(BIO *b, char *out, int outl) ret_code=0; while (outl > 0) { - if (ctx->cont <= 0) break; @@ -195,7 +198,7 @@ static int b64_read(BIO *b, char *out, int outl) { ret_code=i; - /* Should be continue next time we are called? */ + /* Should we continue next time we are called? */ if (!BIO_should_retry(b->next_bio)) { ctx->cont=i; @@ -285,19 +288,27 @@ static int b64_read(BIO *b, char *out, int outl) continue; } else + { ctx->tmp_len=0; } - /* If buffer isn't full and we can retry then - * restart to read in more data. - */ + } 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_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { int z,jj; +#if 0 jj=(i>>2)<<2; +#else + jj = i & ~3; /* process per 4 */ +#endif z=EVP_DecodeBlock((unsigned char *)ctx->buf, (unsigned char *)ctx->tmp,jj); if (jj > 2) @@ -313,18 +324,15 @@ static int b64_read(BIO *b, char *out, int outl) * number consumed */ if (jj != i) { - memcpy((unsigned char *)ctx->tmp, - (unsigned char *)&(ctx->tmp[jj]),i-jj); + 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=1; } - else - i=z; + i=z; } else { @@ -357,14 +365,16 @@ static int b64_read(BIO *b, char *out, int outl) outl-=i; out+=i; } - BIO_clear_retry_flags(b); + /* BIO_clear_retry_flags(b); */ BIO_copy_next_retry(b); return((ret == 0)?ret_code:ret); } static int b64_write(BIO *b, const char *in, int inl) { - int ret=inl,n,i; + int ret=0; + int n; + int i; BIO_B64_CTX *ctx; ctx=(BIO_B64_CTX *)b->ptr; @@ -379,6 +389,9 @@ static int b64_write(BIO *b, const char *in, int inl) EVP_EncodeInit(&(ctx->base64)); } + OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); n=ctx->buf_len-ctx->buf_off; while (n > 0) { @@ -388,7 +401,10 @@ static int b64_write(BIO *b, const char *in, int inl) BIO_copy_next_retry(b); return(i); } + OPENSSL_assert(i <= n); ctx->buf_off+=i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); n-=i; } /* at this point all pending data has been written */ @@ -405,18 +421,19 @@ static int b64_write(BIO *b, const char *in, int inl) { if (ctx->tmp_len > 0) { + OPENSSL_assert(ctx->tmp_len <= 3); n=3-ctx->tmp_len; - /* There's a teoretical possibility for this */ + /* There's a theoretical possibility for 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( - (unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, - ctx->tmp_len); + ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(unsigned char *)ctx->tmp,ctx->tmp_len); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); /* Since we're now done using the temporary buffer, the length should be 0'd */ ctx->tmp_len=0; @@ -425,14 +442,16 @@ static int b64_write(BIO *b, const char *in, int inl) { if (n < 3) { - memcpy(&(ctx->tmp[0]),in,n); + memcpy(ctx->tmp,in,n); ctx->tmp_len=n; + ret += n; break; } n-=n%3; - ctx->buf_len=EVP_EncodeBlock( - (unsigned char *)ctx->buf, - (unsigned char *)in,n); + ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(const unsigned char *)in,n); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; } } else @@ -440,6 +459,9 @@ static int b64_write(BIO *b, const char *in, int inl) EVP_EncodeUpdate(&(ctx->base64), (unsigned char *)ctx->buf,&ctx->buf_len, (unsigned char *)in,n); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; } inl-=n; in+=n; @@ -454,8 +476,11 @@ static int b64_write(BIO *b, const char *in, int inl) BIO_copy_next_retry(b); return((ret == 0)?i:ret); } + OPENSSL_assert(i <= n); n-=i; ctx->buf_off+=i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); } ctx->buf_len=0; ctx->buf_off=0; @@ -486,6 +511,7 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_WPENDING: /* More to write in buffer */ + OPENSSL_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)) @@ -494,6 +520,7 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_PENDING: /* More to read in buffer */ + OPENSSL_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); @@ -565,3 +592,7 @@ static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) return(ret); } +static int b64_puts(BIO *b, const char *str) + { + return b64_write(b,str,strlen(str)); + } diff --git a/crypto/openssl/crypto/evp/bio_enc.c b/crypto/openssl/crypto/evp/bio_enc.c index f6ac94c6e1..b6efb5fbc4 100644 --- a/crypto/openssl/crypto/evp/bio_enc.c +++ b/crypto/openssl/crypto/evp/bio_enc.c @@ -361,8 +361,10 @@ again: case BIO_CTRL_DUP: dbio=(BIO *)ptr; dctx=(BIO_ENC_CTX *)dbio->ptr; - memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher)); - dbio->init=1; + EVP_CIPHER_CTX_init(&dctx->cipher); + ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher); + if (ret) + dbio->init=1; break; default: ret=BIO_ctrl(b->next_bio,cmd,num,ptr); diff --git a/crypto/openssl/crypto/evp/bio_md.c b/crypto/openssl/crypto/evp/bio_md.c index ed5c1135fd..9841e32e1a 100644 --- a/crypto/openssl/crypto/evp/bio_md.c +++ b/crypto/openssl/crypto/evp/bio_md.c @@ -130,8 +130,8 @@ static int md_read(BIO *b, char *out, int outl) { if (ret > 0) { - EVP_DigestUpdate(ctx,(unsigned char *)out, - (unsigned int)ret); + if (EVP_DigestUpdate(ctx,(unsigned char *)out, + (unsigned int)ret)<=0) return (-1); } } BIO_clear_retry_flags(b); @@ -157,8 +157,11 @@ static int md_write(BIO *b, const char *in, int inl) (unsigned int)ret); } } - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); + if(b->next_bio != NULL) + { + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + } return(ret); } @@ -194,6 +197,7 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_C_GET_MD_CTX: pctx=ptr; *pctx=ctx; + b->init = 1; break; case BIO_C_SET_MD_CTX: if (b->init) @@ -249,7 +253,9 @@ static int md_gets(BIO *bp, char *buf, int size) ctx=bp->ptr; if (size < ctx->digest->md_size) return(0); - EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret); + if (EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret)<=0) + return -1; + return((int)ret); } diff --git a/crypto/openssl/crypto/evp/c_all.c b/crypto/openssl/crypto/evp/c_all.c index a5da52e62d..766c4cecdf 100644 --- a/crypto/openssl/crypto/evp/c_all.c +++ b/crypto/openssl/crypto/evp/c_all.c @@ -83,7 +83,7 @@ void OPENSSL_add_all_algorithms_noconf(void) OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); #ifndef OPENSSL_NO_ENGINE -# if defined(__OpenBSD__) || defined(__FreeBSD__) +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) ENGINE_setup_bsd_cryptodev(); # endif #endif diff --git a/crypto/openssl/crypto/evp/c_allc.c b/crypto/openssl/crypto/evp/c_allc.c index e45cee8ab0..c5f9268378 100644 --- a/crypto/openssl/crypto/evp/c_allc.c +++ b/crypto/openssl/crypto/evp/c_allc.c @@ -221,7 +221,4 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256"); EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256"); #endif - - PKCS12_PBE_add(); - PKCS5_PBE_add(); } diff --git a/crypto/openssl/crypto/evp/c_alld.c b/crypto/openssl/crypto/evp/c_alld.c index e0841d12f2..311e1fe2f8 100644 --- a/crypto/openssl/crypto/evp/c_alld.c +++ b/crypto/openssl/crypto/evp/c_alld.c @@ -78,7 +78,7 @@ void OpenSSL_add_all_digests(void) EVP_add_digest(EVP_dss()); #endif #endif -#ifndef OPENSSL_NO_SHA +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) EVP_add_digest(EVP_sha1()); EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); @@ -107,5 +107,8 @@ void OpenSSL_add_all_digests(void) #ifndef OPENSSL_NO_SHA512 EVP_add_digest(EVP_sha384()); EVP_add_digest(EVP_sha512()); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL + EVP_add_digest(EVP_whirlpool()); #endif } diff --git a/crypto/openssl/crypto/evp/digest.c b/crypto/openssl/crypto/evp/digest.c index 6a8f39bef7..982ba2b136 100644 --- a/crypto/openssl/crypto/evp/digest.c +++ b/crypto/openssl/crypto/evp/digest.c @@ -116,7 +116,6 @@ #ifndef OPENSSL_NO_ENGINE #include #endif -#include "evp_locl.h" void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { @@ -139,77 +138,18 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) return EVP_DigestInit_ex(ctx, type, NULL); } -#ifdef OPENSSL_FIPS - -/* The purpose of these is to trap programs that attempt to use non FIPS - * algorithms in FIPS mode and ignore the errors. - */ - -static int bad_init(EVP_MD_CTX *ctx) - { FIPS_ERROR_IGNORED("Digest init"); return 0;} - -static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count) - { FIPS_ERROR_IGNORED("Digest update"); return 0;} - -static int bad_final(EVP_MD_CTX *ctx,unsigned char *md) - { FIPS_ERROR_IGNORED("Digest Final"); return 0;} - -static const EVP_MD bad_md = +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { - 0, - 0, - 0, - 0, - bad_init, - bad_update, - bad_final, - NULL, - NULL, - NULL, - 0, - {0,0,0,0}, - }; - -#endif - + EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); #ifndef OPENSSL_NO_ENGINE - -#ifdef OPENSSL_FIPS - -static int do_engine_null(ENGINE *impl) { return 0;} -static int do_evp_md_engine_null(EVP_MD_CTX *ctx, - const EVP_MD **ptype, ENGINE *impl) - { return 1; } - -static int (*do_engine_init)(ENGINE *impl) - = do_engine_null; - -static int (*do_engine_finish)(ENGINE *impl) - = do_engine_null; - -static int (*do_evp_md_engine) - (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) - = do_evp_md_engine_null; - -void int_EVP_MD_set_engine_callbacks( - int (*eng_md_init)(ENGINE *impl), - int (*eng_md_fin)(ENGINE *impl), - int (*eng_md_evp) - (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)) - { - do_engine_init = eng_md_init; - do_engine_finish = eng_md_fin; - do_evp_md_engine = eng_md_evp; - } - -#else - -#define do_engine_init ENGINE_init -#define do_engine_finish ENGINE_finish - -static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) - { - if (*ptype) + /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts + * so this context may already have an ENGINE! Try to avoid releasing + * the previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. */ + if (ctx->engine && ctx->digest && (!type || + (type && (type->type == ctx->digest->type)))) + goto skip_to_init; + if (type) { /* Ensure an ENGINE left lying around from last time is cleared * (the previous check attempted to avoid this if the same @@ -220,25 +160,26 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) { if (!ENGINE_init(impl)) { - EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); + EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); return 0; } } else /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_digest_engine((*ptype)->type); + impl = ENGINE_get_digest_engine(type->type); if(impl) { /* There's an ENGINE for this job ... (apparently) */ - const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type); + const EVP_MD *d = ENGINE_get_digest(impl, type->type); if(!d) { /* Same comment from evp_enc.c */ - EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); + EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); + ENGINE_finish(impl); return 0; } /* We'll use the ENGINE's private digest definition */ - *ptype = d; + type = d; /* Store the ENGINE functional reference so we know * 'type' came from an ENGINE and we need to release * it when done. */ @@ -250,78 +191,46 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) else if(!ctx->digest) { - EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET); + EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET); return 0; } - return 1; - } - -#endif - -#endif - -int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) - { - M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); -#ifdef OPENSSL_FIPS - if(FIPS_selftest_failed()) - { - FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); - ctx->digest = &bad_md; - return 0; - } -#endif -#ifndef OPENSSL_NO_ENGINE - /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts - * so this context may already have an ENGINE! Try to avoid releasing - * the previous handle, re-querying for an ENGINE, and having a - * reinitialisation, when it may all be unecessary. */ - if (ctx->engine && ctx->digest && (!type || - (type && (type->type == ctx->digest->type)))) - goto skip_to_init; - if (!do_evp_md_engine(ctx, &type, impl)) - return 0; #endif if (ctx->digest != type) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - { - if (!(type->flags & EVP_MD_FLAG_FIPS) - && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) - { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); - ctx->digest = &bad_md; - return 0; - } - } -#endif if (ctx->digest && ctx->digest->ctx_size) OPENSSL_free(ctx->md_data); ctx->digest=type; - if (type->ctx_size) + if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { + ctx->update = type->update; ctx->md_data=OPENSSL_malloc(type->ctx_size); - if (!ctx->md_data) + if (ctx->md_data == NULL) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); + EVPerr(EVP_F_EVP_DIGESTINIT_EX, + ERR_R_MALLOC_FAILURE); return 0; } } } #ifndef OPENSSL_NO_ENGINE - skip_to_init: +skip_to_init: #endif + if (ctx->pctx) + { + int r; + r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); + if (r <= 0 && (r != -2)) + return 0; + } + if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) + return 1; return ctx->digest->init(ctx); } -int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, - size_t count) +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif - return ctx->digest->update(ctx,data,count); + return ctx->update(ctx,data,count); } /* The caller can assume that this removes any secret data from the context */ @@ -337,9 +246,6 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { int ret; -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret=ctx->digest->final(ctx,md); @@ -348,7 +254,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) if (ctx->digest->cleanup) { ctx->digest->cleanup(ctx); - M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); + EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); } memset(ctx->md_data,0,ctx->digest->ctx_size); return ret; @@ -370,7 +276,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) } #ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a digest context using an ENGINE */ - if (in->engine && !do_engine_init(in->engine)) + if (in->engine && !ENGINE_init(in->engine)) { EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB); return 0; @@ -380,13 +286,13 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) if (out->digest == in->digest) { tmp_buf = out->md_data; - M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); + EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); } else tmp_buf = NULL; EVP_MD_CTX_cleanup(out); memcpy(out,in,sizeof *out); - if (out->digest->ctx_size) + if (in->md_data && out->digest->ctx_size) { if (tmp_buf) out->md_data = tmp_buf; @@ -402,6 +308,18 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) memcpy(out->md_data,in->md_data,out->digest->ctx_size); } + out->update = in->update; + + if (in->pctx) + { + out->pctx = EVP_PKEY_CTX_dup(in->pctx); + if (!out->pctx) + { + EVP_MD_CTX_cleanup(out); + return 0; + } + } + if (out->digest->copy) return out->digest->copy(out,in); @@ -415,7 +333,7 @@ int EVP_Digest(const void *data, size_t count, int ret; EVP_MD_CTX_init(&ctx); - M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); + EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); ret=EVP_DigestInit_ex(&ctx, type, impl) && EVP_DigestUpdate(&ctx, data, count) && EVP_DigestFinal_ex(&ctx, md, size); @@ -437,19 +355,21 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) * because sometimes only copies of the context are ever finalised. */ if (ctx->digest && ctx->digest->cleanup - && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) + && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) ctx->digest->cleanup(ctx); if (ctx->digest && ctx->digest->ctx_size && ctx->md_data - && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); OPENSSL_free(ctx->md_data); } + if (ctx->pctx) + EVP_PKEY_CTX_free(ctx->pctx); #ifndef OPENSSL_NO_ENGINE if(ctx->engine) /* The EVP_MD we used belongs to an ENGINE, release the * functional reference we held for this reason. */ - do_engine_finish(ctx->engine); + ENGINE_finish(ctx->engine); #endif memset(ctx,'\0',sizeof *ctx); diff --git a/crypto/openssl/crypto/evp/e_aes.c b/crypto/openssl/crypto/evp/e_aes.c index c9a5ee8d75..bd6c0a3a62 100644 --- a/crypto/openssl/crypto/evp/e_aes.c +++ b/crypto/openssl/crypto/evp/e_aes.c @@ -69,29 +69,32 @@ typedef struct IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, NID_aes_128, 16, 16, 16, 128, - EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - aes_init_key, - NULL, NULL, NULL, NULL) + 0, aes_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL) IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, NID_aes_192, 16, 24, 16, 128, - EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - aes_init_key, - NULL, NULL, NULL, NULL) + 0, aes_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL) IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, NID_aes_256, 16, 32, 16, 128, - EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - aes_init_key, - NULL, NULL, NULL, NULL) + 0, aes_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL) -#define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags) +#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16) -IMPLEMENT_AES_CFBR(128,1,EVP_CIPH_FLAG_FIPS) -IMPLEMENT_AES_CFBR(192,1,EVP_CIPH_FLAG_FIPS) -IMPLEMENT_AES_CFBR(256,1,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(128,1) +IMPLEMENT_AES_CFBR(192,1) +IMPLEMENT_AES_CFBR(256,1) -IMPLEMENT_AES_CFBR(128,8,EVP_CIPH_FLAG_FIPS) -IMPLEMENT_AES_CFBR(192,8,EVP_CIPH_FLAG_FIPS) -IMPLEMENT_AES_CFBR(256,8,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(128,8) +IMPLEMENT_AES_CFBR(192,8) +IMPLEMENT_AES_CFBR(256,8) static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) diff --git a/crypto/openssl/crypto/evp/e_camellia.c b/crypto/openssl/crypto/evp/e_camellia.c index 365d397164..a7b40d1c60 100644 --- a/crypto/openssl/crypto/evp/e_camellia.c +++ b/crypto/openssl/crypto/evp/e_camellia.c @@ -93,7 +93,7 @@ IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY, EVP_CIPHER_get_asn1_iv, NULL) -#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) +#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) IMPLEMENT_CAMELLIA_CFBR(128,1) IMPLEMENT_CAMELLIA_CFBR(192,1) diff --git a/crypto/openssl/crypto/evp/e_des.c b/crypto/openssl/crypto/evp/e_des.c index 04376df232..ca009f2c52 100644 --- a/crypto/openssl/crypto/evp/e_des.c +++ b/crypto/openssl/crypto/evp/e_des.c @@ -72,7 +72,7 @@ static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); /* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { BLOCK_CIPHER_ecb_loop() DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt); @@ -80,24 +80,52 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, (DES_cblock *)ctx->iv, &ctx->num); + while(inl>=EVP_MAXCHUNK) + { + DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); return 1; } static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, - (DES_cblock *)ctx->iv, ctx->encrypt); + while(inl>=EVP_MAXCHUNK) + { + DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); return 1; } static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, + while(inl>=EVP_MAXCHUNK) + { + DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); return 1; } @@ -105,45 +133,62 @@ static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, /* Although we have a CFB-r implementation for DES, it doesn't pack the right way, so wrap it here */ static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - unsigned int n; + size_t n,chunk=EVP_MAXCHUNK/8; unsigned char c[1],d[1]; - for(n=0 ; n < inl ; ++n) + if (inl=chunk) { - c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; - DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv, + for(n=0 ; n < chunk*8; ++n) + { + c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; + DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv, ctx->encrypt); - out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8)); + out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) | + ((d[0]&0x80) >> (unsigned int)(n%8)); + } + inl-=chunk; + in +=chunk; + out+=chunk; + if (inlcipher_data,(DES_cblock *)ctx->iv, - ctx->encrypt); + while (inl>=EVP_MAXCHUNK) + { + DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data, + (DES_cblock *)ctx->iv,ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data, + (DES_cblock *)ctx->iv,ctx->encrypt); return 1; } BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, - EVP_CIPH_RAND_KEY, - des_init_key, NULL, + EVP_CIPH_RAND_KEY, des_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1, - EVP_CIPH_RAND_KEY, - des_init_key, NULL, + EVP_CIPH_RAND_KEY, des_init_key,NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv,des_ctrl) BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8, - EVP_CIPH_RAND_KEY, - des_init_key,NULL, + EVP_CIPH_RAND_KEY,des_init_key,NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv,des_ctrl) diff --git a/crypto/openssl/crypto/evp/e_des3.c b/crypto/openssl/crypto/evp/e_des3.c index f910af19b1..3232cfe024 100644 --- a/crypto/openssl/crypto/evp/e_des3.c +++ b/crypto/openssl/crypto/evp/e_des3.c @@ -85,7 +85,7 @@ typedef struct /* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { BLOCK_CIPHER_ecb_loop() DES_ecb3_encrypt((const_DES_cblock *)(in + i), @@ -97,48 +97,80 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_ede3_ofb64_encrypt(in, out, (long)inl, + if (inl>=EVP_MAXCHUNK) + { + DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, (DES_cblock *)ctx->iv, &ctx->num); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_ofb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num); + return 1; } static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { #ifdef KSSL_DEBUG { int i; - printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", (unsigned long)ctx, ctx->buf_len); + char *cp; + printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len); printf("\t iv= "); for(i=0;i<8;i++) printf("%02X",ctx->iv[i]); printf("\n"); } #endif /* KSSL_DEBUG */ - DES_ede3_cbc_encrypt(in, out, (long)inl, + if (inl>=EVP_MAXCHUNK) + { + DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, (DES_cblock *)ctx->iv, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cbc_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); return 1; } static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_ede3_cfb64_encrypt(in, out, (long)inl, + if (inl>=EVP_MAXCHUNK) + { + DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); return 1; } /* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right way, so wrap it here */ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - unsigned int n; + size_t n; unsigned char c[1],d[1]; for(n=0 ; n < inl ; ++n) @@ -147,25 +179,36 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, DES_ede3_cfb_encrypt(c,d,1,1, &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, (DES_cblock *)ctx->iv,ctx->encrypt); - out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8)); + out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) | + ((d[0]&0x80) >> (unsigned int)(n%8)); } return 1; } static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_ede3_cfb_encrypt(in,out,8,inl, + while (inl>=EVP_MAXCHUNK) + { + DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK, &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, (DES_cblock *)ctx->iv,ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb_encrypt(in,out,8,(long)inl, + &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, + (DES_cblock *)ctx->iv,ctx->encrypt); return 1; } BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, - EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - des_ede_init_key, - NULL, NULL, NULL, + EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, des3_ctrl) #define des_ede3_cfb64_cipher des_ede_cfb64_cipher @@ -174,21 +217,21 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, #define des_ede3_ecb_cipher des_ede_ecb_cipher BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, - EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - des_ede3_init_key, - NULL, NULL, NULL, + EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, - EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - des_ede3_init_key, - NULL, NULL, NULL, + EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, - EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, - des_ede3_init_key, - NULL, NULL, NULL, + EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, des3_ctrl) static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -215,7 +258,7 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #ifdef KSSL_DEBUG { int i; - printf("des_ede3_init_key(ctx=%lx)\n", (unsigned long)ctx); + printf("des_ede3_init_key(ctx=%lx)\n", ctx); printf("\tKEY= "); for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n"); printf("\t IV= "); diff --git a/crypto/openssl/crypto/evp/e_idea.c b/crypto/openssl/crypto/evp/e_idea.c index 48c33a774a..806b080360 100644 --- a/crypto/openssl/crypto/evp/e_idea.c +++ b/crypto/openssl/crypto/evp/e_idea.c @@ -73,7 +73,7 @@ static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, */ static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { BLOCK_CIPHER_ecb_loop() idea_ecb_encrypt(in + i, out + i, ctx->cipher_data); diff --git a/crypto/openssl/crypto/evp/e_null.c b/crypto/openssl/crypto/evp/e_null.c index 0872d733e4..7cf50e1416 100644 --- a/crypto/openssl/crypto/evp/e_null.c +++ b/crypto/openssl/crypto/evp/e_null.c @@ -64,12 +64,12 @@ static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl); + const unsigned char *in, size_t inl); static const EVP_CIPHER n_cipher= { NID_undef, 1,0,0, - EVP_CIPH_FLAG_FIPS, + 0, null_init_key, null_cipher, NULL, @@ -93,10 +93,10 @@ static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { if (in != out) - memcpy((char *)out,(const char *)in,(size_t)inl); + memcpy((char *)out,(const char *)in,inl); return 1; } diff --git a/crypto/openssl/crypto/evp/e_rc2.c b/crypto/openssl/crypto/evp/e_rc2.c index d37726ffae..f78d781129 100644 --- a/crypto/openssl/crypto/evp/e_rc2.c +++ b/crypto/openssl/crypto/evp/e_rc2.c @@ -223,6 +223,11 @@ static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; } return 0; +#ifdef PBE_PRF_TEST + case EVP_CTRL_PBE_PRF_NID: + *(int *)ptr = NID_hmacWithMD5; + return 1; +#endif default: return -1; diff --git a/crypto/openssl/crypto/evp/e_rc4.c b/crypto/openssl/crypto/evp/e_rc4.c index 55baad7446..8b5175e0fd 100644 --- a/crypto/openssl/crypto/evp/e_rc4.c +++ b/crypto/openssl/crypto/evp/e_rc4.c @@ -64,7 +64,6 @@ #include #include #include -#include "evp_locl.h" /* FIXME: surely this is available elsewhere? */ #define EVP_RC4_KEY_SIZE 16 @@ -79,7 +78,7 @@ typedef struct static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl); + const unsigned char *in, size_t inl); static const EVP_CIPHER r4_cipher= { NID_rc4, @@ -129,7 +128,7 @@ static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { RC4(&data(ctx)->ks,inl,in,out); return 1; diff --git a/crypto/openssl/crypto/o_init.c b/crypto/openssl/crypto/evp/e_seed.c similarity index 76% copy from crypto/openssl/crypto/o_init.c copy to crypto/openssl/crypto/evp/e_seed.c index 2a5f5aac76..2d1759d276 100644 --- a/crypto/openssl/crypto/o_init.c +++ b/crypto/openssl/crypto/evp/e_seed.c @@ -1,7 +1,4 @@ -/* o_init.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ +/* crypto/evp/e_seed.c -*- mode:C; c-file-style: "eay" -*- */ /* ==================================================================== * Copyright (c) 2007 The OpenSSL Project. All rights reserved. * @@ -56,36 +53,31 @@ * */ -#include +#include +#ifndef OPENSSL_NO_SEED +#include #include -/* Internal only functions: only ever used here */ -extern void int_ERR_lib_init(void); -extern void int_EVP_MD_init_engine_callbacks(void ); -extern void int_EVP_CIPHER_init_engine_callbacks(void ); -extern void int_RAND_init_engine_callbacks(void ); +#include +#include +#include +#include "evp_locl.h" -/* Perform any essential OpenSSL initialization operations. - * Currently only sets FIPS callbacks - */ +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); -void OPENSSL_init(void) +typedef struct { -#ifdef OPENSSL_FIPS - static int done = 0; - if (!done) - { - int_ERR_lib_init(); -#ifdef CRYPTO_MDEBUG - CRYPTO_malloc_debug_init(); -#endif -#ifndef OPENSSL_NO_ENGINE - int_EVP_MD_init_engine_callbacks(); - int_EVP_CIPHER_init_engine_callbacks(); - int_RAND_init_engine_callbacks(); -#endif - done = 1; - } -#endif + SEED_KEY_SCHEDULE ks; + } EVP_SEED_KEY; + +IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed, + 16, 16, 16, 128, + 0, seed_init_key, 0, 0, 0, 0) + +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + SEED_set_key(key, ctx->cipher_data); + return 1; } - +#endif diff --git a/crypto/openssl/crypto/evp/e_xcbc_d.c b/crypto/openssl/crypto/evp/e_xcbc_d.c index 8832da2433..250e88c8c5 100644 --- a/crypto/openssl/crypto/evp/e_xcbc_d.c +++ b/crypto/openssl/crypto/evp/e_xcbc_d.c @@ -63,12 +63,13 @@ #include #include +#include "evp_locl.h" #include static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl); + const unsigned char *in, size_t inl); typedef struct @@ -113,13 +114,25 @@ static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - DES_xcbc_encrypt(in,out,inl,&data(ctx)->ks, + while (inl>=EVP_MAXCHUNK) + { + DES_xcbc_encrypt(in,out,(long)EVP_MAXCHUNK,&data(ctx)->ks, (DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_xcbc_encrypt(in,out,(long)inl,&data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), + &data(ctx)->inw, + &data(ctx)->outw, + ctx->encrypt); return 1; } #endif diff --git a/crypto/openssl/crypto/evp/enc_min.c b/crypto/openssl/crypto/evp/enc_min.c deleted file mode 100644 index 7fba38ee24..0000000000 --- a/crypto/openssl/crypto/evp/enc_min.c +++ /dev/null @@ -1,390 +0,0 @@ -/* crypto/evp/enc_min.c */ -/* 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 -#include "cryptlib.h" -#include -#include -#include -#ifndef OPENSSL_NO_ENGINE -#include -#endif -#include "evp_locl.h" - -void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) - { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif - memset(ctx,0,sizeof(EVP_CIPHER_CTX)); - /* ctx->cipher=NULL; */ - } - -#ifdef OPENSSL_FIPS - -/* The purpose of these is to trap programs that attempt to use non FIPS - * algorithms in FIPS mode and ignore the errors. - */ - -static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) - { FIPS_ERROR_IGNORED("Cipher init"); return 0;} - -static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) - { FIPS_ERROR_IGNORED("Cipher update"); return 0;} - -/* NB: no cleanup because it is allowed after failed init */ - -static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) - { FIPS_ERROR_IGNORED("Cipher set_asn1"); return 0;} -static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) - { FIPS_ERROR_IGNORED("Cipher get_asn1"); return 0;} -static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) - { FIPS_ERROR_IGNORED("Cipher ctrl"); return 0;} - -static const EVP_CIPHER bad_cipher = - { - 0, - 0, - 0, - 0, - 0, - bad_init, - bad_do_cipher, - NULL, - 0, - bad_set_asn1, - bad_get_asn1, - bad_ctrl, - NULL - }; - -#endif - -#ifndef OPENSSL_NO_ENGINE - -#ifdef OPENSSL_FIPS - -static int do_engine_null(ENGINE *impl) { return 0;} -static int do_evp_enc_engine_null(EVP_CIPHER_CTX *ctx, - const EVP_CIPHER **pciph, ENGINE *impl) - { return 1; } - -static int (*do_engine_finish)(ENGINE *impl) - = do_engine_null; - -static int (*do_evp_enc_engine) - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl) - = do_evp_enc_engine_null; - -void int_EVP_CIPHER_set_engine_callbacks( - int (*eng_ciph_fin)(ENGINE *impl), - int (*eng_ciph_evp) - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)) - { - do_engine_finish = eng_ciph_fin; - do_evp_enc_engine = eng_ciph_evp; - } - -#else - -#define do_engine_finish ENGINE_finish - -static int do_evp_enc_engine(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl) - { - if(impl) - { - if (!ENGINE_init(impl)) - { - EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } - else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_cipher_engine((*pcipher)->nid); - if(impl) - { - /* There's an ENGINE for this job ... (apparently) */ - const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); - if(!c) - { - /* One positive side-effect of US's export - * control history, is that we should at least - * be able to avoid using US mispellings of - * "initialisation"? */ - EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR); - return 0; - } - /* We'll use the ENGINE's private cipher definition */ - *pcipher = c; - /* Store the ENGINE functional reference so we know - * 'cipher' came from an ENGINE and we need to release - * it when done. */ - ctx->engine = impl; - } - else - ctx->engine = NULL; - return 1; - } - -#endif - -#endif - -int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, - const unsigned char *key, const unsigned char *iv, int enc) - { - if (enc == -1) - enc = ctx->encrypt; - else - { - if (enc) - enc = 1; - ctx->encrypt = enc; - } -#ifdef OPENSSL_FIPS - if(FIPS_selftest_failed()) - { - FIPSerr(FIPS_F_EVP_CIPHERINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); - ctx->cipher = &bad_cipher; - return 0; - } -#endif -#ifndef OPENSSL_NO_ENGINE - /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts - * so this context may already have an ENGINE! Try to avoid releasing - * the previous handle, re-querying for an ENGINE, and having a - * reinitialisation, when it may all be unecessary. */ - if (ctx->engine && ctx->cipher && (!cipher || - (cipher && (cipher->nid == ctx->cipher->nid)))) - goto skip_to_init; -#endif - if (cipher) - { - /* Ensure a context left lying around from last time is cleared - * (the previous check attempted to avoid this if the same - * ENGINE and EVP_CIPHER could be used). */ - EVP_CIPHER_CTX_cleanup(ctx); - - /* Restore encrypt field: it is zeroed by cleanup */ - ctx->encrypt = enc; -#ifndef OPENSSL_NO_ENGINE - if (!do_evp_enc_engine(ctx, &cipher, impl)) - return 0; -#endif - - ctx->cipher=cipher; - if (ctx->cipher->ctx_size) - { - ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); - if (!ctx->cipher_data) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); - return 0; - } - } - else - { - ctx->cipher_data = NULL; - } - ctx->key_len = cipher->key_len; - ctx->flags = 0; - if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) - { - if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } - } - else if(!ctx->cipher) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); - return 0; - } -#ifndef OPENSSL_NO_ENGINE -skip_to_init: -#endif - /* we assume block size is a power of 2 in *cryptUpdate */ - OPENSSL_assert(ctx->cipher->block_size == 1 - || ctx->cipher->block_size == 8 - || ctx->cipher->block_size == 16); - - if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { - switch(EVP_CIPHER_CTX_mode(ctx)) { - - case EVP_CIPH_STREAM_CIPHER: - case EVP_CIPH_ECB_MODE: - break; - - case EVP_CIPH_CFB_MODE: - case EVP_CIPH_OFB_MODE: - - ctx->num = 0; - - case EVP_CIPH_CBC_MODE: - - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= - (int)sizeof(ctx->iv)); - if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); - break; - - default: - return 0; - break; - } - } - -#ifdef OPENSSL_FIPS - /* After 'key' is set no further parameters changes are permissible. - * So only check for non FIPS enabling at this point. - */ - if (key && FIPS_mode()) - { - if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS) - & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS); -#if 0 - ERR_add_error_data(2, "cipher=", - EVP_CIPHER_name(ctx->cipher)); -#endif - ctx->cipher = &bad_cipher; - return 0; - } - } -#endif - - if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { - if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; - } - ctx->buf_len=0; - ctx->final_used=0; - ctx->block_mask=ctx->cipher->block_size-1; - return 1; - } - -int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) - { - if (c->cipher != NULL) - { - if(c->cipher->cleanup && !c->cipher->cleanup(c)) - return 0; - /* Cleanse cipher context data */ - if (c->cipher_data) - OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); - } - if (c->cipher_data) - OPENSSL_free(c->cipher_data); -#ifndef OPENSSL_NO_ENGINE - if (c->engine) - /* The EVP_CIPHER we used belongs to an ENGINE, release the - * functional reference we held for this reason. */ - do_engine_finish(c->engine); -#endif - memset(c,0,sizeof(EVP_CIPHER_CTX)); - return 1; - } - -int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) - { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif - return ctx->cipher->do_cipher(ctx,out,in,inl); - } - -int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) -{ - int ret; - if(!ctx->cipher) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); - return 0; - } - - if(!ctx->cipher->ctrl) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); - return 0; - } - - ret = ctx->cipher->ctrl(ctx, type, arg, ptr); - if(ret == -1) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); - return 0; - } - return ret; -} - -unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) - { - return ctx->cipher->flags; - } - -int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) - { - return ctx->cipher->iv_len; - } - -int EVP_CIPHER_nid(const EVP_CIPHER *cipher) - { - return cipher->nid; - } diff --git a/crypto/openssl/crypto/evp/encode.c b/crypto/openssl/crypto/evp/encode.c index 5921f0d710..b42c747249 100644 --- a/crypto/openssl/crypto/evp/encode.c +++ b/crypto/openssl/crypto/evp/encode.c @@ -85,7 +85,7 @@ #define CHUNKS_PER_LINE (64/4) #define CHAR_PER_LINE (64+1) -static unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\ +static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz0123456789+/"; /* 0xF0 is a EOLN @@ -102,7 +102,7 @@ abcdefghijklmnopqrstuvwxyz0123456789+/"; #define B64_ERROR 0xFF #define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) -static unsigned char data_ascii2bin[128]={ +static const unsigned char data_ascii2bin[128]={ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, diff --git a/crypto/openssl/crypto/evp/evp.h b/crypto/openssl/crypto/evp/evp.h index 79c097181f..9f9795e2d9 100644 --- a/crypto/openssl/crypto/evp/evp.h +++ b/crypto/openssl/crypto/evp/evp.h @@ -75,10 +75,6 @@ #include #endif -#ifdef OPENSSL_FIPS -#include -#endif - /* #define EVP_RC2_KEY_SIZE 16 #define EVP_RC4_KEY_SIZE 16 @@ -119,6 +115,7 @@ #define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 #define EVP_PKEY_DH NID_dhKeyAgreement #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_HMAC NID_hmac #ifdef __cplusplus extern "C" { @@ -132,6 +129,8 @@ struct evp_pkey_st int type; int save_type; int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; union { char *ptr; #ifndef OPENSSL_NO_RSA @@ -156,73 +155,6 @@ struct evp_pkey_st #define EVP_PKEY_MO_ENCRYPT 0x0004 #define EVP_PKEY_MO_DECRYPT 0x0008 -#if 0 -/* This structure is required to tie the message digest and signing together. - * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or - * oid, md and pkey. - * This is required because for various smart-card perform the digest and - * signing/verification on-board. To handle this case, the specific - * EVP_MD and EVP_PKEY_METHODs need to be closely associated. - * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it. - * This can either be software or a token to provide the required low level - * routines. - */ -typedef struct evp_pkey_md_st - { - int oid; - EVP_MD *md; - EVP_PKEY_METHOD *pkey; - } EVP_PKEY_MD; - -#define EVP_rsa_md2() \ - EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\ - EVP_rsa_pkcs1(),EVP_md2()) -#define EVP_rsa_md5() \ - EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\ - EVP_rsa_pkcs1(),EVP_md5()) -#define EVP_rsa_sha0() \ - EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\ - EVP_rsa_pkcs1(),EVP_sha()) -#define EVP_rsa_sha1() \ - EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\ - EVP_rsa_pkcs1(),EVP_sha1()) -#define EVP_rsa_ripemd160() \ - EVP_PKEY_MD_add(NID_ripemd160WithRSA,\ - EVP_rsa_pkcs1(),EVP_ripemd160()) -#define EVP_rsa_mdc2() \ - EVP_PKEY_MD_add(NID_mdc2WithRSA,\ - EVP_rsa_octet_string(),EVP_mdc2()) -#define EVP_dsa_sha() \ - EVP_PKEY_MD_add(NID_dsaWithSHA,\ - EVP_dsa(),EVP_sha()) -#define EVP_dsa_sha1() \ - EVP_PKEY_MD_add(NID_dsaWithSHA1,\ - EVP_dsa(),EVP_sha1()) - -typedef struct evp_pkey_method_st - { - char *name; - int flags; - int type; /* RSA, DSA, an SSLeay specific constant */ - int oid; /* For the pub-key type */ - int encrypt_oid; /* pub/priv key encryption */ - - int (*sign)(); - int (*verify)(); - struct { - int (*set)(); /* get and/or set the underlying type */ - int (*get)(); - int (*encrypt)(); - int (*decrypt)(); - int (*i2d)(); - int (*d2i)(); - int (*dup)(); - } pub,priv; - int (*set_asn1_parameters)(); - int (*get_asn1_parameters)(); - } EVP_PKEY_METHOD; -#endif - #ifndef EVP_MD struct env_md_st { @@ -245,6 +177,8 @@ struct env_md_st int required_pkey_type[5]; /*EVP_PKEY_xxx */ int block_size; int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); } /* EVP_MD */; typedef int evp_sign_method(int type,const unsigned char *m, @@ -254,18 +188,42 @@ typedef int evp_verify_method(int type,const unsigned char *m, unsigned int m_length,const unsigned char *sigbuf, unsigned int siglen, void *key); -typedef struct - { - EVP_MD_CTX *mctx; - void *key; - } EVP_MD_SVCTX; - #define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single * block */ -#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ +#define EVP_MD_FLAG_PKEY_DIGEST 0x0002 /* digest is a "clone" digest used + * which is a copy of an existing + * one for a specific public key type. + * EVP_dss1() etc */ + +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ + +#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 + +/* DigestAlgorithmIdentifier flags... */ + +#define EVP_MD_FLAG_DIGALGID_MASK 0x0018 -#define EVP_MD_FLAG_SVCTX 0x0800 /* pass EVP_MD_SVCTX to sign/verify */ +/* NULL or absent parameter accepted. Use NULL */ + +#define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +#define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Digest ctrls */ + +#define EVP_MD_CTRL_DIGALGID 0x1 +#define EVP_MD_CTRL_MICALG 0x2 + +/* Minimum Algorithm specific ctrl value */ + +#define EVP_MD_CTRL_ALG_CTRL 0x1000 #define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} @@ -307,6 +265,10 @@ struct env_md_ctx_st ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */ unsigned long flags; void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count); } /* EVP_MD_CTX */; /* values for EVP_MD_CTX flags */ @@ -317,17 +279,23 @@ struct env_md_ctx_st * cleaned */ #define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data * in EVP_MD_CTX_cleanup */ +/* FIPS and pad options are ignored in 1.0.0, definitions are here + * so we don't accidentally reuse the values for other purposes. + */ + #define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest * in FIPS mode */ +/* The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ #define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */ #define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ #define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ #define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ -#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \ - ((ctx->flags>>16) &0xFFFF) /* seed length */ -#define EVP_MD_CTX_FLAG_PSS_MDLEN 0xFFFF /* salt len same as digest */ -#define EVP_MD_CTX_FLAG_PSS_MREC 0xFFFE /* salt max or auto recovered */ + +#define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */ struct evp_cipher_st { @@ -339,7 +307,7 @@ struct evp_cipher_st int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* init key */ int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */ + const unsigned char *in, size_t inl);/* encrypt/decrypt data */ int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ int ctx_size; /* how big ctx->cipher_data needs to be */ int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ @@ -357,7 +325,7 @@ struct evp_cipher_st #define EVP_CIPH_CBC_MODE 0x2 #define EVP_CIPH_CFB_MODE 0x3 #define EVP_CIPH_OFB_MODE 0x4 -#define EVP_CIPH_MODE 0x7 +#define EVP_CIPH_MODE 0xF0007 /* Set if variable length cipher */ #define EVP_CIPH_VARIABLE_LENGTH 0x8 /* Set if the iv handling should be done by the cipher itself */ @@ -372,10 +340,8 @@ struct evp_cipher_st #define EVP_CIPH_NO_PADDING 0x100 /* cipher handles random key generation */ #define EVP_CIPH_RAND_KEY 0x200 -/* Note if suitable for use in FIPS mode */ -#define EVP_CIPH_FLAG_FIPS 0x400 -/* Allow non FIPS cipher in FIPS mode */ -#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 +/* cipher has its own additional copying logic */ +#define EVP_CIPH_CUSTOM_COPY 0x400 /* Allow use default ASN1 get/set iv */ #define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 /* Buffer length in bits not bytes: CFB1 mode only */ @@ -390,6 +356,8 @@ struct evp_cipher_st #define EVP_CTRL_GET_RC5_ROUNDS 0x4 #define EVP_CTRL_SET_RC5_ROUNDS 0x5 #define EVP_CTRL_RAND_KEY 0x6 +#define EVP_CTRL_PBE_PRF_NID 0x7 +#define EVP_CTRL_COPY 0x8 typedef struct evp_cipher_info_st { @@ -462,26 +430,15 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) -/* Macros to reduce FIPS dependencies: do NOT use in applications */ -#define M_EVP_MD_size(e) ((e)->md_size) -#define M_EVP_MD_block_size(e) ((e)->block_size) -#define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) -#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs)) -#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs)) -#define M_EVP_MD_type(e) ((e)->type) -#define M_EVP_MD_CTX_type(e) M_EVP_MD_type(M_EVP_MD_CTX_md(e)) -#define M_EVP_MD_CTX_md(e) ((e)->digest) - -#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) - int EVP_MD_type(const EVP_MD *md); #define EVP_MD_nid(e) EVP_MD_type(e) #define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) int EVP_MD_pkey_type(const EVP_MD *md); int EVP_MD_size(const EVP_MD *md); int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); -const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); #define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) #define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) #define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) @@ -499,6 +456,7 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) @@ -516,6 +474,8 @@ unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); #define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) #define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) #define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +#define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) #ifdef CONST_STRICT void BIO_set_md(BIO *,const EVP_MD *md); @@ -562,6 +522,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify); +int EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify); void EVP_set_pw_prompt(const char *prompt); char * EVP_get_pw_prompt(void); @@ -608,6 +569,16 @@ int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s, int EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf, unsigned int siglen,EVP_PKEY *pkey); +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, + unsigned char *sigret, size_t *siglen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, + unsigned char *sig, size_t siglen); + int EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv); @@ -680,6 +651,9 @@ const EVP_MD *EVP_mdc2(void); #ifndef OPENSSL_NO_RIPEMD const EVP_MD *EVP_ripemd160(void); #endif +#ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +#endif const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ #ifndef OPENSSL_NO_DES const EVP_CIPHER *EVP_des_ecb(void); @@ -847,16 +821,31 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name); const EVP_MD *EVP_get_digestbyname(const char *name); void EVP_cleanup(void); -int EVP_PKEY_decrypt(unsigned char *dec_key, +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *x), void *arg); +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key,int enc_key_len, EVP_PKEY *private_key); -int EVP_PKEY_encrypt(unsigned char *enc_key, +int EVP_PKEY_encrypt_old(unsigned char *enc_key, const unsigned char *key,int key_len, EVP_PKEY *pub_key); int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); int EVP_PKEY_bits(EVP_PKEY *pkey); int EVP_PKEY_size(EVP_PKEY *pkey); -int EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key); +int EVP_PKEY_set_type(EVP_PKEY *pkey,int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key); +void * EVP_PKEY_get0(EVP_PKEY *pkey); #ifndef OPENSSL_NO_RSA struct rsa_st; @@ -899,6 +888,15 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + int EVP_CIPHER_type(const EVP_CIPHER *ctx); /* calls methods */ @@ -916,6 +914,10 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, + int keylen, unsigned char *out); int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de); @@ -924,27 +926,260 @@ void PKCS5_PBE_add(void); int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen, ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +#define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +#define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, + EVP_PBE_KEYGEN *keygen); int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen); void EVP_PBE_cleanup(void); -#ifdef OPENSSL_FIPS -#ifndef OPENSSL_NO_ENGINE -void int_EVP_MD_set_engine_callbacks( - int (*eng_md_init)(ENGINE *impl), - int (*eng_md_fin)(ENGINE *impl), - int (*eng_md_evp) - (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)); -void int_EVP_MD_init_engine_callbacks(void); -void int_EVP_CIPHER_set_engine_callbacks( - int (*eng_ciph_fin)(ENGINE *impl), - int (*eng_ciph_evp) - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)); -void int_EVP_CIPHER_init_engine_callbacks(void); -#endif -#endif +#define ASN1_PKEY_ALIAS 0x1 +#define ASN1_PKEY_DYNAMIC 0x2 +#define ASN1_PKEY_SIGPARAM_NULL 0x4 + +#define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +#define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +#define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub), + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk), + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx), + int (*pkey_size)(const EVP_PKEY *pk), + int (*pkey_bits)(const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf), + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk), + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode)(EVP_PKEY *pkey, + const unsigned char **pder, int derlen), + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **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), + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free)(EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, + long arg1, void *arg2)); + + +#define EVP_PKEY_OP_UNDEFINED 0 +#define EVP_PKEY_OP_PARAMGEN (1<<1) +#define EVP_PKEY_OP_KEYGEN (1<<2) +#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_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +#define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +#define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +#define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +#define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_PEER_KEY 2 + +#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +#define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +#define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +#define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +#define EVP_PKEY_CTRL_SET_IV 8 + +#define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +#define EVP_PKEY_CTRL_CMS_DECRYPT 10 +#define EVP_PKEY_CTRL_CMS_SIGN 11 + +#define EVP_PKEY_ALG_CTRL 0x1000 + + +#define EVP_PKEY_FLAG_AUTOARGLEN 2 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + unsigned char *key, int keylen); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init)(EVP_PKEY_CTX *ctx), + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init)(EVP_PKEY_CTX *ctx), + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); -void EVP_add_alg_module(void); +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + 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)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + 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)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init)(EVP_PKEY_CTX *ctx), + int (*verify_recover)(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + 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)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + 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)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init)(EVP_PKEY_CTX *ctx), + int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + 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)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init)(EVP_PKEY_CTX *ctx), + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + 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)); /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -956,46 +1191,66 @@ void ERR_load_EVP_strings(void); /* Function codes. */ #define EVP_F_AES_INIT_KEY 133 -#define EVP_F_ALG_MODULE_INIT 138 #define EVP_F_CAMELLIA_INIT_KEY 159 #define EVP_F_D2I_PKEY 100 -#define EVP_F_DO_EVP_ENC_ENGINE 140 -#define EVP_F_DO_EVP_ENC_ENGINE_FULL 141 -#define EVP_F_DO_EVP_MD_ENGINE 139 -#define EVP_F_DO_EVP_MD_ENGINE_FULL 142 +#define EVP_F_DO_SIGVER_INIT 161 #define EVP_F_DSAPKEY2PKCS8 134 #define EVP_F_DSA_PKEY2PKCS8 135 #define EVP_F_ECDSA_PKEY2PKCS8 129 #define EVP_F_ECKEY_PKEY2PKCS8 132 -#define EVP_F_EVP_CIPHERINIT 137 #define EVP_F_EVP_CIPHERINIT_EX 123 +#define EVP_F_EVP_CIPHER_CTX_COPY 163 #define EVP_F_EVP_CIPHER_CTX_CTRL 124 #define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 #define EVP_F_EVP_DECRYPTFINAL_EX 101 -#define EVP_F_EVP_DIGESTINIT 136 #define EVP_F_EVP_DIGESTINIT_EX 128 #define EVP_F_EVP_ENCRYPTFINAL_EX 127 #define EVP_F_EVP_MD_CTX_COPY_EX 110 +#define EVP_F_EVP_MD_SIZE 162 #define EVP_F_EVP_OPENINIT 102 #define EVP_F_EVP_PBE_ALG_ADD 115 +#define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 #define EVP_F_EVP_PBE_CIPHERINIT 116 #define EVP_F_EVP_PKCS82PKEY 111 +#define EVP_F_EVP_PKCS82PKEY_BROKEN 136 #define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 #define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +#define EVP_F_EVP_PKEY_CTX_CTRL 137 +#define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +#define EVP_F_EVP_PKEY_CTX_DUP 156 #define EVP_F_EVP_PKEY_DECRYPT 104 +#define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +#define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +#define EVP_F_EVP_PKEY_DERIVE 153 +#define EVP_F_EVP_PKEY_DERIVE_INIT 154 +#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 #define EVP_F_EVP_PKEY_ENCRYPT 105 +#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 #define EVP_F_EVP_PKEY_GET1_DH 119 #define EVP_F_EVP_PKEY_GET1_DSA 120 #define EVP_F_EVP_PKEY_GET1_ECDSA 130 #define EVP_F_EVP_PKEY_GET1_EC_KEY 131 #define EVP_F_EVP_PKEY_GET1_RSA 121 +#define EVP_F_EVP_PKEY_KEYGEN 146 +#define EVP_F_EVP_PKEY_KEYGEN_INIT 147 #define EVP_F_EVP_PKEY_NEW 106 +#define EVP_F_EVP_PKEY_PARAMGEN 148 +#define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +#define EVP_F_EVP_PKEY_SIGN 140 +#define EVP_F_EVP_PKEY_SIGN_INIT 141 +#define EVP_F_EVP_PKEY_VERIFY 142 +#define EVP_F_EVP_PKEY_VERIFY_INIT 143 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 #define EVP_F_EVP_RIJNDAEL 126 #define EVP_F_EVP_SIGNFINAL 107 #define EVP_F_EVP_VERIFYFINAL 108 +#define EVP_F_INT_CTX_NEW 157 #define EVP_F_PKCS5_PBE_KEYIVGEN 117 #define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 #define EVP_F_PKCS8_SET_BROKEN 112 +#define EVP_F_PKEY_SET_TYPE 158 #define EVP_F_RC2_MAGIC_TO_METH 109 #define EVP_F_RC5_CTRL 125 @@ -1007,41 +1262,52 @@ void ERR_load_EVP_strings(void); #define EVP_R_BAD_KEY_LENGTH 137 #define EVP_R_BN_DECODE_ERROR 112 #define EVP_R_BN_PUBKEY_ERROR 113 +#define EVP_R_BUFFER_TOO_SMALL 155 #define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 #define EVP_R_CIPHER_PARAMETER_ERROR 122 +#define EVP_R_COMMAND_NOT_SUPPORTED 147 #define EVP_R_CTRL_NOT_IMPLEMENTED 132 #define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 #define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 #define EVP_R_DECODE_ERROR 114 #define EVP_R_DIFFERENT_KEY_TYPES 101 -#define EVP_R_DISABLED_FOR_FIPS 144 +#define EVP_R_DIFFERENT_PARAMETERS 153 #define EVP_R_ENCODE_ERROR 115 -#define EVP_R_ERROR_LOADING_SECTION 145 -#define EVP_R_ERROR_SETTING_FIPS_MODE 146 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 #define EVP_R_EXPECTING_AN_RSA_KEY 127 #define EVP_R_EXPECTING_A_DH_KEY 128 #define EVP_R_EXPECTING_A_DSA_KEY 129 #define EVP_R_EXPECTING_A_ECDSA_KEY 141 #define EVP_R_EXPECTING_A_EC_KEY 142 -#define EVP_R_FIPS_MODE_NOT_SUPPORTED 147 #define EVP_R_INITIALIZATION_ERROR 134 #define EVP_R_INPUT_NOT_INITIALIZED 111 -#define EVP_R_INVALID_FIPS_MODE 148 +#define EVP_R_INVALID_DIGEST 152 #define EVP_R_INVALID_KEY_LENGTH 130 +#define EVP_R_INVALID_OPERATION 148 #define EVP_R_IV_TOO_LARGE 102 #define EVP_R_KEYGEN_FAILURE 120 +#define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +#define EVP_R_METHOD_NOT_SUPPORTED 144 #define EVP_R_MISSING_PARAMETERS 103 #define EVP_R_NO_CIPHER_SET 131 +#define EVP_R_NO_DEFAULT_DIGEST 158 #define EVP_R_NO_DIGEST_SET 139 #define EVP_R_NO_DSA_PARAMETERS 116 +#define EVP_R_NO_KEY_SET 154 +#define EVP_R_NO_OPERATION_SET 149 #define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +#define EVP_R_OPERATON_NOT_INITIALIZED 151 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 #define EVP_R_PUBLIC_KEY_NOT_RSA 106 -#define EVP_R_UNKNOWN_OPTION 149 +#define EVP_R_UNKNOWN_CIPHER 160 +#define EVP_R_UNKNOWN_DIGEST 161 #define EVP_R_UNKNOWN_PBE_ALGORITHM 121 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +#define EVP_R_UNSUPPORTED_ALGORITHM 156 #define EVP_R_UNSUPPORTED_CIPHER 107 #define EVP_R_UNSUPPORTED_KEYLENGTH 123 #define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 @@ -1051,7 +1317,6 @@ void ERR_load_EVP_strings(void); #define EVP_R_UNSUPPORTED_SALT_TYPE 126 #define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 #define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 -#define EVP_R_SEED_KEY_SETUP_FAILED 162 #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/evp/evp_enc.c b/crypto/openssl/crypto/evp/evp_enc.c index 30e0ca4d9f..bead6a2170 100644 --- a/crypto/openssl/crypto/evp/evp_enc.c +++ b/crypto/openssl/crypto/evp/evp_enc.c @@ -66,16 +66,14 @@ #endif #include "evp_locl.h" -#ifdef OPENSSL_FIPS - #define M_do_cipher(ctx, out, in, inl) \ - EVP_Cipher(ctx,out,in,inl) -#else - #define M_do_cipher(ctx, out, in, inl) \ - ctx->cipher->do_cipher(ctx,out,in,inl) -#endif - const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) + { + memset(ctx,0,sizeof(EVP_CIPHER_CTX)); + /* ctx->cipher=NULL; */ + } + EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) { EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx); @@ -92,6 +90,144 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); } +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, const unsigned char *iv, int enc) + { + if (enc == -1) + enc = ctx->encrypt; + else + { + if (enc) + enc = 1; + ctx->encrypt = enc; + } +#ifndef OPENSSL_NO_ENGINE + /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts + * so this context may already have an ENGINE! Try to avoid releasing + * the previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. */ + if (ctx->engine && ctx->cipher && (!cipher || + (cipher && (cipher->nid == ctx->cipher->nid)))) + goto skip_to_init; +#endif + if (cipher) + { + /* Ensure a context left lying around from last time is cleared + * (the previous check attempted to avoid this if the same + * ENGINE and EVP_CIPHER could be used). */ + EVP_CIPHER_CTX_cleanup(ctx); + + /* Restore encrypt field: it is zeroed by cleanup */ + ctx->encrypt = enc; +#ifndef OPENSSL_NO_ENGINE + if(impl) + { + if (!ENGINE_init(impl)) + { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_cipher_engine(cipher->nid); + if(impl) + { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); + if(!c) + { + /* One positive side-effect of US's export + * control history, is that we should at least + * be able to avoid using US mispellings of + * "initialisation"? */ + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + /* We'll use the ENGINE's private cipher definition */ + cipher = c; + /* Store the ENGINE functional reference so we know + * 'cipher' came from an ENGINE and we need to release + * it when done. */ + ctx->engine = impl; + } + else + ctx->engine = NULL; +#endif + + ctx->cipher=cipher; + if (ctx->cipher->ctx_size) + { + ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); + if (!ctx->cipher_data) + { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } + else + { + ctx->cipher_data = NULL; + } + ctx->key_len = cipher->key_len; + ctx->flags = 0; + if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) + { + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) + { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + } + else if(!ctx->cipher) + { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); + return 0; + } +#ifndef OPENSSL_NO_ENGINE +skip_to_init: +#endif + /* we assume block size is a power of 2 in *cryptUpdate */ + OPENSSL_assert(ctx->cipher->block_size == 1 + || ctx->cipher->block_size == 8 + || ctx->cipher->block_size == 16); + + if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch(EVP_CIPHER_CTX_mode(ctx)) { + + case EVP_CIPH_STREAM_CIPHER: + case EVP_CIPH_ECB_MODE: + break; + + case EVP_CIPH_CFB_MODE: + case EVP_CIPH_OFB_MODE: + + ctx->num = 0; + + case EVP_CIPH_CBC_MODE: + + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= + (int)sizeof(ctx->iv)); + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + default: + return 0; + break; + } + } + + if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; + } + ctx->buf_len=0; + ctx->final_used=0; + ctx->block_mask=ctx->cipher->block_size-1; + return 1; + } + int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { @@ -151,7 +287,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { - if(M_do_cipher(ctx,out,in,inl)) + if(ctx->cipher->do_cipher(ctx,out,in,inl)) { *outl=inl; return 1; @@ -178,7 +314,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { j=bl-i; memcpy(&(ctx->buf[i]),in,j); - if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; + if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; inl-=j; in+=j; out+=bl; @@ -191,7 +327,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, inl-=i; if (inl > 0) { - if(!M_do_cipher(ctx,out,in,inl)) return 0; + if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0; *outl+=inl; } @@ -235,7 +371,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) n=b-bl; for (i=bl; ibuf[i]=n; - ret=M_do_cipher(ctx,out,ctx->buf,b); + ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); if(ret) @@ -357,6 +493,28 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) } } +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) + { + if (c->cipher != NULL) + { + if(c->cipher->cleanup && !c->cipher->cleanup(c)) + return 0; + /* Cleanse cipher context data */ + if (c->cipher_data) + OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); + } + if (c->cipher_data) + OPENSSL_free(c->cipher_data); +#ifndef OPENSSL_NO_ENGINE + if (c->engine) + /* The EVP_CIPHER we used belongs to an ENGINE, release the + * functional reference we held for this reason. */ + ENGINE_finish(c->engine); +#endif + memset(c,0,sizeof(EVP_CIPHER_CTX)); + return 1; + } + int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) { if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) @@ -378,6 +536,27 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) return 1; } +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + int ret; + if(!ctx->cipher) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); + return 0; + } + + if(!ctx->cipher->ctrl) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, type, arg, ptr); + if(ret == -1) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + return ret; +} + int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) { if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) @@ -387,54 +566,38 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) return 1; } -#ifndef OPENSSL_NO_ENGINE - -#ifdef OPENSSL_FIPS - -static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl) +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { - if(impl) + if ((in == NULL) || (in->cipher == NULL)) { - if (!ENGINE_init(impl)) - { - EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); - return 0; - } + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED); + return 0; } - else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_cipher_engine((*pcipher)->nid); - if(impl) +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a cipher context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) + { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB); + return 0; + } +#endif + + EVP_CIPHER_CTX_cleanup(out); + memcpy(out,in,sizeof *out); + + if (in->cipher_data && in->cipher->ctx_size) { - /* There's an ENGINE for this job ... (apparently) */ - const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); - if(!c) + out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) { - /* One positive side-effect of US's export - * control history, is that we should at least - * be able to avoid using US mispellings of - * "initialisation"? */ - EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE); return 0; } - /* We'll use the ENGINE's private cipher definition */ - *pcipher = c; - /* Store the ENGINE functional reference so we know - * 'cipher' came from an ENGINE and we need to release - * it when done. */ - ctx->engine = impl; + memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size); } - else - ctx->engine = NULL; - return 1; - } -void int_EVP_CIPHER_init_engine_callbacks(void) - { - int_EVP_CIPHER_set_engine_callbacks( - ENGINE_finish, do_evp_enc_engine_full); + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) + return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); + return 1; } -#endif - -#endif diff --git a/crypto/openssl/crypto/evp/evp_err.c b/crypto/openssl/crypto/evp/evp_err.c index b5b900d4fe..d8bfec0959 100644 --- a/crypto/openssl/crypto/evp/evp_err.c +++ b/crypto/openssl/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* crypto/evp/evp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 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 @@ -71,46 +71,66 @@ static ERR_STRING_DATA EVP_str_functs[]= { {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"}, -{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"}, {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"}, {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"}, -{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE), "DO_EVP_ENC_ENGINE"}, -{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE_FULL), "DO_EVP_ENC_ENGINE_FULL"}, -{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE), "DO_EVP_MD_ENGINE"}, -{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE_FULL), "DO_EVP_MD_ENGINE_FULL"}, +{ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"}, {ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"}, {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, -{ERR_FUNC(EVP_F_EVP_CIPHERINIT), "EVP_CipherInit"}, {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, +{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"}, {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), "EVP_CIPHER_CTX_set_key_length"}, {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, -{ERR_FUNC(EVP_F_EVP_DIGESTINIT), "EVP_DigestInit"}, {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, +{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_SIZE"}, {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, +{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"}, {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"}, {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, +{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"}, {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"}, {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, +{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"}, +{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"}, +{ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"}, {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"}, +{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"}, +{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"}, +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"}, +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"}, +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"}, {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"}, +{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"}, +{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"}, +{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"}, +{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"}, {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"}, +{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"}, +{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"}, +{ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"}, +{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"}, +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"}, +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"}, +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"}, +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT), "EVP_PKEY_verify_recover_init"}, {ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"}, {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"}, {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"}, +{ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"}, {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, +{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"}, {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, {ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"}, {0,NULL} @@ -125,42 +145,52 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_BAD_KEY_LENGTH) ,"bad key length"}, {ERR_REASON(EVP_R_BN_DECODE_ERROR) ,"bn decode error"}, {ERR_REASON(EVP_R_BN_PUBKEY_ERROR) ,"bn pubkey error"}, +{ERR_REASON(EVP_R_BUFFER_TOO_SMALL) ,"buffer too small"}, {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),"camellia key setup failed"}, {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR),"cipher parameter error"}, +{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) ,"command not supported"}, {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED) ,"ctrl not implemented"}, {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),"ctrl operation not implemented"}, {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"}, {ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"}, -{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) ,"disabled for fips"}, +{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"}, {ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"}, -{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"}, -{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"}, {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"}, {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) ,"expecting a dh key"}, {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) ,"expecting a dsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"}, -{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"}, {ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"}, {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"}, -{ERR_REASON(EVP_R_INVALID_FIPS_MODE) ,"invalid fips mode"}, +{ERR_REASON(EVP_R_INVALID_DIGEST) ,"invalid digest"}, {ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"}, +{ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"}, {ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"}, {ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"}, +{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL),"message digest is null"}, +{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) ,"method not supported"}, {ERR_REASON(EVP_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"}, +{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST) ,"no default digest"}, {ERR_REASON(EVP_R_NO_DIGEST_SET) ,"no digest set"}, {ERR_REASON(EVP_R_NO_DSA_PARAMETERS) ,"no dsa parameters"}, +{ERR_REASON(EVP_R_NO_KEY_SET) ,"no key set"}, +{ERR_REASON(EVP_R_NO_OPERATION_SET) ,"no operation set"}, {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"}, {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"}, +{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"}, +{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED),"operaton not initialized"}, {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"}, +{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"}, +{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"}, {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"}, -{ERR_REASON(EVP_R_SEED_KEY_SETUP_FAILED) ,"seed key setup failed"}, -{ERR_REASON(EVP_R_UNKNOWN_OPTION) ,"unknown option"}, +{ERR_REASON(EVP_R_UNKNOWN_CIPHER) ,"unknown cipher"}, +{ERR_REASON(EVP_R_UNKNOWN_DIGEST) ,"unknown digest"}, {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"}, {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"}, +{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"}, {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"}, {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"}, diff --git a/crypto/openssl/crypto/evp/evp_key.c b/crypto/openssl/crypto/evp/evp_key.c index 361ea69ab6..839d6a3a16 100644 --- a/crypto/openssl/crypto/evp/evp_key.c +++ b/crypto/openssl/crypto/evp/evp_key.c @@ -89,6 +89,11 @@ char *EVP_get_pw_prompt(void) * in the DES library -- if someone ever wants to disable DES, * this function will fail */ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) + { + return EVP_read_pw_string_min(buf, 0, len, prompt, verify); + } + +int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify) { int ret; char buff[BUFSIZ]; @@ -97,10 +102,10 @@ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) if ((prompt == NULL) && (prompt_string[0] != '\0')) prompt=prompt_string; ui = UI_new(); - UI_add_input_string(ui,prompt,0,buf,0,(len>=BUFSIZ)?BUFSIZ-1:len); + UI_add_input_string(ui,prompt,0,buf,min,(len>=BUFSIZ)?BUFSIZ-1:len); if (verify) UI_add_verify_string(ui,prompt,0, - buff,0,(len>=BUFSIZ)?BUFSIZ-1:len,buf); + buff,min,(len>=BUFSIZ)?BUFSIZ-1:len,buf); ret = UI_process(ui); UI_free(ui); OPENSSL_cleanse(buff,BUFSIZ); diff --git a/crypto/openssl/crypto/evp/evp_lib.c b/crypto/openssl/crypto/evp/evp_lib.c index 9c200617a6..40951a04f0 100644 --- a/crypto/openssl/crypto/evp/evp_lib.c +++ b/crypto/openssl/crypto/evp/evp_lib.c @@ -67,8 +67,6 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (c->cipher->set_asn1_parameters != NULL) ret=c->cipher->set_asn1_parameters(c,type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) - ret=EVP_CIPHER_set_asn1_iv(c, type); else ret=-1; return(ret); @@ -80,8 +78,6 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (c->cipher->get_asn1_parameters != NULL) ret=c->cipher->get_asn1_parameters(c,type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) - ret=EVP_CIPHER_get_asn1_iv(c, type); else ret=-1; return(ret); @@ -188,6 +184,11 @@ int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) return ctx->cipher->block_size; } +int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) + { + return ctx->cipher->do_cipher(ctx,out,in,inl); + } + const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { return ctx->cipher; @@ -198,6 +199,11 @@ unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) return cipher->flags; } +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) + { + return ctx->cipher->flags; + } + void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) { return ctx->app_data; @@ -213,6 +219,11 @@ int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) return cipher->iv_len; } +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) + { + return ctx->cipher->iv_len; + } + int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { return cipher->key_len; @@ -223,6 +234,11 @@ int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) return ctx->key_len; } +int EVP_CIPHER_nid(const EVP_CIPHER *cipher) + { + return cipher->nid; + } + int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) { return ctx->cipher->nid; @@ -245,11 +261,23 @@ int EVP_MD_pkey_type(const EVP_MD *md) int EVP_MD_size(const EVP_MD *md) { + if (!md) + { + EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); + return -1; + } return md->md_size; } -const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx) +unsigned long EVP_MD_flags(const EVP_MD *md) + { + return md->flags; + } + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { + if (!ctx) + return NULL; return ctx->digest; } diff --git a/crypto/openssl/crypto/evp/evp_locl.h b/crypto/openssl/crypto/evp/evp_locl.h index 72105b0fe2..292d74c188 100644 --- a/crypto/openssl/crypto/evp/evp_locl.h +++ b/crypto/openssl/crypto/evp/evp_locl.h @@ -61,38 +61,66 @@ /* Wrapper functions for each cipher mode */ #define BLOCK_CIPHER_ecb_loop() \ - unsigned int i, bl; \ + size_t i, bl; \ bl = ctx->cipher->block_size;\ if(inl < bl) return 1;\ inl -= bl; \ for(i=0; i <= inl; i+=bl) #define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \ -static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ +static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ {\ BLOCK_CIPHER_ecb_loop() \ cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\ return 1;\ } +#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2)) + #define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ -static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ +static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ {\ - cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + while(inl>=EVP_MAXCHUNK)\ + {\ + cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + inl-=EVP_MAXCHUNK;\ + in +=EVP_MAXCHUNK;\ + out+=EVP_MAXCHUNK;\ + }\ + if (inl)\ + cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ return 1;\ } #define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ -static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ +static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ {\ - cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + while(inl>=EVP_MAXCHUNK) \ + {\ + cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + inl-=EVP_MAXCHUNK;\ + in +=EVP_MAXCHUNK;\ + out+=EVP_MAXCHUNK;\ + }\ + if (inl)\ + cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ return 1;\ } #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ -static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ +static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ {\ - cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + size_t chunk=EVP_MAXCHUNK;\ + if (cbits==1) chunk>>=3;\ + if (inl=chunk)\ + {\ + cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + inl-=chunk;\ + in +=chunk;\ + out+=chunk;\ + if(inlcipher_data) -#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \ +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ - (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \ - cipher##_init_key, NULL, NULL, NULL, NULL) - -#ifdef OPENSSL_FIPS -#define RC2_set_key private_RC2_set_key -#define RC4_set_key private_RC4_set_key -#define CAST_set_key private_CAST_set_key -#define RC5_32_set_key private_RC5_32_set_key -#define BF_set_key private_BF_set_key -#define Camellia_set_key private_Camellia_set_key -#define idea_set_encrypt_key private_idea_set_encrypt_key - -#define MD5_Init private_MD5_Init -#define MD4_Init private_MD4_Init -#define MD2_Init private_MD2_Init -#define MDC2_Init private_MDC2_Init -#define SHA_Init private_SHA_Init - -#endif + 0, cipher##_init_key, NULL, \ + EVP_CIPHER_set_asn1_iv, \ + EVP_CIPHER_get_asn1_iv, \ + NULL) + +struct evp_pkey_ctx_st + { + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Actual operation */ + int operation; + /* Algorithm specific data */ + void *data; + /* Application specific data */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; + } /* EVP_PKEY_CTX */; + +#define EVP_PKEY_FLAG_DYNAMIC 1 + +struct evp_pkey_method_st + { + int pkey_id; + int flags; + + int (*init)(EVP_PKEY_CTX *ctx); + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup)(EVP_PKEY_CTX *ctx); + + int (*paramgen_init)(EVP_PKEY_CTX *ctx); + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*keygen_init)(EVP_PKEY_CTX *ctx); + 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 (*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 (*verify_recover_init)(EVP_PKEY_CTX *ctx); + int (*verify_recover)(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + + 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 (*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 (*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 (*derive_init)(EVP_PKEY_CTX *ctx); + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *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 */; +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); diff --git a/crypto/openssl/crypto/evp/evp_pbe.c b/crypto/openssl/crypto/evp/evp_pbe.c index 5e830be65f..c9d932d205 100644 --- a/crypto/openssl/crypto/evp/evp_pbe.c +++ b/crypto/openssl/crypto/evp/evp_pbe.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -59,79 +59,253 @@ #include #include "cryptlib.h" #include +#include #include /* Password based encryption (PBE) functions */ -static STACK *pbe_algs; +DECLARE_STACK_OF(EVP_PBE_CTL) +static STACK_OF(EVP_PBE_CTL) *pbe_algs; /* Setup a cipher context from a PBE algorithm */ -typedef struct { -int pbe_nid; -const EVP_CIPHER *cipher; -const EVP_MD *md; -EVP_PBE_KEYGEN *keygen; -} EVP_PBE_CTL; +typedef struct + { + int pbe_type; + int pbe_nid; + int cipher_nid; + int md_nid; + EVP_PBE_KEYGEN *keygen; + } EVP_PBE_CTL; -int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, - ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) -{ +static const EVP_PBE_CTL builtin_pbe[] = + { + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, + NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, + NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, + NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, - EVP_PBE_CTL *pbetmp, pbelu; - int i; - pbelu.pbe_nid = OBJ_obj2nid(pbe_obj); - if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu); - else i = -1; + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, + NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, + NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, + NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, + NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, + NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, +#endif + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, + NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, + NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, + NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + + + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, + {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, + }; + +#ifdef TEST +int main(int argc, char **argv) + { + int i, nid_md, nid_cipher; + EVP_PBE_CTL *tpbe, *tpbe2; + /*OpenSSL_add_all_algorithms();*/ + + for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++) + { + tpbe = builtin_pbe + i; + fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid, + OBJ_nid2sn(tpbe->pbe_nid)); + if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid, + &nid_cipher ,&nid_md,0)) + fprintf(stderr, "Found %s %s\n", + OBJ_nid2sn(nid_cipher), + OBJ_nid2sn(nid_md)); + else + fprintf(stderr, "Find ERROR!!\n"); + } + + return 0; + } +#endif + + + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) + { + const EVP_CIPHER *cipher; + const EVP_MD *md; + int cipher_nid, md_nid; + EVP_PBE_KEYGEN *keygen; - if (i == -1) { + if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), + &cipher_nid, &md_nid, &keygen)) + { char obj_tmp[80]; EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); ERR_add_error_data(2, "TYPE=", obj_tmp); return 0; - } - if(!pass) passlen = 0; - else if (passlen == -1) passlen = strlen(pass); - pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i); - i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher, - pbetmp->md, en_de); - if (!i) { + } + + if(!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + if (cipher_nid == -1) + cipher = NULL; + else + { + cipher = EVP_get_cipherbynid(cipher_nid); + if (!cipher) + { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER); + return 0; + } + } + + if (md_nid == -1) + md = NULL; + else + { + md = EVP_get_digestbynid(md_nid); + if (!md) + { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST); + return 0; + } + } + + if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) + { EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); return 0; - } + } return 1; } -static int pbe_cmp(const char * const *a, const char * const *b) -{ - const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a, - * const *pbe2 = (const EVP_PBE_CTL * const *)b; - return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid); -} +DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); + +static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) + { + int ret = pbe1->pbe_type - pbe2->pbe_type; + if (ret) + return ret; + else + return pbe1->pbe_nid - pbe2->pbe_nid; + } + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); + +static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b) + { + int ret = (*a)->pbe_type - (*b)->pbe_type; + if (ret) + return ret; + else + return (*a)->pbe_nid - (*b)->pbe_nid; + } /* Add a PBE algorithm */ -int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, - EVP_PBE_KEYGEN *keygen) -{ +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, + EVP_PBE_KEYGEN *keygen) + { EVP_PBE_CTL *pbe_tmp; - if (!pbe_algs) pbe_algs = sk_new(pbe_cmp); - if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) { - EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE); + if (!pbe_algs) + pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); + if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) + { + EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE); return 0; - } - pbe_tmp->pbe_nid = nid; - pbe_tmp->cipher = cipher; - pbe_tmp->md = md; + } + pbe_tmp->pbe_type = pbe_type; + pbe_tmp->pbe_nid = pbe_nid; + pbe_tmp->cipher_nid = cipher_nid; + pbe_tmp->md_nid = md_nid; pbe_tmp->keygen = keygen; - sk_push (pbe_algs, (char *)pbe_tmp); + + + sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp); return 1; -} + } + +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen) + { + int cipher_nid, md_nid; + if (cipher) + cipher_nid = EVP_CIPHER_type(cipher); + else + cipher_nid = -1; + if (md) + md_nid = EVP_MD_type(md); + else + md_nid = -1; + + return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, + cipher_nid, md_nid, keygen); + } + +int EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) + { + EVP_PBE_CTL *pbetmp = NULL, pbelu; + int i; + if (pbe_nid == NID_undef) + return 0; + + pbelu.pbe_type = type; + pbelu.pbe_nid = pbe_nid; + + if (pbe_algs) + { + i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); + if (i != -1) + pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i); + } + if (pbetmp == NULL) + { + pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, + sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL)); + } + if (pbetmp == NULL) + return 0; + if (pcnid) + *pcnid = pbetmp->cipher_nid; + if (pmnid) + *pmnid = pbetmp->md_nid; + if (pkeygen) + *pkeygen = pbetmp->keygen; + return 1; + } + +static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) + { + OPENSSL_freeFunc(pbe); + } void EVP_PBE_cleanup(void) -{ - sk_pop_free(pbe_algs, OPENSSL_freeFunc); + { + sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); pbe_algs = NULL; -} + } diff --git a/crypto/openssl/crypto/evp/evp_pkey.c b/crypto/openssl/crypto/evp/evp_pkey.c index 10d9e9e772..ceebf69284 100644 --- a/crypto/openssl/crypto/evp/evp_pkey.c +++ b/crypto/openssl/crypto/evp/evp_pkey.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -61,287 +61,52 @@ #include "cryptlib.h" #include #include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#include - -#ifndef OPENSSL_NO_DSA -static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey); -#endif -#ifndef OPENSSL_NO_EC -static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey); -#endif +#include "asn1_locl.h" /* Extract a private key from a PKCS8 structure */ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; -#ifndef OPENSSL_NO_RSA - RSA *rsa = NULL; -#endif -#ifndef OPENSSL_NO_DSA - DSA *dsa = NULL; - ASN1_TYPE *t1, *t2; - ASN1_INTEGER *privkey; - STACK_OF(ASN1_TYPE) *ndsa = NULL; -#endif -#ifndef OPENSSL_NO_EC - EC_KEY *eckey = NULL; - const unsigned char *p_tmp; -#endif -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) - ASN1_TYPE *param = NULL; - BN_CTX *ctx = NULL; - int plen; -#endif - X509_ALGOR *a; - const unsigned char *p; - const unsigned char *cp; - int pkeylen; - int nid; + ASN1_OBJECT *algoid; char obj_tmp[80]; - if(p8->pkey->type == V_ASN1_OCTET_STRING) { - p8->broken = PKCS8_OK; - p = p8->pkey->value.octet_string->data; - pkeylen = p8->pkey->value.octet_string->length; - } else { - p8->broken = PKCS8_NO_OCTET; - p = p8->pkey->value.sequence->data; - pkeylen = p8->pkey->value.sequence->length; - } + if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) + return NULL; + if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } - a = p8->pkeyalg; - nid = OBJ_obj2nid(a->algorithm); - switch(nid) - { -#ifndef OPENSSL_NO_RSA - case NID_rsaEncryption: - cp = p; - if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - return NULL; - } - EVP_PKEY_assign_RSA (pkey, rsa); - break; -#endif -#ifndef OPENSSL_NO_DSA - case NID_dsa: - /* PKCS#8 DSA is weird: you just get a private key integer - * and parameters in the AlgorithmIdentifier the pubkey must - * be recalculated. - */ - - /* Check for broken DSA PKCS#8, UGH! */ - if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { - if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, - d2i_ASN1_TYPE, - ASN1_TYPE_free))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - if(sk_ASN1_TYPE_num(ndsa) != 2 ) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - /* Handle Two broken types: - * SEQUENCE {parameters, priv_key} - * SEQUENCE {pub_key, priv_key} - */ - - t1 = sk_ASN1_TYPE_value(ndsa, 0); - t2 = sk_ASN1_TYPE_value(ndsa, 1); - if(t1->type == V_ASN1_SEQUENCE) { - p8->broken = PKCS8_EMBEDDED_PARAM; - param = t1; - } else if(a->parameter->type == V_ASN1_SEQUENCE) { - p8->broken = PKCS8_NS_DB; - param = a->parameter; - } else { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - - if(t2->type != V_ASN1_INTEGER) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - privkey = t2->value.integer; - } else { - if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - param = p8->pkeyalg->parameter; - } - if (!param || (param->type != V_ASN1_SEQUENCE)) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - cp = p = param->value.sequence->data; - plen = param->value.sequence->length; - if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto dsaerr; - } - /* We have parameters now set private key */ - if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { - EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); - goto dsaerr; - } - /* Calculate public key (ouch!) */ - if (!(dsa->pub_key = BN_new())) { - EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - if (!(ctx = BN_CTX_new())) { - EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - - if (!BN_mod_exp(dsa->pub_key, dsa->g, - dsa->priv_key, dsa->p, ctx)) { - - EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); - goto dsaerr; - } - EVP_PKEY_assign_DSA(pkey, dsa); - BN_CTX_free (ctx); - if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); - else ASN1_INTEGER_free(privkey); - break; - dsaerr: - BN_CTX_free (ctx); - sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); - DSA_free(dsa); - EVP_PKEY_free(pkey); - return NULL; - break; -#endif -#ifndef OPENSSL_NO_EC - case NID_X9_62_id_ecPublicKey: - p_tmp = p; - /* extract the ec parameters */ - param = p8->pkeyalg->parameter; - - if (!param || ((param->type != V_ASN1_SEQUENCE) && - (param->type != V_ASN1_OBJECT))) + if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto ecerr; + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + i2t_ASN1_OBJECT(obj_tmp, 80, algoid); + ERR_add_error_data(2, "TYPE=", obj_tmp); + goto error; } - if (param->type == V_ASN1_SEQUENCE) + if (pkey->ameth->priv_decode) { - cp = p = param->value.sequence->data; - plen = param->value.sequence->length; - - if (!(eckey = d2i_ECParameters(NULL, &cp, plen))) + if (!pkey->ameth->priv_decode(pkey, p8)) { - EVPerr(EVP_F_EVP_PKCS82PKEY, - EVP_R_DECODE_ERROR); - goto ecerr; + EVPerr(EVP_F_EVP_PKCS82PKEY, + EVP_R_PRIVATE_KEY_DECODE_ERROR); + goto error; } } - else + else { - EC_GROUP *group; - cp = p = param->value.object->data; - plen = param->value.object->length; - - /* type == V_ASN1_OBJECT => the parameters are given - * by an asn1 OID - */ - if ((eckey = EC_KEY_new()) == NULL) - { - EVPerr(EVP_F_EVP_PKCS82PKEY, - ERR_R_MALLOC_FAILURE); - goto ecerr; - } - group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); - if (group == NULL) - goto ecerr; - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(eckey, group) == 0) - goto ecerr; - EC_GROUP_free(group); - } - - /* We have parameters now set private key */ - if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen)) - { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); - goto ecerr; - } - - /* calculate public key (if necessary) */ - if (EC_KEY_get0_public_key(eckey) == NULL) - { - const BIGNUM *priv_key; - const EC_GROUP *group; - EC_POINT *pub_key; - /* the public key was not included in the SEC1 private - * key => calculate the public key */ - group = EC_KEY_get0_group(eckey); - pub_key = EC_POINT_new(group); - if (pub_key == NULL) - { - EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); - goto ecerr; - } - if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) - { - EC_POINT_free(pub_key); - EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); - goto ecerr; - } - priv_key = EC_KEY_get0_private_key(eckey); - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) - { - EC_POINT_free(pub_key); - EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); - goto ecerr; - } - if (EC_KEY_set_public_key(eckey, pub_key) == 0) - { - EC_POINT_free(pub_key); - EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); - goto ecerr; - } - EC_POINT_free(pub_key); + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); + goto error; } - EVP_PKEY_assign_EC_KEY(pkey, eckey); - if (ctx) - BN_CTX_free(ctx); - break; -ecerr: - if (ctx) - BN_CTX_free(ctx); - if (eckey) - EC_KEY_free(eckey); - if (pkey) - EVP_PKEY_free(pkey); - return NULL; -#endif - default: - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); - if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); - else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); - ERR_add_error_data(2, "TYPE=", obj_tmp); - EVP_PKEY_free (pkey); - return NULL; - } return pkey; + + error: + EVP_PKEY_free (pkey); + return NULL; } PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) @@ -360,59 +125,37 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) return NULL; } p8->broken = broken; - if (!ASN1_INTEGER_set(p8->version, 0)) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); - PKCS8_PRIV_KEY_INFO_free (p8); - return NULL; - } - if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); - PKCS8_PRIV_KEY_INFO_free (p8); - return NULL; - } - p8->pkey->type = V_ASN1_OCTET_STRING; - switch (EVP_PKEY_type(pkey->type)) { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE; - - p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption); - p8->pkeyalg->parameter->type = V_ASN1_NULL; - if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey, - &p8->pkey->value.octet_string)) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); - PKCS8_PRIV_KEY_INFO_free (p8); - return NULL; - } - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - if(!dsa_pkey2pkcs8(p8, pkey)) { - PKCS8_PRIV_KEY_INFO_free (p8); - return NULL; + if (pkey->ameth) + { + if (pkey->ameth->priv_encode) + { + if (!pkey->ameth->priv_encode(p8, pkey)) + { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_PRIVATE_KEY_ENCODE_ERROR); + goto error; + } + } + else + { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } } - - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - if (!eckey_pkey2pkcs8(p8, pkey)) + else { - PKCS8_PRIV_KEY_INFO_free(p8); - return(NULL); + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + goto error; } - break; -#endif - default: - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); - PKCS8_PRIV_KEY_INFO_free (p8); - return NULL; - } RAND_add(p8->pkey->value.octet_string->data, p8->pkey->value.octet_string->length, 0.0); return p8; + error: + PKCS8_PRIV_KEY_INFO_free(p8); + return NULL; } PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) @@ -436,301 +179,6 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) } } -#ifndef OPENSSL_NO_DSA -static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) -{ - ASN1_STRING *params = NULL; - ASN1_INTEGER *prkey = NULL; - ASN1_TYPE *ttmp = NULL; - STACK_OF(ASN1_TYPE) *ndsa = NULL; - unsigned char *p = NULL, *q; - int len; - - p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa); - len = i2d_DSAparams (pkey->pkey.dsa, NULL); - if (!(p = OPENSSL_malloc(len))) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - q = p; - i2d_DSAparams (pkey->pkey.dsa, &q); - if (!(params = ASN1_STRING_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - if (!ASN1_STRING_set(params, p, len)) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_free(p); - p = NULL; - /* Get private key into integer */ - if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR); - goto err; - } - - switch(p8->broken) { - - case PKCS8_OK: - case PKCS8_NO_OCTET: - - if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER, - &p8->pkey->value.octet_string)) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - - M_ASN1_INTEGER_free (prkey); - prkey = NULL; - p8->pkeyalg->parameter->value.sequence = params; - params = NULL; - p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; - - break; - - case PKCS8_NS_DB: - - p8->pkeyalg->parameter->value.sequence = params; - params = NULL; - p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; - if (!(ndsa = sk_ASN1_TYPE_new_null())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - if (!(ttmp = ASN1_TYPE_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - if (!(ttmp->value.integer = - BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR); - goto err; - } - ttmp->type = V_ASN1_INTEGER; - if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!(ttmp = ASN1_TYPE_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - ttmp->value.integer = prkey; - prkey = NULL; - ttmp->type = V_ASN1_INTEGER; - if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - ttmp = NULL; - - if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, - &p8->pkey->value.octet_string->data, - &p8->pkey->value.octet_string->length)) { - - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); - break; - - case PKCS8_EMBEDDED_PARAM: - - p8->pkeyalg->parameter->type = V_ASN1_NULL; - if (!(ndsa = sk_ASN1_TYPE_new_null())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - if (!(ttmp = ASN1_TYPE_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - ttmp->value.sequence = params; - params = NULL; - ttmp->type = V_ASN1_SEQUENCE; - if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!(ttmp = ASN1_TYPE_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - ttmp->value.integer = prkey; - prkey = NULL; - ttmp->type = V_ASN1_INTEGER; - if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - ttmp = NULL; - - if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) { - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, - &p8->pkey->value.octet_string->data, - &p8->pkey->value.octet_string->length)) { - - EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); - goto err; - } - sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); - break; - } - return 1; -err: - if (p != NULL) OPENSSL_free(p); - if (params != NULL) ASN1_STRING_free(params); - if (prkey != NULL) M_ASN1_INTEGER_free(prkey); - if (ttmp != NULL) ASN1_TYPE_free(ttmp); - if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); - return 0; -} -#endif - -#ifndef OPENSSL_NO_EC -static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) -{ - EC_KEY *ec_key; - const EC_GROUP *group; - unsigned char *p, *pp; - int nid, i, ret = 0; - unsigned int tmp_flags, old_flags; - - ec_key = pkey->pkey.ec; - if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS); - return 0; - } - - /* set the ec parameters OID */ - if (p8->pkeyalg->algorithm) - ASN1_OBJECT_free(p8->pkeyalg->algorithm); - - p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey); - - /* set the ec parameters */ - - if (p8->pkeyalg->parameter) - { - ASN1_TYPE_free(p8->pkeyalg->parameter); - p8->pkeyalg->parameter = NULL; - } - - if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL) - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (EC_GROUP_get_asn1_flag(group) - && (nid = EC_GROUP_get_curve_name(group))) - { - /* we have a 'named curve' => just set the OID */ - p8->pkeyalg->parameter->type = V_ASN1_OBJECT; - p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid); - } - else /* explicit parameters */ - { - if ((i = i2d_ECParameters(ec_key, NULL)) == 0) - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); - return 0; - } - if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); - return 0; - } - pp = p; - if (!i2d_ECParameters(ec_key, &pp)) - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); - OPENSSL_free(p); - return 0; - } - p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; - if ((p8->pkeyalg->parameter->value.sequence - = ASN1_STRING_new()) == NULL) - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB); - OPENSSL_free(p); - return 0; - } - ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i); - OPENSSL_free(p); - } - - /* set the private key */ - - /* do not include the parameters in the SEC1 private key - * see PKCS#11 12.11 */ - old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec); - tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; - EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags); - i = i2d_ECPrivateKey(pkey->pkey.ec, NULL); - if (!i) - { - EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); - return 0; - } - p = (unsigned char *) OPENSSL_malloc(i); - if (!p) - { - EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); - return 0; - } - pp = p; - if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp)) - { - EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); - OPENSSL_free(p); - return 0; - } - /* restore old encoding flags */ - EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); - - switch(p8->broken) { - - case PKCS8_OK: - p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); - if (!p8->pkey->value.octet_string || - !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string, - (const void *)p, i)) - - { - EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); - } - else - ret = 1; - break; - case PKCS8_NO_OCTET: /* RSA specific */ - case PKCS8_NS_DB: /* DSA specific */ - case PKCS8_EMBEDDED_PARAM: /* DSA specific */ - default: - EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR); - } - OPENSSL_cleanse(p, (size_t)i); - OPENSSL_free(p); - return ret; -} -#endif - /* EVP_PKEY attribute functions */ int EVP_PKEY_get_attr_count(const EVP_PKEY *key) diff --git a/crypto/openssl/crypto/evp/m_dss.c b/crypto/openssl/crypto/evp/m_dss.c index 6b0c0aa7a3..48c2689504 100644 --- a/crypto/openssl/crypto/evp/m_dss.c +++ b/crypto/openssl/crypto/evp/m_dss.c @@ -81,7 +81,7 @@ static const EVP_MD dsa_md= NID_dsaWithSHA, NID_dsaWithSHA, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_FIPS, + EVP_MD_FLAG_PKEY_DIGEST, init, update, final, diff --git a/crypto/openssl/crypto/evp/m_dss1.c b/crypto/openssl/crypto/evp/m_dss1.c index da8babc147..4f03fb70e0 100644 --- a/crypto/openssl/crypto/evp/m_dss1.c +++ b/crypto/openssl/crypto/evp/m_dss1.c @@ -68,8 +68,6 @@ #include #endif -#ifndef OPENSSL_FIPS - static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -84,7 +82,7 @@ static const EVP_MD dss1_md= NID_dsa, NID_dsaWithSHA1, SHA_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_DIGEST, init, update, final, @@ -100,4 +98,3 @@ const EVP_MD *EVP_dss1(void) return(&dss1_md); } #endif -#endif diff --git a/crypto/openssl/crypto/evp/m_ecdsa.c b/crypto/openssl/crypto/evp/m_ecdsa.c index fad270faca..8d87a49ebe 100644 --- a/crypto/openssl/crypto/evp/m_ecdsa.c +++ b/crypto/openssl/crypto/evp/m_ecdsa.c @@ -130,7 +130,7 @@ static const EVP_MD ecdsa_md= NID_ecdsa_with_SHA1, NID_ecdsa_with_SHA1, SHA_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_DIGEST, init, update, final, diff --git a/crypto/openssl/crypto/evp/m_md2.c b/crypto/openssl/crypto/evp/m_md2.c index 8eee6236ba..5ce849f161 100644 --- a/crypto/openssl/crypto/evp/m_md2.c +++ b/crypto/openssl/crypto/evp/m_md2.c @@ -58,7 +58,6 @@ #include #include "cryptlib.h" -#include "evp_locl.h" #ifndef OPENSSL_NO_MD2 diff --git a/crypto/openssl/crypto/evp/m_md4.c b/crypto/openssl/crypto/evp/m_md4.c index 5cd2ab5ade..1e0b7c5b42 100644 --- a/crypto/openssl/crypto/evp/m_md4.c +++ b/crypto/openssl/crypto/evp/m_md4.c @@ -58,7 +58,6 @@ #include #include "cryptlib.h" -#include "evp_locl.h" #ifndef OPENSSL_NO_MD4 diff --git a/crypto/openssl/crypto/evp/m_md5.c b/crypto/openssl/crypto/evp/m_md5.c index 6455829671..63c142119e 100644 --- a/crypto/openssl/crypto/evp/m_md5.c +++ b/crypto/openssl/crypto/evp/m_md5.c @@ -62,7 +62,6 @@ #ifndef OPENSSL_NO_MD5 #include -#include "evp_locl.h" #include #include #include diff --git a/crypto/openssl/crypto/evp/m_mdc2.c b/crypto/openssl/crypto/evp/m_mdc2.c index 9f9bcf06ed..b08d559803 100644 --- a/crypto/openssl/crypto/evp/m_mdc2.c +++ b/crypto/openssl/crypto/evp/m_mdc2.c @@ -58,7 +58,6 @@ #include #include "cryptlib.h" -#include "evp_locl.h" #ifndef OPENSSL_NO_MDC2 @@ -66,7 +65,9 @@ #include #include #include +#ifndef OPENSSL_NO_RSA #include +#endif static int init(EVP_MD_CTX *ctx) { return MDC2_Init(ctx->md_data); } diff --git a/crypto/openssl/crypto/evp/m_sha.c b/crypto/openssl/crypto/evp/m_sha.c index 3f30dfc579..acccc8f92d 100644 --- a/crypto/openssl/crypto/evp/m_sha.c +++ b/crypto/openssl/crypto/evp/m_sha.c @@ -58,7 +58,6 @@ #include #include "cryptlib.h" -#include "evp_locl.h" #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) diff --git a/crypto/openssl/crypto/evp/m_sha1.c b/crypto/openssl/crypto/evp/m_sha1.c index 471ec30be0..9a2790fdea 100644 --- a/crypto/openssl/crypto/evp/m_sha1.c +++ b/crypto/openssl/crypto/evp/m_sha1.c @@ -68,8 +68,6 @@ #include #endif -#ifndef OPENSSL_FIPS - static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -84,7 +82,7 @@ static const EVP_MD sha1_md= NID_sha1, NID_sha1WithRSAEncryption, SHA_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, init, update, final, @@ -99,6 +97,7 @@ const EVP_MD *EVP_sha1(void) { return(&sha1_md); } +#endif #ifndef OPENSSL_NO_SHA256 static int init224(EVP_MD_CTX *ctx) @@ -120,7 +119,7 @@ static const EVP_MD sha224_md= NID_sha224, NID_sha224WithRSAEncryption, SHA224_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, init224, update256, final256, @@ -139,7 +138,7 @@ static const EVP_MD sha256_md= NID_sha256, NID_sha256WithRSAEncryption, SHA256_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, init256, update256, final256, @@ -170,7 +169,7 @@ static const EVP_MD sha384_md= NID_sha384, NID_sha384WithRSAEncryption, SHA384_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, init384, update512, final512, @@ -189,7 +188,7 @@ static const EVP_MD sha512_md= NID_sha512, NID_sha512WithRSAEncryption, SHA512_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, init512, update512, final512, @@ -203,7 +202,3 @@ static const EVP_MD sha512_md= const EVP_MD *EVP_sha512(void) { return(&sha512_md); } #endif /* ifndef OPENSSL_NO_SHA512 */ - -#endif - -#endif diff --git a/crypto/openssl/crypto/evp/m_sigver.c b/crypto/openssl/crypto/evp/m_sigver.c new file mode 100644 index 0000000000..f0b7f95059 --- /dev/null +++ b/crypto/openssl/crypto/evp/m_sigver.c @@ -0,0 +1,200 @@ +/* m_sigver.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006,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 +#include "cryptlib.h" +#include +#include +#include +#include "evp_locl.h" + +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, + int ver) + { + if (ctx->pctx == NULL) + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return 0; + + if (type == NULL) + { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } + + if (type == NULL) + { + EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + + if (ver) + { + if (ctx->pctx->pmeth->verifyctx_init) + { + if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; + } + else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) + return 0; + } + else + { + if (ctx->pctx->pmeth->signctx_init) + { + if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; + } + else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) + return 0; + } + if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) + return 0; + if (pctx) + *pctx = ctx->pctx; + if (!EVP_DigestInit_ex(ctx, type, e)) + return 0; + return 1; + } + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) + { + return do_sigver_init(ctx, pctx, type, e, pkey, 0); + } + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) + { + return do_sigver_init(ctx, pctx, type, e, pkey, 1); + } + +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) + { + int sctx, r = 0; + if (ctx->pctx->pmeth->signctx) + sctx = 1; + else + sctx = 0; + if (sigret) + { + MS_STATIC EVP_MD_CTX tmp_ctx; + unsigned char 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 (sctx) + r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, + sigret, siglen, &tmp_ctx); + else + r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (sctx || !r) + return r; + if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) + return 0; + } + else + { + if (sctx) + { + if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0) + return 0; + } + else + { + int s = EVP_MD_size(ctx->digest); + if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0) + return 0; + } + } + return 1; + } + +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen) + { + MS_STATIC EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + int r; + unsigned int mdlen; + int vctx; + + if (ctx->pctx->pmeth->verifyctx) + vctx = 1; + else + vctx = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) + return -1; + if (vctx) + { + r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, + sig, siglen, &tmp_ctx); + } + else + r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (vctx || !r) + return r; + return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); + } diff --git a/crypto/openssl/crypto/evp/m_wp.c b/crypto/openssl/crypto/evp/m_wp.c new file mode 100644 index 0000000000..1ce47c040b --- /dev/null +++ b/crypto/openssl/crypto/evp/m_wp.c @@ -0,0 +1,42 @@ +/* crypto/evp/m_wp.c */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_WHIRLPOOL + +#include +#include +#include +#include + +static int init(EVP_MD_CTX *ctx) + { return WHIRLPOOL_Init(ctx->md_data); } + +static int update(EVP_MD_CTX *ctx,const void *data,size_t count) + { return WHIRLPOOL_Update(ctx->md_data,data,count); } + +static int final(EVP_MD_CTX *ctx,unsigned char *md) + { return WHIRLPOOL_Final(md,ctx->md_data); } + +static const EVP_MD whirlpool_md= + { + NID_whirlpool, + 0, + WHIRLPOOL_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_NULL_method, + WHIRLPOOL_BBLOCK/8, + sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX), + }; + +const EVP_MD *EVP_whirlpool(void) + { + return(&whirlpool_md); + } +#endif diff --git a/crypto/openssl/crypto/evp/names.c b/crypto/openssl/crypto/evp/names.c index e2e04c3570..f2869f5c78 100644 --- a/crypto/openssl/crypto/evp/names.c +++ b/crypto/openssl/crypto/evp/names.c @@ -66,35 +66,32 @@ int EVP_add_cipher(const EVP_CIPHER *c) { int r; -#ifdef OPENSSL_FIPS - OPENSSL_init(); -#endif - r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); if (r == 0) return(0); + check_defer(c->nid); r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); return(r); } + int EVP_add_digest(const EVP_MD *md) { int r; const char *name; -#ifdef OPENSSL_FIPS - OPENSSL_init(); -#endif name=OBJ_nid2sn(md->type); r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md); if (r == 0) return(0); + check_defer(md->type); r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md); if (r == 0) return(0); - if (md->type != md->pkey_type) + if (md->pkey_type && md->type != md->pkey_type) { r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); if (r == 0) return(0); + check_defer(md->pkey_type); r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); } @@ -127,4 +124,78 @@ void EVP_cleanup(void) OBJ_NAME_cleanup(-1); EVP_PBE_cleanup(); + if (obj_cleanup_defer == 2) + { + obj_cleanup_defer = 0; + OBJ_cleanup(); + } + OBJ_sigid_free(); + } + +struct doall_cipher + { + void *arg; + void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *arg); + }; + +static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg) + { + struct doall_cipher *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg); + } + +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg) + { + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); + } + +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg) + { + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn,&dc); + } + +struct doall_md + { + void *arg; + void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *arg); + }; + +static void do_all_md_fn(const OBJ_NAME *nm, void *arg) + { + struct doall_md *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg); + } + +void EVP_MD_do_all(void (*fn)(const EVP_MD *md, + const char *from, const char *to, void *x), void *arg) + { + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); + } + +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md, + const char *from, const char *to, void *x), void *arg) + { + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); } diff --git a/crypto/openssl/crypto/evp/p5_crpt.c b/crypto/openssl/crypto/evp/p5_crpt.c index 2a265fdee2..7ecfa8dad9 100644 --- a/crypto/openssl/crypto/evp/p5_crpt.c +++ b/crypto/openssl/crypto/evp/p5_crpt.c @@ -62,42 +62,11 @@ #include #include -/* PKCS#5 v1.5 compatible PBE functions: see PKCS#5 v2.0 for more info. +/* Doesn't do anything now: Builtin PBE algorithms in static table. */ void PKCS5_PBE_add(void) { -#ifndef OPENSSL_NO_DES -# ifndef OPENSSL_NO_MD5 -EVP_PBE_alg_add(NID_pbeWithMD5AndDES_CBC, EVP_des_cbc(), EVP_md5(), - PKCS5_PBE_keyivgen); -# endif -# ifndef OPENSSL_NO_MD2 -EVP_PBE_alg_add(NID_pbeWithMD2AndDES_CBC, EVP_des_cbc(), EVP_md2(), - PKCS5_PBE_keyivgen); -# endif -# ifndef OPENSSL_NO_SHA -EVP_PBE_alg_add(NID_pbeWithSHA1AndDES_CBC, EVP_des_cbc(), EVP_sha1(), - PKCS5_PBE_keyivgen); -# endif -#endif -#ifndef OPENSSL_NO_RC2 -# ifndef OPENSSL_NO_MD5 -EVP_PBE_alg_add(NID_pbeWithMD5AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md5(), - PKCS5_PBE_keyivgen); -# endif -# ifndef OPENSSL_NO_MD2 -EVP_PBE_alg_add(NID_pbeWithMD2AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md2(), - PKCS5_PBE_keyivgen); -# endif -# ifndef OPENSSL_NO_SHA -EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(), - PKCS5_PBE_keyivgen); -# endif -#endif -#ifndef OPENSSL_NO_HMAC -EVP_PBE_alg_add(NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen); -#endif } int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, @@ -112,6 +81,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, int saltlen, iter; unsigned char *salt; const unsigned char *pbuf; + int mdsize; /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || @@ -140,9 +110,12 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, EVP_DigestUpdate(&ctx, salt, saltlen); PBEPARAM_free(pbe); EVP_DigestFinal_ex(&ctx, md_tmp, NULL); + mdsize = EVP_MD_size(md); + if (mdsize < 0) + return 0; for (i = 1; i < iter; i++) { EVP_DigestInit_ex(&ctx, md, NULL); - EVP_DigestUpdate(&ctx, md_tmp, EVP_MD_size(md)); + EVP_DigestUpdate(&ctx, md_tmp, mdsize); EVP_DigestFinal_ex (&ctx, md_tmp, NULL); } EVP_MD_CTX_cleanup(&ctx); diff --git a/crypto/openssl/crypto/evp/p5_crpt2.c b/crypto/openssl/crypto/evp/p5_crpt2.c index 6bec77baf9..334379f310 100644 --- a/crypto/openssl/crypto/evp/p5_crpt2.c +++ b/crypto/openssl/crypto/evp/p5_crpt2.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -71,28 +71,38 @@ #endif /* This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2 using the only currently defined function HMAC - * with SHA1. Verified against test vectors posted by Peter Gutmann + * derivation function PBKDF2. + * SHA1 version verified against test vectors posted by Peter Gutmann * to the PKCS-TNG mailing list. */ -int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out) -{ - unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4]; - int cplen, j, k, tkeylen; + { + unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; + int cplen, j, k, tkeylen, mdlen; unsigned long i = 1; HMAC_CTX hctx; + mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; + HMAC_CTX_init(&hctx); p = out; tkeylen = keylen; - if(!pass) passlen = 0; - else if(passlen == -1) passlen = strlen(pass); - while(tkeylen) { - if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH; - else cplen = tkeylen; + if(!pass) + passlen = 0; + else if(passlen == -1) + passlen = strlen(pass); + while(tkeylen) + { + if(tkeylen > mdlen) + cplen = mdlen; + else + cplen = tkeylen; /* We are unlikely to ever use more than 256 blocks (5120 bits!) * but just in case... */ @@ -100,20 +110,22 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, itmp[1] = (unsigned char)((i >> 16) & 0xff); itmp[2] = (unsigned char)((i >> 8) & 0xff); itmp[3] = (unsigned char)(i & 0xff); - HMAC_Init_ex(&hctx, pass, passlen, EVP_sha1(), NULL); + HMAC_Init_ex(&hctx, pass, passlen, digest, NULL); HMAC_Update(&hctx, salt, saltlen); HMAC_Update(&hctx, itmp, 4); HMAC_Final(&hctx, digtmp, NULL); memcpy(p, digtmp, cplen); - for(j = 1; j < iter; j++) { - HMAC(EVP_sha1(), pass, passlen, - digtmp, SHA_DIGEST_LENGTH, digtmp, NULL); - for(k = 0; k < cplen; k++) p[k] ^= digtmp[k]; - } + for(j = 1; j < iter; j++) + { + HMAC(digest, pass, passlen, + digtmp, mdlen, digtmp, NULL); + for(k = 0; k < cplen; k++) + p[k] ^= digtmp[k]; + } tkeylen-= cplen; i++; p+= cplen; - } + } HMAC_CTX_cleanup(&hctx); #ifdef DEBUG_PKCS5V2 fprintf(stderr, "Password:\n"); @@ -125,7 +137,15 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, h__dump (out, keylen); #endif return 1; -} + } + +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out) + { + return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), + keylen, out); + } #ifdef DO_TEST main() @@ -155,6 +175,8 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, PBE2PARAM *pbe2 = NULL; const EVP_CIPHER *cipher; PBKDF2PARAM *kdf = NULL; + const EVP_MD *prfmd; + int prf_nid, hmac_md_nid; if (param == NULL || param->type != V_ASN1_SEQUENCE || param->value.sequence == NULL) { @@ -180,8 +202,7 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, /* lets see if we recognise the encryption algorithm. */ - cipher = EVP_get_cipherbyname( - OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm))); + cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); if(!cipher) { EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, @@ -226,10 +247,23 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, goto err; } - if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) { + if (kdf->prf) + prf_nid = OBJ_obj2nid(kdf->prf->algorithm); + else + prf_nid = NID_hmacWithSHA1; + + if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) + { EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); goto err; - } + } + + prfmd = EVP_get_digestbynid(hmac_md_nid); + if (prfmd == NULL) + { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + goto err; + } if(kdf->salt->type != V_ASN1_OCTET_STRING) { EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, @@ -241,7 +275,9 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, salt = kdf->salt->value.octet_string->data; saltlen = kdf->salt->value.octet_string->length; iter = ASN1_INTEGER_get(kdf->iter); - PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key); + if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, + keylen, key)) + goto err; EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); OPENSSL_cleanse(key, keylen); PBKDF2PARAM_free(kdf); diff --git a/crypto/openssl/crypto/evp/p_dec.c b/crypto/openssl/crypto/evp/p_dec.c index f64901f653..4201dcbad9 100644 --- a/crypto/openssl/crypto/evp/p_dec.c +++ b/crypto/openssl/crypto/evp/p_dec.c @@ -66,7 +66,7 @@ #include #include -int EVP_PKEY_decrypt(unsigned char *key, const unsigned char *ek, int ekl, +int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, EVP_PKEY *priv) { int ret= -1; @@ -75,7 +75,7 @@ int EVP_PKEY_decrypt(unsigned char *key, const unsigned char *ek, int ekl, if (priv->type != EVP_PKEY_RSA) { #endif - EVPerr(EVP_F_EVP_PKEY_DECRYPT,EVP_R_PUBLIC_KEY_NOT_RSA); + EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA); #ifndef OPENSSL_NO_RSA goto err; } diff --git a/crypto/openssl/crypto/evp/p_enc.c b/crypto/openssl/crypto/evp/p_enc.c index c2dfdc52ad..b5a3a84c41 100644 --- a/crypto/openssl/crypto/evp/p_enc.c +++ b/crypto/openssl/crypto/evp/p_enc.c @@ -66,7 +66,7 @@ #include #include -int EVP_PKEY_encrypt(unsigned char *ek, const unsigned char *key, int key_len, +int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len, EVP_PKEY *pubk) { int ret=0; @@ -75,7 +75,7 @@ int EVP_PKEY_encrypt(unsigned char *ek, const unsigned char *key, int key_len, if (pubk->type != EVP_PKEY_RSA) { #endif - EVPerr(EVP_F_EVP_PKEY_ENCRYPT,EVP_R_PUBLIC_KEY_NOT_RSA); + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA); #ifndef OPENSSL_NO_RSA goto err; } diff --git a/crypto/openssl/crypto/evp/p_lib.c b/crypto/openssl/crypto/evp/p_lib.c index 22155ecf62..1916c61699 100644 --- a/crypto/openssl/crypto/evp/p_lib.c +++ b/crypto/openssl/crypto/evp/p_lib.c @@ -74,66 +74,26 @@ #include #endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "asn1_locl.h" + static void EVP_PKEY_free_it(EVP_PKEY *x); int EVP_PKEY_bits(EVP_PKEY *pkey) { - if (0) - return 0; -#ifndef OPENSSL_NO_RSA - else if (pkey->type == EVP_PKEY_RSA) - return(BN_num_bits(pkey->pkey.rsa->n)); -#endif -#ifndef OPENSSL_NO_DSA - else if (pkey->type == EVP_PKEY_DSA) - return(BN_num_bits(pkey->pkey.dsa->p)); -#endif -#ifndef OPENSSL_NO_EC - else if (pkey->type == EVP_PKEY_EC) - { - BIGNUM *order = BN_new(); - const EC_GROUP *group; - int ret; - - if (!order) - { - ERR_clear_error(); - return 0; - } - group = EC_KEY_get0_group(pkey->pkey.ec); - if (!EC_GROUP_get_order(group, order, NULL)) - { - ERR_clear_error(); - return 0; - } - - ret = BN_num_bits(order); - BN_free(order); - return ret; - } -#endif - return(0); + if (pkey && pkey->ameth && pkey->ameth->pkey_bits) + return pkey->ameth->pkey_bits(pkey); + return 0; } int EVP_PKEY_size(EVP_PKEY *pkey) { - if (pkey == NULL) - return(0); -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - return(RSA_size(pkey->pkey.rsa)); - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - return(DSA_size(pkey->pkey.dsa)); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) - return(ECDSA_size(pkey->pkey.ec)); -#endif - - return(0); + if (pkey && pkey->ameth && pkey->ameth->pkey_size) + return pkey->ameth->pkey_size(pkey); + return 0; } int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) @@ -174,88 +134,26 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS); goto err; } -#ifndef OPENSSL_NO_DSA - if (to->type == EVP_PKEY_DSA) - { - BIGNUM *a; - - if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err; - if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p); - to->pkey.dsa->p=a; - - if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err; - if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q); - to->pkey.dsa->q=a; - - if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err; - if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g); - to->pkey.dsa->g=a; - } -#endif -#ifndef OPENSSL_NO_EC - if (to->type == EVP_PKEY_EC) - { - EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); - if (group == NULL) - goto err; - if (EC_KEY_set_group(to->pkey.ec, group) == 0) - goto err; - EC_GROUP_free(group); - } -#endif - return(1); + if (from->ameth && from->ameth->param_copy) + return from->ameth->param_copy(to, from); err: - return(0); + return 0; } int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - { - DSA *dsa; - - dsa=pkey->pkey.dsa; - if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) - return(1); - } -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) - { - if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) - return(1); - } -#endif - - return(0); + if (pkey->ameth && pkey->ameth->param_missing) + return pkey->ameth->param_missing(pkey); + return 0; } int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { -#ifndef OPENSSL_NO_DSA - if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA)) - { - if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || - BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || - BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g)) - return(0); - else - return(1); - } -#endif -#ifndef OPENSSL_NO_EC - if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC) - { - const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), - *group_b = EC_KEY_get0_group(b->pkey.ec); - if (EC_GROUP_cmp(group_a, group_b, NULL)) - return 0; - else - return 1; - } -#endif - return(-1); + if (a->type != b->type) + return -1; + if (a->ameth && a->ameth->param_cmp) + return a->ameth->param_cmp(a, b); + return -2; } int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -263,51 +161,22 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) if (a->type != b->type) return -1; - if (EVP_PKEY_cmp_parameters(a, b) == 0) - return 0; - - switch (a->type) + if (a->ameth) { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 - || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0) - return 0; - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) - return 0; - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - { - int r; - const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); - const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), - *pb = EC_KEY_get0_public_key(b->pkey.ec); - r = EC_POINT_cmp(group, pa, pb, NULL); - if (r != 0) + int ret; + /* Compare parameters if the algorithm has them */ + if (a->ameth->param_cmp) { - if (r == 1) - return 0; - else - return -2; + ret = a->ameth->param_cmp(a, b); + if (ret <= 0) + return ret; } - } - break; -#endif -#ifndef OPENSSL_NO_DH - case EVP_PKEY_DH: - return -2; -#endif - default: - return -2; + + if (a->ameth->pub_cmp) + return a->ameth->pub_cmp(a, b); } - return 1; + return -2; } EVP_PKEY *EVP_PKEY_new(void) @@ -321,22 +190,87 @@ EVP_PKEY *EVP_PKEY_new(void) return(NULL); } ret->type=EVP_PKEY_NONE; + ret->save_type=EVP_PKEY_NONE; ret->references=1; + ret->ameth=NULL; + ret->engine=NULL; ret->pkey.ptr=NULL; ret->attributes=NULL; ret->save_parameters=1; return(ret); } -int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key) +/* Setup a public key ASN1 method and ENGINE from a NID or a string. + * If pkey is NULL just return 1 or 0 if the algorithm exists. + */ + +static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) { - if (pkey == NULL) return(0); - if (pkey->pkey.ptr != NULL) - EVP_PKEY_free_it(pkey); - pkey->type=EVP_PKEY_type(type); - pkey->save_type=type; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e = NULL; + if (pkey) + { + if (pkey->pkey.ptr) + EVP_PKEY_free_it(pkey); + /* If key type matches and a method exists then this + * lookup has succeeded once so just indicate success. + */ + if ((type == pkey->save_type) && pkey->ameth) + return 1; +#ifndef OPENSSL_NO_ENGINE + /* If we have an ENGINE release it */ + if (pkey->engine) + { + ENGINE_finish(pkey->engine); + pkey->engine = NULL; + } +#endif + } + if (str) + ameth = EVP_PKEY_asn1_find_str(&e, str, len); + else + ameth = EVP_PKEY_asn1_find(&e, type); +#ifndef OPENSSL_NO_ENGINE + if (!pkey && e) + ENGINE_finish(e); +#endif + if (!ameth) + { + EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + if (pkey) + { + pkey->ameth = ameth; + pkey->engine = e; + + pkey->type = pkey->ameth->pkey_id; + pkey->save_type=type; + } + return 1; + } + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) + { + return pkey_set_type(pkey, type, NULL, -1); + } + +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) + { + return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); + } + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) + { + if (!EVP_PKEY_set_type(pkey, type)) + return 0; pkey->pkey.ptr=key; - return(key != NULL); + return (key != NULL); + } + +void *EVP_PKEY_get0(EVP_PKEY *pkey) + { + return pkey->pkey.ptr; } #ifndef OPENSSL_NO_RSA @@ -425,24 +359,29 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) int EVP_PKEY_type(int type) { - switch (type) - { - case EVP_PKEY_RSA: - case EVP_PKEY_RSA2: - return(EVP_PKEY_RSA); - case EVP_PKEY_DSA: - case EVP_PKEY_DSA1: - case EVP_PKEY_DSA2: - case EVP_PKEY_DSA3: - case EVP_PKEY_DSA4: - return(EVP_PKEY_DSA); - case EVP_PKEY_DH: - return(EVP_PKEY_DH); - case EVP_PKEY_EC: - return(EVP_PKEY_EC); - default: - return(NID_undef); - } + int ret; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e; + ameth = EVP_PKEY_asn1_find(&e, type); + if (ameth) + ret = ameth->pkey_id; + else + ret = NID_undef; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return ret; + } + +int EVP_PKEY_id(const EVP_PKEY *pkey) + { + return pkey->type; + } + +int EVP_PKEY_base_id(const EVP_PKEY *pkey) + { + return EVP_PKEY_type(pkey->type); } void EVP_PKEY_free(EVP_PKEY *x) @@ -471,32 +410,57 @@ void EVP_PKEY_free(EVP_PKEY *x) static void EVP_PKEY_free_it(EVP_PKEY *x) { - switch (x->type) + if (x->ameth && x->ameth->pkey_free) + x->ameth->pkey_free(x); +#ifndef OPENSSL_NO_ENGINE + if (x->engine) { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - case EVP_PKEY_RSA2: - RSA_free(x->pkey.rsa); - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - case EVP_PKEY_DSA2: - case EVP_PKEY_DSA3: - case EVP_PKEY_DSA4: - DSA_free(x->pkey.dsa); - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - EC_KEY_free(x->pkey.ec); - break; -#endif -#ifndef OPENSSL_NO_DH - case EVP_PKEY_DH: - DH_free(x->pkey.dh); - break; -#endif + ENGINE_finish(x->engine); + x->engine = NULL; } +#endif + } + +static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, + const char *kstr) + { + BIO_indent(out, indent, 128); + BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)); + return 1; + } + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) + { + if (pkey->ameth && pkey->ameth->pub_print) + return pkey->ameth->pub_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Public Key"); + } + +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) + { + if (pkey->ameth && pkey->ameth->priv_print) + return pkey->ameth->priv_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Private Key"); + } + +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) + { + if (pkey->ameth && pkey->ameth->param_print) + return pkey->ameth->param_print(out, pkey, indent, pctx); + return unsup_alg(out, pkey, indent, "Parameters"); + } + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) + { + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return -2; + return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, + 0, pnid); } diff --git a/crypto/openssl/crypto/evp/p_open.c b/crypto/openssl/crypto/evp/p_open.c index 9935206d0f..53a59a295c 100644 --- a/crypto/openssl/crypto/evp/p_open.c +++ b/crypto/openssl/crypto/evp/p_open.c @@ -95,7 +95,7 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, goto err; } - i=EVP_PKEY_decrypt(key,ek,ekl,priv); + i=EVP_PKEY_decrypt_old(key,ek,ekl,priv); if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { /* ERROR */ diff --git a/crypto/openssl/crypto/evp/p_seal.c b/crypto/openssl/crypto/evp/p_seal.c index 8cc8fcb0bd..d8324526e7 100644 --- a/crypto/openssl/crypto/evp/p_seal.c +++ b/crypto/openssl/crypto/evp/p_seal.c @@ -87,7 +87,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek for (i=0; idigest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) + { + EVP_PKEY_CTX *pkctx = NULL; + size_t sltmp = (size_t)EVP_PKEY_size(pkey); + i = 0; + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx) + goto err; + if (EVP_PKEY_sign_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) + goto err; + *siglen = sltmp; + i = 1; + err: + EVP_PKEY_CTX_free(pkctx); + return i; + } + for (i=0; i<4; i++) { v=ctx->digest->required_pkey_type[i]; @@ -99,28 +125,13 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE); return(0); } + if (ctx->digest->sign == NULL) { EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED); return(0); } - EVP_MD_CTX_init(&tmp_ctx); - EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); - if (ctx->digest->flags & EVP_MD_FLAG_SVCTX) - { - EVP_MD_SVCTX sctmp; - sctmp.mctx = &tmp_ctx; - sctmp.key = pkey->pkey.ptr; - i = ctx->digest->sign(ctx->digest->type, - NULL, -1, sigret, siglen, &sctmp); - } - else - { - EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); - i = ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen, - pkey->pkey.ptr); - } - EVP_MD_CTX_cleanup(&tmp_ctx); - return i; + return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen, + pkey->pkey.ptr)); } diff --git a/crypto/openssl/crypto/evp/p_verify.c b/crypto/openssl/crypto/evp/p_verify.c index 2d46dffe7e..8db46412f3 100644 --- a/crypto/openssl/crypto/evp/p_verify.c +++ b/crypto/openssl/crypto/evp/p_verify.c @@ -70,6 +70,28 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, int i,ok=0,v; MS_STATIC EVP_MD_CTX tmp_ctx; + EVP_MD_CTX_init(&tmp_ctx); + EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); + EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); + EVP_MD_CTX_cleanup(&tmp_ctx); + + if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) + { + EVP_PKEY_CTX *pkctx = NULL; + i = -1; + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); + err: + EVP_PKEY_CTX_free(pkctx); + return i; + } + for (i=0; i<4; i++) { v=ctx->digest->required_pkey_type[i]; @@ -85,29 +107,13 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE); return(-1); } - if (ctx->digest->verify == NULL) + if (ctx->digest->verify == NULL) { EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED); return(0); } - EVP_MD_CTX_init(&tmp_ctx); - EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); - if (ctx->digest->flags & EVP_MD_FLAG_SVCTX) - { - EVP_MD_SVCTX sctmp; - sctmp.mctx = &tmp_ctx; - sctmp.key = pkey->pkey.ptr; - i = ctx->digest->verify(ctx->digest->type, - NULL, -1, sigbuf, siglen, &sctmp); - } - else - { - EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); - i = ctx->digest->verify(ctx->digest->type,m,m_len, - sigbuf,siglen,pkey->pkey.ptr); - } - EVP_MD_CTX_cleanup(&tmp_ctx); - return i; + return(ctx->digest->verify(ctx->digest->type,m,m_len, + sigbuf,siglen,pkey->pkey.ptr)); } diff --git a/crypto/openssl/crypto/evp/pmeth_fn.c b/crypto/openssl/crypto/evp/pmeth_fn.c new file mode 100644 index 0000000000..c4676f2f8d --- /dev/null +++ b/crypto/openssl/crypto/evp/pmeth_fn.c @@ -0,0 +1,368 @@ +/* pmeth_fn.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +#define M_check_autoarg(ctx, arg, arglen, err) \ + if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \ + { \ + size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ + if (!arg) \ + { \ + *arglen = pksize; \ + return 1; \ + } \ + else if (*arglen < pksize) \ + { \ + EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\ + return 0; \ + } \ + } + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) + { + EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_SIGN; + if (!ctx->pmeth->sign_init) + return 1; + ret = ctx->pmeth->sign_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) + { + EVPerr(EVP_F_EVP_PKEY_SIGN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) + { + EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) + return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); + } + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) + { + EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + if (!ctx->pmeth->verify_init) + return 1; + ret = ctx->pmeth->verify_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) + { + EVPerr(EVP_F_EVP_PKEY_VERIFY, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) + { + EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); + } + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) + { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + if (!ctx->pmeth->verify_recover_init) + return 1; + ret = ctx->pmeth->verify_recover_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) + { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) + { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) + return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); + } + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) + { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + if (!ctx->pmeth->encrypt_init) + return 1; + ret = ctx->pmeth->encrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) + { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) + { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); + } + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) + { + EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + if (!ctx->pmeth->decrypt_init) + return 1; + ret = ctx->pmeth->decrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) + { + EVPerr(EVP_F_EVP_PKEY_DECRYPT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) + { + EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); + } + + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + if (!ctx->pmeth->derive_init) + return 1; + ret = ctx->pmeth->derive_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) + { + int ret; + if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (!ctx->pkey) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are + * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + * (different key types) is impossible here because it is checked earlier. + * -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)) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) + { + ctx->peerkey = NULL; + return ret; + } + + CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY); + return 1; + } + + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) + return ctx->pmeth->derive(ctx, key, pkeylen); + } + diff --git a/crypto/openssl/crypto/evp/pmeth_gn.c b/crypto/openssl/crypto/evp/pmeth_gn.c new file mode 100644 index 0000000000..5d74161a09 --- /dev/null +++ b/crypto/openssl/crypto/evp/pmeth_gn.c @@ -0,0 +1,220 @@ +/* pmeth_gn.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include +#include "cryptlib.h" +#include +#include +#include +#include "evp_locl.h" + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) + { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_PARAMGEN; + if (!ctx->pmeth->paramgen_init) + return 1; + ret = ctx->pmeth->paramgen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) + { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_PARAMGEN) + { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (!ppkey) + return -1; + + if (!*ppkey) + *ppkey = EVP_PKEY_new(); + + ret = ctx->pmeth->paramgen(ctx, *ppkey); + if (ret <= 0) + { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; + } + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) + { + EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + if (!ctx->pmeth->keygen_init) + return 1; + ret = ctx->pmeth->keygen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; + } + +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) + { + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) + { + EVPerr(EVP_F_EVP_PKEY_KEYGEN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) + { + EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (!ppkey) + return -1; + + if (!*ppkey) + *ppkey = EVP_PKEY_new(); + + ret = ctx->pmeth->keygen(ctx, *ppkey); + if (ret <= 0) + { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; + } + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) + { + ctx->pkey_gencb = cb; + } + +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) + { + return ctx->pkey_gencb; + } + +/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB + * style callbacks. + */ + +static int trans_cb(int a, int b, BN_GENCB *gcb) + { + EVP_PKEY_CTX *ctx = gcb->arg; + ctx->keygen_info[0] = a; + ctx->keygen_info[1] = b; + return ctx->pkey_gencb(ctx); + } + +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) + { + BN_GENCB_set(cb, trans_cb, ctx) + } + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) + { + if (idx == -1) + return ctx->keygen_info_count; + if (idx < 0 || idx > ctx->keygen_info_count) + return 0; + return ctx->keygen_info[idx]; + } + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + unsigned char *key, int keylen) + { + EVP_PKEY_CTX *mac_ctx = NULL; + EVP_PKEY *mac_key = NULL; + mac_ctx = EVP_PKEY_CTX_new_id(type, e); + if (!mac_ctx) + return NULL; + if (EVP_PKEY_keygen_init(mac_ctx) <= 0) + goto merr; + if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0) + goto merr; + if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) + goto merr; + merr: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + return mac_key; + } diff --git a/crypto/openssl/crypto/evp/pmeth_lib.c b/crypto/openssl/crypto/evp/pmeth_lib.c new file mode 100644 index 0000000000..b2d8de3a8d --- /dev/null +++ b/crypto/openssl/crypto/evp/pmeth_lib.c @@ -0,0 +1,538 @@ +/* pmeth_lib.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include "asn1_locl.h" +#include "evp_locl.h" + +typedef int sk_cmp_fn_type(const char * const *a, const char * const *b); + +DECLARE_STACK_OF(EVP_PKEY_METHOD) +STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; + +extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth; + +static const EVP_PKEY_METHOD *standard_methods[] = + { +#ifndef OPENSSL_NO_RSA + &rsa_pkey_meth, +#endif +#ifndef OPENSSL_NO_DH + &dh_pkey_meth, +#endif +#ifndef OPENSSL_NO_DSA + &dsa_pkey_meth, +#endif +#ifndef OPENSSL_NO_EC + &ec_pkey_meth, +#endif + &hmac_pkey_meth, + }; + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, + pmeth); + +static int pmeth_cmp(const EVP_PKEY_METHOD * const *a, + const EVP_PKEY_METHOD * const *b) + { + return ((*a)->pkey_id - (*b)->pkey_id); + } + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, + pmeth); + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) + { + EVP_PKEY_METHOD tmp; + const EVP_PKEY_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; + if (app_pkey_methods) + { + int idx; + idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); + } + ret = OBJ_bsearch_pmeth(&t, standard_methods, + sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *)); + if (!ret || !*ret) + return NULL; + return *ret; + } + +static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) + { + EVP_PKEY_CTX *ret; + const EVP_PKEY_METHOD *pmeth; + if (id == -1) + { + if (!pkey || !pkey->ameth) + return NULL; + id = pkey->ameth->pkey_id; + } +#ifndef OPENSSL_NO_ENGINE + /* Try to find an ENGINE which implements this method */ + if (e) + { + if (!ENGINE_init(e)) + { + EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB); + return NULL; + } + } + else + e = ENGINE_get_pkey_meth_engine(id); + + /* If an ENGINE handled this method look it up. Othewise + * use internal tables. + */ + + if (e) + pmeth = ENGINE_get_pkey_meth(e, id); + else +#endif + pmeth = EVP_PKEY_meth_find(id); + + if (pmeth == NULL) + { + EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) + { +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->engine = e; + ret->pmeth = pmeth; + ret->operation = EVP_PKEY_OP_UNDEFINED; + ret->pkey = pkey; + ret->peerkey = NULL; + ret->pkey_gencb = 0; + if (pkey) + CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); + ret->data = NULL; + + if (pmeth->init) + { + if (pmeth->init(ret) <= 0) + { + EVP_PKEY_CTX_free(ret); + return NULL; + } + } + + return ret; + } + +EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags) + { + EVP_PKEY_METHOD *pmeth; + pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD)); + if (!pmeth) + return NULL; + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + + pmeth->init = 0; + pmeth->copy = 0; + pmeth->cleanup = 0; + pmeth->paramgen_init = 0; + pmeth->paramgen = 0; + pmeth->keygen_init = 0; + pmeth->keygen = 0; + pmeth->sign_init = 0; + pmeth->sign = 0; + pmeth->verify_init = 0; + pmeth->verify = 0; + pmeth->verify_recover_init = 0; + pmeth->verify_recover = 0; + pmeth->signctx_init = 0; + pmeth->signctx = 0; + pmeth->verifyctx_init = 0; + pmeth->verifyctx = 0; + pmeth->encrypt_init = 0; + pmeth->encrypt = 0; + pmeth->decrypt_init = 0; + pmeth->decrypt = 0; + pmeth->derive_init = 0; + pmeth->derive = 0; + pmeth->ctrl = 0; + pmeth->ctrl_str = 0; + + return pmeth; + } + +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) + { + if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) + OPENSSL_free(pmeth); + } + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) + { + return int_ctx_new(pkey, e, -1); + } + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) + { + return int_ctx_new(NULL, e, id); + } + +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) + { + EVP_PKEY_CTX *rctx; + if (!pctx->pmeth || !pctx->pmeth->copy) + return NULL; +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a pkey context using an ENGINE */ + if (pctx->engine && !ENGINE_init(pctx->engine)) + { + EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB); + return 0; + } +#endif + rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!rctx) + return NULL; + + rctx->pmeth = pctx->pmeth; +#ifndef OPENSSL_NO_ENGINE + rctx->engine = pctx->engine; +#endif + + if (pctx->pkey) + CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY); + + rctx->pkey = pctx->pkey; + + if (pctx->peerkey) + CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY); + + rctx->peerkey = pctx->peerkey; + + rctx->data = NULL; + rctx->app_data = NULL; + rctx->operation = pctx->operation; + + if (pctx->pmeth->copy(rctx, pctx) > 0) + return rctx; + + EVP_PKEY_CTX_free(rctx); + return NULL; + + } + +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) + { + if (app_pkey_methods == NULL) + { + app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); + if (!app_pkey_methods) + return 0; + } + if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) + return 0; + sk_EVP_PKEY_METHOD_sort(app_pkey_methods); + return 1; + } + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) + { + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); + if (ctx->pkey) + EVP_PKEY_free(ctx->pkey); + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); +#ifndef OPENSSL_NO_ENGINE + if(ctx->engine) + /* The EVP_PKEY_CTX we used belongs to an ENGINE, release the + * functional reference we held for this reason. */ + ENGINE_finish(ctx->engine); +#endif + OPENSSL_free(ctx); + } + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) + { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) + return -1; + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) + { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); + return -1; + } + + if ((optype != -1) && !(ctx->operation & optype)) + { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + + if (ret == -2) + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; + + } + +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, + const char *name, const char *value) + { + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) + { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, + EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!strcmp(name, "digest")) + { + const EVP_MD *md; + if (!value || !(md = EVP_get_digestbyname(value))) + { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, + EVP_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_signature_md(ctx, md); + } + return ctx->pmeth->ctrl_str(ctx, name, value); + } + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) + { + return ctx->operation; + } + +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) + { + ctx->keygen_info = dat; + ctx->keygen_info_count = datlen; + } + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) + { + ctx->data = data; + } + +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) + { + return ctx->data; + } + +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) + { + return ctx->pkey; + } + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) + { + return ctx->peerkey; + } + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) + { + ctx->app_data = data; + } + +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) + { + return ctx->app_data; + } + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init)(EVP_PKEY_CTX *ctx)) + { + pmeth->init = init; + } + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)) + { + pmeth->copy = copy; + } + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup)(EVP_PKEY_CTX *ctx)) + { + pmeth->cleanup = cleanup; + } + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init)(EVP_PKEY_CTX *ctx), + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) + { + pmeth->paramgen_init = paramgen_init; + pmeth->paramgen = paramgen; + } + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init)(EVP_PKEY_CTX *ctx), + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) + { + pmeth->keygen_init = keygen_init; + pmeth->keygen = keygen; + } + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + 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)) + { + pmeth->sign_init = sign_init; + pmeth->sign = sign; + } + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + 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)) + { + pmeth->verify_init = verify_init; + pmeth->verify = verify; + } + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init)(EVP_PKEY_CTX *ctx), + int (*verify_recover)(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)) + { + pmeth->verify_recover_init = verify_recover_init; + pmeth->verify_recover = verify_recover; + } + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + 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)) + { + pmeth->signctx_init = signctx_init; + pmeth->signctx = signctx; + } + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + 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)) + { + pmeth->verifyctx_init = verifyctx_init; + pmeth->verifyctx = verifyctx; + } + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init)(EVP_PKEY_CTX *ctx), + int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)) + { + pmeth->encrypt_init = encrypt_init; + pmeth->encrypt = encryptfn; + } + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + 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)) + { + pmeth->decrypt_init = decrypt_init; + pmeth->decrypt = decrypt; + } + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init)(EVP_PKEY_CTX *ctx), + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)) + { + pmeth->derive_init = derive_init; + pmeth->derive = derive; + } + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + 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)) + { + pmeth->ctrl = ctrl; + pmeth->ctrl_str = ctrl_str; + } diff --git a/crypto/openssl/crypto/ex_data.c b/crypto/openssl/crypto/ex_data.c index 3b11e7a556..e2bc8298d0 100644 --- a/crypto/openssl/crypto/ex_data.c +++ b/crypto/openssl/crypto/ex_data.c @@ -245,18 +245,21 @@ typedef struct st_ex_class_item { static int ex_class = CRYPTO_EX_INDEX_USER; /* The global hash table of EX_CLASS_ITEM items */ -static LHASH *ex_data = NULL; +DECLARE_LHASH_OF(EX_CLASS_ITEM); +static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL; /* The callbacks required in the "ex_data" hash table */ -static unsigned long ex_hash_cb(const void *a_void) +static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a) { - return ((const EX_CLASS_ITEM *)a_void)->class_index; + return a->class_index; } -static int ex_cmp_cb(const void *a_void, const void *b_void) +static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM) + +static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) { - return (((const EX_CLASS_ITEM *)a_void)->class_index - - ((const EX_CLASS_ITEM *)b_void)->class_index); + return a->class_index - b->class_index; } +static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM) /* Internal functions used by the "impl_default" implementation to access the * state */ @@ -265,7 +268,8 @@ static int ex_data_check(void) { int toret = 1; CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - if(!ex_data && ((ex_data = lh_new(ex_hash_cb, ex_cmp_cb)) == NULL)) + if(!ex_data + && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL) toret = 0; CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); return toret; @@ -298,7 +302,7 @@ static EX_CLASS_ITEM *def_get_class(int class_index) EX_DATA_CHECK(return NULL;) d.class_index = class_index; CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - p = lh_retrieve(ex_data, &d); + p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); if(!p) { gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM)); @@ -313,7 +317,7 @@ static EX_CLASS_ITEM *def_get_class(int class_index) { /* Because we're inside the ex_data lock, the * return value from the insert will be NULL */ - lh_insert(ex_data, gen); + (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); p = gen; } } @@ -375,8 +379,8 @@ static int int_new_class(void) static void int_cleanup(void) { EX_DATA_CHECK(return;) - lh_doall(ex_data, def_cleanup_cb); - lh_free(ex_data); + lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb); + lh_EX_CLASS_ITEM_free(ex_data); ex_data = NULL; impl = NULL; } @@ -452,7 +456,7 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, return 0; CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); - j = sk_num(from->sk); + j = sk_void_num(from->sk); if(j < mx) mx = j; if(mx > 0) @@ -523,7 +527,7 @@ skip: OPENSSL_free(storage); if(ad->sk) { - sk_free(ad->sk); + sk_void_free(ad->sk); ad->sk=NULL; } } @@ -596,24 +600,24 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) if (ad->sk == NULL) { - if ((ad->sk=sk_new_null()) == NULL) + if ((ad->sk=sk_void_new_null()) == NULL) { CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); return(0); } } - i=sk_num(ad->sk); + i=sk_void_num(ad->sk); while (i <= idx) { - if (!sk_push(ad->sk,NULL)) + if (!sk_void_push(ad->sk,NULL)) { CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); return(0); } i++; } - sk_set(ad->sk,idx,val); + sk_void_set(ad->sk,idx,val); return(1); } @@ -623,10 +627,10 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) { if (ad->sk == NULL) return(0); - else if (idx >= sk_num(ad->sk)) + else if (idx >= sk_void_num(ad->sk)) return(0); else - return(sk_value(ad->sk,idx)); + return(sk_void_value(ad->sk,idx)); } IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) diff --git a/crypto/openssl/crypto/fips_err.c b/crypto/openssl/crypto/fips_err.c deleted file mode 100644 index 09f11748f6..0000000000 --- a/crypto/openssl/crypto/fips_err.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -#ifdef OPENSSL_FIPS -# include "fips_err.h" -#else -static void *dummy=&dummy; -#endif diff --git a/crypto/openssl/crypto/fips_err.h b/crypto/openssl/crypto/fips_err.h deleted file mode 100644 index b328616858..0000000000 --- a/crypto/openssl/crypto/fips_err.h +++ /dev/null @@ -1,137 +0,0 @@ -/* crypto/fips_err.h */ -/* ==================================================================== - * Copyright (c) 1999-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). - * - */ - -/* NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include -#include - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -#define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0) -#define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason) - -static ERR_STRING_DATA FIPS_str_functs[]= - { -{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, -{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, -{ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"}, -{ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"}, -{ERR_FUNC(FIPS_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, -{ERR_FUNC(FIPS_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, -{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "FIPS_CHECK_DSA"}, -{ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT), "FIPS_CHECK_INCORE_FINGERPRINT"}, -{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "FIPS_CHECK_RSA"}, -{ERR_FUNC(FIPS_F_FIPS_DSA_CHECK), "FIPS_DSA_CHECK"}, -{ERR_FUNC(FIPS_F_FIPS_MODE_SET), "FIPS_mode_set"}, -{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"}, -{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"}, -{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"}, -{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"}, -{ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"}, -{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RNG), "FIPS_selftest_rng"}, -{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"}, -{ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"}, -{ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, -{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, -{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, -{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, -{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, -{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX), "RSA_X931_generate_key_ex"}, -{ERR_FUNC(FIPS_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, -{0,NULL} - }; - -static ERR_STRING_DATA FIPS_str_reasons[]= - { -{ERR_REASON(FIPS_R_CANNOT_READ_EXE) ,"cannot read exe"}, -{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"}, -{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"}, -{ERR_REASON(FIPS_R_EXE_DIGEST_DOES_NOT_MATCH),"exe digest does not match"}, -{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"}, -{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"}, -{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"}, -{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"}, -{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"}, -{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH) ,"invalid key length"}, -{ERR_REASON(FIPS_R_KEY_TOO_SHORT) ,"key too short"}, -{ERR_REASON(FIPS_R_NON_FIPS_METHOD) ,"non fips method"}, -{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"}, -{ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR) ,"rsa decrypt error"}, -{ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR) ,"rsa encrypt error"}, -{ERR_REASON(FIPS_R_SELFTEST_FAILED) ,"selftest failed"}, -{ERR_REASON(FIPS_R_TEST_FAILURE) ,"test failure"}, -{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"}, -{0,NULL} - }; - -#endif - -void ERR_load_FIPS_strings(void) - { -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL) - { - ERR_load_strings(0,FIPS_str_functs); - ERR_load_strings(0,FIPS_str_reasons); - } -#endif - } diff --git a/crypto/openssl/crypto/evp/evp_cnf.c b/crypto/openssl/crypto/hmac/hm_ameth.c similarity index 59% copy from crypto/openssl/crypto/evp/evp_cnf.c copy to crypto/openssl/crypto/hmac/hm_ameth.c index 2e4db30235..6d8a89149e 100644 --- a/crypto/openssl/crypto/evp/evp_cnf.c +++ b/crypto/openssl/crypto/hmac/hm_ameth.c @@ -1,5 +1,4 @@ -/* evp_cnf.c */ -/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2007. */ /* ==================================================================== @@ -57,69 +56,112 @@ */ #include -#include -#include #include "cryptlib.h" -#include -#include -#include -#include -#ifdef OPENSSL_FIPS -#include -#endif +#include +#include "asn1_locl.h" + +#define HMAC_TEST_PRIVATE_KEY_FORMAT +/* HMAC "ASN1" method. This is just here to indicate the + * maximum HMAC output length and to free up an HMAC + * key. + */ -/* Algorithm configuration module. */ +static int hmac_size(const EVP_PKEY *pkey) + { + return EVP_MAX_MD_SIZE; + } -static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) +static void hmac_key_free(EVP_PKEY *pkey) { - int i; - const char *oid_section; - STACK_OF(CONF_VALUE) *sktmp; - CONF_VALUE *oval; - oid_section = CONF_imodule_get_value(md); - if(!(sktmp = NCONF_get_section(cnf, oid_section))) + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (os) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); - return 0; + if (os->data) + OPENSSL_cleanse(os->data, os->length); + ASN1_OCTET_STRING_free(os); } - for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) + } + + +static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) + { + switch (op) { - oval = sk_CONF_VALUE_value(sktmp, i); - if (!strcmp(oval->name, "fips_mode")) - { - int m; - if (!X509V3_get_value_bool(oval, &m)) - { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); - return 0; - } - if (m > 0) - { -#ifdef OPENSSL_FIPS - if (!FIPS_mode() && !FIPS_mode_set(1)) - { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE); - return 0; - } -#else - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); - return 0; -#endif - } - } - else - { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); - ERR_add_error_data(4, "name=", oval->name, - ", value=", oval->value); - } - + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 1; + + default: + return -2; } + } + +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT +/* A bogus private key format for test purposes. This is simply the + * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the + * genpkey utility can be used to "generate" HMAC keys. + */ + +static int old_hmac_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + ASN1_OCTET_STRING *os; + os = ASN1_OCTET_STRING_new(); + if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen)) + return 0; + EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os); return 1; } -void EVP_add_alg_module(void) +static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder) { - CONF_module_add("alg_section", alg_module_init, 0); + int inc; + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (pder) + { + if (!*pder) + { + *pder = OPENSSL_malloc(os->length); + inc = 0; + } + else inc = 1; + + memcpy(*pder, os->data, os->length); + + if (inc) + *pder += os->length; + } + + return os->length; } + +#endif + +const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = + { + EVP_PKEY_HMAC, + EVP_PKEY_HMAC, + 0, + + "HMAC", + "OpenSSL HMAC method", + + 0,0,0,0, + + 0,0,0, + + hmac_size, + 0, + 0,0,0,0,0,0, + + hmac_key_free, + hmac_pkey_ctrl, +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT + old_hmac_decode, + old_hmac_encode +#else + 0,0 +#endif + }; + diff --git a/crypto/openssl/crypto/hmac/hm_pmeth.c b/crypto/openssl/crypto/hmac/hm_pmeth.c new file mode 100644 index 0000000000..985921ca1a --- /dev/null +++ b/crypto/openssl/crypto/hmac/hm_pmeth.c @@ -0,0 +1,265 @@ +/* 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include "evp_locl.h" + +/* HMAC pkey context structure */ + +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; + hctx->md = NULL; + hctx->ktmp.data = NULL; + hctx->ktmp.length = 0; + hctx->ktmp.flags = 0; + hctx->ktmp.type = V_ASN1_OCTET_STRING; + HMAC_CTX_init(&hctx->ctx); + + ctx->data = hctx; + ctx->keygen_info_count = 0; + + 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); + HMAC_CTX_copy(&dctx->ctx, &sctx->ctx); + 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; + 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 int 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); + return 1; + } + +static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) + { + 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; + int l = EVP_MD_CTX_size(mctx); + + if (l < 0) + return 0; + *siglen = l; + if (!sig) + return 1; + + HMAC_Final(&hctx->ctx, sig, &hlen); + *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; + HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, + ctx->engine); + break; + + default: + return -2; + + } + return 1; + } + +static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!value) + { + return 0; + } + if (!strcmp(type, "key")) + { + void *p = (void *)value; + return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + -1, p); + } + if (!strcmp(type, "hexkey")) + { + unsigned char *key; + int r; + long keylen; + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + OPENSSL_free(key); + return r; + } + return -2; + } + +const EVP_PKEY_METHOD hmac_pkey_meth = + { + EVP_PKEY_HMAC, + 0, + pkey_hmac_init, + pkey_hmac_copy, + pkey_hmac_cleanup, + + 0, 0, + + 0, + pkey_hmac_keygen, + + 0, 0, + + 0, 0, + + 0,0, + + hmac_signctx_init, + hmac_signctx, + + 0,0, + + 0,0, + + 0,0, + + 0,0, + + pkey_hmac_ctrl, + pkey_hmac_ctrl_str + + }; diff --git a/crypto/openssl/crypto/hmac/hmac.c b/crypto/openssl/crypto/hmac/hmac.c index cbc1c76a57..45015fe754 100644 --- a/crypto/openssl/crypto/hmac/hmac.c +++ b/crypto/openssl/crypto/hmac/hmac.c @@ -61,9 +61,7 @@ #include "cryptlib.h" #include -#ifndef OPENSSL_FIPS - -void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { int i,j,reset=0; @@ -84,10 +82,13 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, OPENSSL_assert(j <= (int)sizeof(ctx->key)); if (j < len) { - EVP_DigestInit_ex(&ctx->md_ctx,md, impl); - EVP_DigestUpdate(&ctx->md_ctx,key,len); - EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key, - &ctx->key_length); + if (!EVP_DigestInit_ex(&ctx->md_ctx,md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx,key,len)) + goto err; + if (!EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key, + &ctx->key_length)) + goto err; } else { @@ -104,31 +105,38 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, { for (i=0; ikey[i]; - EVP_DigestInit_ex(&ctx->i_ctx,md, impl); - EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)); + if (!EVP_DigestInit_ex(&ctx->i_ctx,md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md))) + goto err; for (i=0; ikey[i]; - EVP_DigestInit_ex(&ctx->o_ctx,md, impl); - EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)); + if (!EVP_DigestInit_ex(&ctx->o_ctx,md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md))) + goto err; } - EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx); + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx)) + goto err; + return 1; + err: + return 0; } -void HMAC_Init(HMAC_CTX *ctx, const void *key, int len, - const EVP_MD *md) +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) { if(key && md) HMAC_CTX_init(ctx); - HMAC_Init_ex(ctx,key,len,md, NULL); + return HMAC_Init_ex(ctx,key,len,md, NULL); } -void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) { - EVP_DigestUpdate(&ctx->md_ctx,data,len); + return EVP_DigestUpdate(&ctx->md_ctx,data,len); } -void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { int j; unsigned int i; @@ -136,10 +144,17 @@ void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) j=EVP_MD_block_size(ctx->md); - EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i); - EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx); - EVP_DigestUpdate(&ctx->md_ctx,buf,i); - EVP_DigestFinal_ex(&ctx->md_ctx,md,len); + if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx,buf,i)) + goto err; + if (!EVP_DigestFinal_ex(&ctx->md_ctx,md,len)) + goto err; + return 1; + err: + return 0; } void HMAC_CTX_init(HMAC_CTX *ctx) @@ -149,6 +164,22 @@ void HMAC_CTX_init(HMAC_CTX *ctx) EVP_MD_CTX_init(&ctx->md_ctx); } +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) + { + if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx)) + goto err; + memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK); + dctx->key_length = sctx->key_length; + dctx->md = sctx->md; + return 1; + err: + return 0; + } + void HMAC_CTX_cleanup(HMAC_CTX *ctx) { EVP_MD_CTX_cleanup(&ctx->i_ctx); @@ -166,11 +197,16 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, if (md == NULL) md=m; HMAC_CTX_init(&c); - HMAC_Init(&c,key,key_len,evp_md); - HMAC_Update(&c,d,n); - HMAC_Final(&c,md,md_len); + if (!HMAC_Init(&c,key,key_len,evp_md)) + goto err; + if (!HMAC_Update(&c,d,n)) + goto err; + if (!HMAC_Final(&c,md,md_len)) + goto err; HMAC_CTX_cleanup(&c); - return(md); + return md; + err: + return NULL; } void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) @@ -179,5 +215,3 @@ void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); } - -#endif diff --git a/crypto/openssl/crypto/hmac/hmac.h b/crypto/openssl/crypto/hmac/hmac.h index fc38ffb52b..1be0022190 100644 --- a/crypto/openssl/crypto/hmac/hmac.h +++ b/crypto/openssl/crypto/hmac/hmac.h @@ -90,15 +90,16 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx); #define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */ -void HMAC_Init(HMAC_CTX *ctx, const void *key, int len, +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md); /* deprecated */ -void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); -void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); -void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, size_t n, unsigned char *md, unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); diff --git a/crypto/openssl/crypto/idea/i_skey.c b/crypto/openssl/crypto/idea/i_skey.c index fa75b14466..1c95bc9c7b 100644 --- a/crypto/openssl/crypto/idea/i_skey.c +++ b/crypto/openssl/crypto/idea/i_skey.c @@ -57,27 +57,10 @@ */ #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - #include "idea_lcl.h" static IDEA_INT inverse(unsigned int xin); - -#ifdef OPENSSL_FIPS -void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) - { - if (FIPS_mode()) - FIPS_BAD_ABORT(IDEA) - private_idea_set_encrypt_key(key, ks); - } -void private_idea_set_encrypt_key(const unsigned char *key, - IDEA_KEY_SCHEDULE *ks) -#else void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) -#endif { int i; register IDEA_INT *kt,*kf,r0,r1,r2; @@ -111,11 +94,10 @@ void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) } } -void idea_set_decrypt_key(const IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) { int r; - register IDEA_INT *tp,t; - const IDEA_INT *fp; + register IDEA_INT *fp,*tp,t; tp= &(dk->data[0][0]); fp= &(ek->data[8][0]); diff --git a/crypto/openssl/crypto/idea/idea.h b/crypto/openssl/crypto/idea/idea.h index a137d4cbce..5782e54b0f 100644 --- a/crypto/openssl/crypto/idea/idea.h +++ b/crypto/openssl/crypto/idea/idea.h @@ -83,11 +83,8 @@ typedef struct idea_key_st const char *idea_options(void); void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, IDEA_KEY_SCHEDULE *ks); -#ifdef OPENSSL_FIPS -void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); -#endif void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); -void idea_set_decrypt_key(const IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc); void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, diff --git a/crypto/openssl/crypto/krb5/krb5_asn.c b/crypto/openssl/crypto/krb5/krb5_asn.c deleted file mode 100644 index 1fb741d2a0..0000000000 --- a/crypto/openssl/crypto/krb5/krb5_asn.c +++ /dev/null @@ -1,167 +0,0 @@ -/* krb5_asn.c */ -/* Written by Vern Staats for the OpenSSL project, -** using ocsp/{*.h,*asn*.c} as a starting point -*/ -/* ==================================================================== - * Copyright (c) 2000 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 -#include -#include - - -ASN1_SEQUENCE(KRB5_ENCDATA) = { - ASN1_EXP(KRB5_ENCDATA, etype, ASN1_INTEGER, 0), - ASN1_EXP_OPT(KRB5_ENCDATA, kvno, ASN1_INTEGER, 1), - ASN1_EXP(KRB5_ENCDATA, cipher, ASN1_OCTET_STRING,2) -} ASN1_SEQUENCE_END(KRB5_ENCDATA) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA) - - -ASN1_SEQUENCE(KRB5_PRINCNAME) = { - ASN1_EXP(KRB5_PRINCNAME, nametype, ASN1_INTEGER, 0), - ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1) -} ASN1_SEQUENCE_END(KRB5_PRINCNAME) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME) - - -/* [APPLICATION 1] = 0x61 */ -ASN1_SEQUENCE(KRB5_TKTBODY) = { - ASN1_EXP(KRB5_TKTBODY, tktvno, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_TKTBODY, realm, ASN1_GENERALSTRING, 1), - ASN1_EXP(KRB5_TKTBODY, sname, KRB5_PRINCNAME, 2), - ASN1_EXP(KRB5_TKTBODY, encdata, KRB5_ENCDATA, 3) -} ASN1_SEQUENCE_END(KRB5_TKTBODY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY) - - -ASN1_ITEM_TEMPLATE(KRB5_TICKET) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1, - KRB5_TICKET, KRB5_TKTBODY) -ASN1_ITEM_TEMPLATE_END(KRB5_TICKET) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET) - - -/* [APPLICATION 14] = 0x6e */ -ASN1_SEQUENCE(KRB5_APREQBODY) = { - ASN1_EXP(KRB5_APREQBODY, pvno, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_APREQBODY, msgtype, ASN1_INTEGER, 1), - ASN1_EXP(KRB5_APREQBODY, apoptions, ASN1_BIT_STRING, 2), - ASN1_EXP(KRB5_APREQBODY, ticket, KRB5_TICKET, 3), - ASN1_EXP(KRB5_APREQBODY, authenticator, KRB5_ENCDATA, 4), -} ASN1_SEQUENCE_END(KRB5_APREQBODY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY) - -ASN1_ITEM_TEMPLATE(KRB5_APREQ) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14, - KRB5_APREQ, KRB5_APREQBODY) -ASN1_ITEM_TEMPLATE_END(KRB5_APREQ) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ) - - -/* Authenticator stuff */ - -ASN1_SEQUENCE(KRB5_CHECKSUM) = { - ASN1_EXP(KRB5_CHECKSUM, ctype, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_CHECKSUM, checksum, ASN1_OCTET_STRING,1) -} ASN1_SEQUENCE_END(KRB5_CHECKSUM) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM) - - -ASN1_SEQUENCE(KRB5_ENCKEY) = { - ASN1_EXP(KRB5_ENCKEY, ktype, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_ENCKEY, keyvalue, ASN1_OCTET_STRING,1) -} ASN1_SEQUENCE_END(KRB5_ENCKEY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY) - - -/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */ -ASN1_SEQUENCE(KRB5_AUTHDATA) = { - ASN1_EXP(KRB5_AUTHDATA, adtype, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_AUTHDATA, addata, ASN1_OCTET_STRING,1) -} ASN1_SEQUENCE_END(KRB5_AUTHDATA) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA) - - -/* [APPLICATION 2] = 0x62 */ -ASN1_SEQUENCE(KRB5_AUTHENTBODY) = { - ASN1_EXP(KRB5_AUTHENTBODY, avno, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_AUTHENTBODY, crealm, ASN1_GENERALSTRING, 1), - ASN1_EXP(KRB5_AUTHENTBODY, cname, KRB5_PRINCNAME, 2), - ASN1_EXP_OPT(KRB5_AUTHENTBODY, cksum, KRB5_CHECKSUM, 3), - ASN1_EXP(KRB5_AUTHENTBODY, cusec, ASN1_INTEGER, 4), - ASN1_EXP(KRB5_AUTHENTBODY, ctime, ASN1_GENERALIZEDTIME, 5), - ASN1_EXP_OPT(KRB5_AUTHENTBODY, subkey, KRB5_ENCKEY, 6), - ASN1_EXP_OPT(KRB5_AUTHENTBODY, seqnum, ASN1_INTEGER, 7), - ASN1_EXP_SEQUENCE_OF_OPT - (KRB5_AUTHENTBODY, authorization, KRB5_AUTHDATA, 8), -} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) - -ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2, - KRB5_AUTHENT, KRB5_AUTHENTBODY) -ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT) - diff --git a/crypto/openssl/crypto/krb5/krb5_asn.h b/crypto/openssl/crypto/krb5/krb5_asn.h deleted file mode 100644 index 41725d0dc4..0000000000 --- a/crypto/openssl/crypto/krb5/krb5_asn.h +++ /dev/null @@ -1,256 +0,0 @@ -/* krb5_asn.h */ -/* Written by Vern Staats for the OpenSSL project, -** using ocsp/{*.h,*asn*.c} as a starting point -*/ - -/* ==================================================================== - * Copyright (c) 1998-2000 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). - * - */ - -#ifndef HEADER_KRB5_ASN_H -#define HEADER_KRB5_ASN_H - -/* -#include -*/ -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* ASN.1 from Kerberos RFC 1510 -*/ - -/* EncryptedData ::= SEQUENCE { -** etype[0] INTEGER, -- EncryptionType -** kvno[1] INTEGER OPTIONAL, -** cipher[2] OCTET STRING -- ciphertext -** } -*/ -typedef struct krb5_encdata_st - { - ASN1_INTEGER *etype; - ASN1_INTEGER *kvno; - ASN1_OCTET_STRING *cipher; - } KRB5_ENCDATA; - -DECLARE_STACK_OF(KRB5_ENCDATA) - -/* PrincipalName ::= SEQUENCE { -** name-type[0] INTEGER, -** name-string[1] SEQUENCE OF GeneralString -** } -*/ -typedef struct krb5_princname_st - { - ASN1_INTEGER *nametype; - STACK_OF(ASN1_GENERALSTRING) *namestring; - } KRB5_PRINCNAME; - -DECLARE_STACK_OF(KRB5_PRINCNAME) - - -/* Ticket ::= [APPLICATION 1] SEQUENCE { -** tkt-vno[0] INTEGER, -** realm[1] Realm, -** sname[2] PrincipalName, -** enc-part[3] EncryptedData -** } -*/ -typedef struct krb5_tktbody_st - { - ASN1_INTEGER *tktvno; - ASN1_GENERALSTRING *realm; - KRB5_PRINCNAME *sname; - KRB5_ENCDATA *encdata; - } KRB5_TKTBODY; - -typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; -DECLARE_STACK_OF(KRB5_TKTBODY) - - -/* AP-REQ ::= [APPLICATION 14] SEQUENCE { -** pvno[0] INTEGER, -** msg-type[1] INTEGER, -** ap-options[2] APOptions, -** ticket[3] Ticket, -** authenticator[4] EncryptedData -** } -** -** APOptions ::= BIT STRING { -** reserved(0), use-session-key(1), mutual-required(2) } -*/ -typedef struct krb5_ap_req_st - { - ASN1_INTEGER *pvno; - ASN1_INTEGER *msgtype; - ASN1_BIT_STRING *apoptions; - KRB5_TICKET *ticket; - KRB5_ENCDATA *authenticator; - } KRB5_APREQBODY; - -typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; -DECLARE_STACK_OF(KRB5_APREQBODY) - - -/* Authenticator Stuff */ - - -/* Checksum ::= SEQUENCE { -** cksumtype[0] INTEGER, -** checksum[1] OCTET STRING -** } -*/ -typedef struct krb5_checksum_st - { - ASN1_INTEGER *ctype; - ASN1_OCTET_STRING *checksum; - } KRB5_CHECKSUM; - -DECLARE_STACK_OF(KRB5_CHECKSUM) - - -/* EncryptionKey ::= SEQUENCE { -** keytype[0] INTEGER, -** keyvalue[1] OCTET STRING -** } -*/ -typedef struct krb5_encryptionkey_st - { - ASN1_INTEGER *ktype; - ASN1_OCTET_STRING *keyvalue; - } KRB5_ENCKEY; - -DECLARE_STACK_OF(KRB5_ENCKEY) - - -/* AuthorizationData ::= SEQUENCE OF SEQUENCE { -** ad-type[0] INTEGER, -** ad-data[1] OCTET STRING -** } -*/ -typedef struct krb5_authorization_st - { - ASN1_INTEGER *adtype; - ASN1_OCTET_STRING *addata; - } KRB5_AUTHDATA; - -DECLARE_STACK_OF(KRB5_AUTHDATA) - - -/* -- Unencrypted authenticator -** Authenticator ::= [APPLICATION 2] SEQUENCE { -** authenticator-vno[0] INTEGER, -** crealm[1] Realm, -** cname[2] PrincipalName, -** cksum[3] Checksum OPTIONAL, -** cusec[4] INTEGER, -** ctime[5] KerberosTime, -** subkey[6] EncryptionKey OPTIONAL, -** seq-number[7] INTEGER OPTIONAL, -** authorization-data[8] AuthorizationData OPTIONAL -** } -*/ -typedef struct krb5_authenticator_st - { - ASN1_INTEGER *avno; - ASN1_GENERALSTRING *crealm; - KRB5_PRINCNAME *cname; - KRB5_CHECKSUM *cksum; - ASN1_INTEGER *cusec; - ASN1_GENERALIZEDTIME *ctime; - KRB5_ENCKEY *subkey; - ASN1_INTEGER *seqnum; - KRB5_AUTHDATA *authorization; - } KRB5_AUTHENTBODY; - -typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; -DECLARE_STACK_OF(KRB5_AUTHENTBODY) - - -/* DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = -** type *name##_new(void); -** void name##_free(type *a); -** DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = -** DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = -** type *d2i_##name(type **a, const unsigned char **in, long len); -** int i2d_##name(type *a, unsigned char **out); -** DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it -*/ - -DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) -DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) -DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) -DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) -DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) -DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) - -DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) -DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) -DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) -DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) -DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) - - -/* BEGIN ERROR CODES */ -/* The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/crypto/openssl/crypto/lhash/lh_stats.c b/crypto/openssl/crypto/lhash/lh_stats.c index 5aa7766aa6..815615e338 100644 --- a/crypto/openssl/crypto/lhash/lh_stats.c +++ b/crypto/openssl/crypto/lhash/lh_stats.c @@ -139,7 +139,7 @@ void lh_node_usage_stats(LHASH *lh, FILE *out) #else #ifndef OPENSSL_NO_FP_API -void lh_stats(const LHASH *lh, FILE *fp) +void lh_stats(const _LHASH *lh, FILE *fp) { BIO *bp; @@ -151,7 +151,7 @@ void lh_stats(const LHASH *lh, FILE *fp) end:; } -void lh_node_stats(const LHASH *lh, FILE *fp) +void lh_node_stats(const _LHASH *lh, FILE *fp) { BIO *bp; @@ -163,7 +163,7 @@ void lh_node_stats(const LHASH *lh, FILE *fp) end:; } -void lh_node_usage_stats(const LHASH *lh, FILE *fp) +void lh_node_usage_stats(const _LHASH *lh, FILE *fp) { BIO *bp; @@ -177,7 +177,7 @@ end:; #endif -void lh_stats_bio(const LHASH *lh, BIO *out) +void lh_stats_bio(const _LHASH *lh, BIO *out) { BIO_printf(out,"num_items = %lu\n",lh->num_items); BIO_printf(out,"num_nodes = %u\n",lh->num_nodes); @@ -205,7 +205,7 @@ void lh_stats_bio(const LHASH *lh, BIO *out) #endif } -void lh_node_stats_bio(const LHASH *lh, BIO *out) +void lh_node_stats_bio(const _LHASH *lh, BIO *out) { LHASH_NODE *n; unsigned int i,num; @@ -218,7 +218,7 @@ void lh_node_stats_bio(const LHASH *lh, BIO *out) } } -void lh_node_usage_stats_bio(const LHASH *lh, BIO *out) +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out) { LHASH_NODE *n; unsigned long num; diff --git a/crypto/openssl/crypto/lhash/lhash.c b/crypto/openssl/crypto/lhash/lhash.c index 0b41f87621..47f748081b 100644 --- a/crypto/openssl/crypto/lhash/lhash.c +++ b/crypto/openssl/crypto/lhash/lhash.c @@ -107,18 +107,18 @@ const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT; #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ -static void expand(LHASH *lh); -static void contract(LHASH *lh); -static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash); +static void expand(_LHASH *lh); +static void contract(_LHASH *lh); +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); -LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) { - LHASH *ret; + _LHASH *ret; int i; - if ((ret=(LHASH *)OPENSSL_malloc(sizeof(LHASH))) == NULL) + if ((ret=OPENSSL_malloc(sizeof(_LHASH))) == NULL) goto err0; - if ((ret->b=(LHASH_NODE **)OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL) + if ((ret->b=OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL) goto err1; for (i=0; ib[i]=NULL; @@ -154,7 +154,7 @@ err0: return(NULL); } -void lh_free(LHASH *lh) +void lh_free(_LHASH *lh) { unsigned int i; LHASH_NODE *n,*nn; @@ -176,7 +176,7 @@ void lh_free(LHASH *lh) OPENSSL_free(lh); } -void *lh_insert(LHASH *lh, void *data) +void *lh_insert(_LHASH *lh, void *data) { unsigned long hash; LHASH_NODE *nn,**rn; @@ -214,7 +214,7 @@ void *lh_insert(LHASH *lh, void *data) return(ret); } -void *lh_delete(LHASH *lh, const void *data) +void *lh_delete(_LHASH *lh, const void *data) { unsigned long hash; LHASH_NODE *nn,**rn; @@ -245,7 +245,7 @@ void *lh_delete(LHASH *lh, const void *data) return(ret); } -void *lh_retrieve(LHASH *lh, const void *data) +void *lh_retrieve(_LHASH *lh, const void *data) { unsigned long hash; LHASH_NODE **rn; @@ -267,12 +267,15 @@ void *lh_retrieve(LHASH *lh, const void *data) return(ret); } -static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, +static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) { int i; LHASH_NODE *a,*n; + if (lh == NULL) + return; + /* reverse the order so we search from 'top to bottom' * We were having memory leaks otherwise */ for (i=lh->num_nodes-1; i>=0; i--) @@ -282,6 +285,8 @@ static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, { /* 28/05/91 - eay - n added so items can be deleted * via lh_doall */ + /* 22/05/08 - ben - eh? since a is not passed, + * this should not be needed */ n=a->next; if(use_arg) func_arg(a->data,arg); @@ -292,53 +297,29 @@ static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, } } -void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func) +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) { doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); } -void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) { doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); } -static void expand(LHASH *lh) +static void expand(_LHASH *lh) { LHASH_NODE **n,**n1,**n2,*np; - unsigned int p,i,j,pmax; + unsigned int p,i,j; unsigned long hash,nni; - p=(int)lh->p++; - nni=lh->num_alloc_nodes; - pmax=lh->pmax; - - if ((lh->p) >= lh->pmax) - { - j=(int)lh->num_alloc_nodes*2; - n=(LHASH_NODE **)OPENSSL_realloc(lh->b, - (int)sizeof(LHASH_NODE *)*j); - if (n == NULL) - { -/* fputs("realloc error in lhash",stderr); */ - lh->error++; - lh->p=0; - return; - } - /* else */ - for (i=(int)lh->num_alloc_nodes; ipmax=lh->num_alloc_nodes; - lh->num_alloc_nodes=j; - lh->num_expand_reallocs++; - lh->p=0; - lh->b=n; - } - lh->num_nodes++; lh->num_expands++; + p=(int)lh->p++; n1= &(lh->b[p]); - n2= &(lh->b[p+pmax]); + n2= &(lh->b[p+(int)lh->pmax]); *n2=NULL; /* 27/07/92 - eay - undefined pointer bug */ + nni=lh->num_alloc_nodes; for (np= *n1; np != NULL; ) { @@ -359,14 +340,35 @@ static void expand(LHASH *lh) np= *n1; } + if ((lh->p) >= lh->pmax) + { + j=(int)lh->num_alloc_nodes*2; + n=(LHASH_NODE **)OPENSSL_realloc(lh->b, + (int)(sizeof(LHASH_NODE *)*j)); + if (n == NULL) + { +/* fputs("realloc error in lhash",stderr); */ + lh->error++; + lh->p=0; + return; + } + /* else */ + for (i=(int)lh->num_alloc_nodes; ipmax=lh->num_alloc_nodes; + lh->num_alloc_nodes=j; + lh->num_expand_reallocs++; + lh->p=0; + lh->b=n; + } } -static void contract(LHASH *lh) +static void contract(_LHASH *lh) { LHASH_NODE **n,*n1,*np; - int idx = lh->p+lh->pmax-1; - np=lh->b[idx]; + np=lh->b[lh->p+lh->pmax-1]; + lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */ if (lh->p == 0) { n=(LHASH_NODE **)OPENSSL_realloc(lh->b, @@ -386,7 +388,6 @@ static void contract(LHASH *lh) else lh->p--; - lh->b[idx] = NULL; lh->num_nodes--; lh->num_contracts++; @@ -401,7 +402,7 @@ static void contract(LHASH *lh) } } -static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash) +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) { LHASH_NODE **ret,*n1; unsigned long hash,nn; @@ -468,7 +469,7 @@ unsigned long lh_strhash(const char *c) return((ret>>16)^ret); } -unsigned long lh_num_items(const LHASH *lh) +unsigned long lh_num_items(const _LHASH *lh) { return lh ? lh->num_items : 0; } diff --git a/crypto/openssl/crypto/lhash/lhash.h b/crypto/openssl/crypto/lhash/lhash.h index d392d0cd80..e7d8763591 100644 --- a/crypto/openssl/crypto/lhash/lhash.h +++ b/crypto/openssl/crypto/lhash/lhash.h @@ -98,42 +98,42 @@ typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *); * macros if the functions are strictly internal. */ /* First: "hash" functions */ -#define DECLARE_LHASH_HASH_FN(f_name,o_type) \ - unsigned long f_name##_LHASH_HASH(const void *); -#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \ - unsigned long f_name##_LHASH_HASH(const void *arg) { \ - o_type a = (o_type)arg; \ - return f_name(a); } -#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH +#define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +#define LHASH_HASH_FN(name) name##_LHASH_HASH /* Second: "compare" functions */ -#define DECLARE_LHASH_COMP_FN(f_name,o_type) \ - int f_name##_LHASH_COMP(const void *, const void *); -#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \ - int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \ - o_type a = (o_type)arg1; \ - o_type b = (o_type)arg2; \ - return f_name(a,b); } -#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP +#define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +#define LHASH_COMP_FN(name) name##_LHASH_COMP /* Third: "doall" functions */ -#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \ - void f_name##_LHASH_DOALL(void *); -#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \ - void f_name##_LHASH_DOALL(void *arg) { \ - o_type a = (o_type)arg; \ - f_name(a); } -#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL +#define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +#define LHASH_DOALL_FN(name) name##_LHASH_DOALL /* Fourth: "doall_arg" functions */ -#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ - void f_name##_LHASH_DOALL_ARG(void *, void *); -#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ - void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ - o_type a = (o_type)arg1; \ - a_type b = (a_type)arg2; \ - f_name(a,b); } -#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG +#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG typedef struct lhash_st { @@ -163,7 +163,8 @@ typedef struct lhash_st unsigned long num_hash_comps; int error; - } LHASH; + } _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ #define LH_LOAD_MULT 256 @@ -171,27 +172,67 @@ typedef struct lhash_st * in lh_insert(). */ #define lh_error(lh) ((lh)->error) -LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); -void lh_free(LHASH *lh); -void *lh_insert(LHASH *lh, void *data); -void *lh_delete(LHASH *lh, const void *data); -void *lh_retrieve(LHASH *lh, const void *data); -void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func); -void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); unsigned long lh_strhash(const char *c); -unsigned long lh_num_items(const LHASH *lh); +unsigned long lh_num_items(const _LHASH *lh); #ifndef OPENSSL_NO_FP_API -void lh_stats(const LHASH *lh, FILE *out); -void lh_node_stats(const LHASH *lh, FILE *out); -void lh_node_usage_stats(const LHASH *lh, FILE *out); +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); #endif #ifndef OPENSSL_NO_BIO -void lh_stats_bio(const LHASH *lh, BIO *out); -void lh_node_stats_bio(const LHASH *lh, BIO *out); -void lh_node_usage_stats_bio(const LHASH *lh, BIO *out); +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); #endif + +/* Type checking... */ + +#define LHASH_OF(type) struct lhash_st_##type + +#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +#define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +#define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +#define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +#define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +#define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + #ifdef __cplusplus } #endif diff --git a/crypto/openssl/crypto/md2/md2.h b/crypto/openssl/crypto/md2/md2.h deleted file mode 100644 index d59c9f2593..0000000000 --- a/crypto/openssl/crypto/md2/md2.h +++ /dev/null @@ -1,95 +0,0 @@ -/* crypto/md/md2.h */ -/* Copyright (C) 1995-1997 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_MD2_H -#define HEADER_MD2_H - -#include /* OPENSSL_NO_MD2, MD2_INT */ -#ifdef OPENSSL_NO_MD2 -#error MD2 is disabled. -#endif -#include - -#define MD2_DIGEST_LENGTH 16 -#define MD2_BLOCK 16 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct MD2state_st - { - unsigned int num; - unsigned char data[MD2_BLOCK]; - MD2_INT cksm[MD2_BLOCK]; - MD2_INT state[MD2_BLOCK]; - } MD2_CTX; - -const char *MD2_options(void); -#ifdef OPENSSL_FIPS -int private_MD2_Init(MD2_CTX *c); -#endif -int MD2_Init(MD2_CTX *c); -int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len); -int MD2_Final(unsigned char *md, MD2_CTX *c); -unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/crypto/openssl/crypto/md2/md2_dgst.c b/crypto/openssl/crypto/md2/md2_dgst.c deleted file mode 100644 index cc4eeaf7a7..0000000000 --- a/crypto/openssl/crypto/md2/md2_dgst.c +++ /dev/null @@ -1,232 +0,0 @@ -/* crypto/md2/md2_dgst.c */ -/* 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 -#include -#include -#include -#include -#include -#ifdef OPENSSL_FIPS -#include -#endif - -#include - -const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT; - -/* Implemented from RFC1319 The MD2 Message-Digest Algorithm - */ - -#define UCHAR unsigned char - -static void md2_block(MD2_CTX *c, const unsigned char *d); -/* The magic S table - I have converted it to hex since it is - * basically just a random byte string. */ -static MD2_INT S[256]={ - 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, - 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, - 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, - 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, - 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, - 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, - 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, - 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, - 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, - 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, - 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, - 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, - 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, - 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, - 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, - 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, - 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, - 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, - 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, - 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, - 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, - 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, - 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, - 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, - 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, - 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, - 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, - 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, - 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, - 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, - 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, - 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14, - }; - -const char *MD2_options(void) - { - if (sizeof(MD2_INT) == 1) - return("md2(char)"); - else - return("md2(int)"); - } - -FIPS_NON_FIPS_MD_Init(MD2) - { - c->num=0; - memset(c->state,0,sizeof c->state); - memset(c->cksm,0,sizeof c->cksm); - memset(c->data,0,sizeof c->data); - return 1; - } - -int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len) - { - register UCHAR *p; - - if (len == 0) return 1; - - p=c->data; - if (c->num != 0) - { - if ((c->num+len) >= MD2_BLOCK) - { - memcpy(&(p[c->num]),data,MD2_BLOCK-c->num); - md2_block(c,c->data); - data+=(MD2_BLOCK - c->num); - len-=(MD2_BLOCK - c->num); - c->num=0; - /* drop through and do the rest */ - } - else - { - memcpy(&(p[c->num]),data,len); - /* data+=len; */ - c->num+=(int)len; - return 1; - } - } - /* we now can process the input data in blocks of MD2_BLOCK - * chars and save the leftovers to c->data. */ - while (len >= MD2_BLOCK) - { - md2_block(c,data); - data+=MD2_BLOCK; - len-=MD2_BLOCK; - } - memcpy(p,data,len); - c->num=(int)len; - return 1; - } - -static void md2_block(MD2_CTX *c, const unsigned char *d) - { - register MD2_INT t,*sp1,*sp2; - register int i,j; - MD2_INT state[48]; - - sp1=c->state; - sp2=c->cksm; - j=sp2[MD2_BLOCK-1]; - for (i=0; i<16; i++) - { - state[i]=sp1[i]; - state[i+16]=t=d[i]; - state[i+32]=(t^sp1[i]); - j=sp2[i]^=S[t^j]; - } - t=0; - for (i=0; i<18; i++) - { - for (j=0; j<48; j+=8) - { - t= state[j+ 0]^=S[t]; - t= state[j+ 1]^=S[t]; - t= state[j+ 2]^=S[t]; - t= state[j+ 3]^=S[t]; - t= state[j+ 4]^=S[t]; - t= state[j+ 5]^=S[t]; - t= state[j+ 6]^=S[t]; - t= state[j+ 7]^=S[t]; - } - t=(t+i)&0xff; - } - memcpy(sp1,state,16*sizeof(MD2_INT)); - OPENSSL_cleanse(state,48*sizeof(MD2_INT)); - } - -int MD2_Final(unsigned char *md, MD2_CTX *c) - { - int i,v; - register UCHAR *cp; - register MD2_INT *p1,*p2; - - cp=c->data; - p1=c->state; - p2=c->cksm; - v=MD2_BLOCK-c->num; - for (i=c->num; i -#include "cryptlib.h" -#include - -/* This is a separate file so that #defines in cryptlib.h can - * map my MD functions to different names */ - -unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md) - { - MD2_CTX c; - static unsigned char m[MD2_DIGEST_LENGTH]; - - if (md == NULL) md=m; - if (!MD2_Init(&c)) - return NULL; -#ifndef CHARSET_EBCDIC - MD2_Update(&c,d,n); -#else - { - char temp[1024]; - unsigned long chunk; - - while (n > 0) - { - chunk = (n > sizeof(temp)) ? sizeof(temp) : n; - ebcdic2ascii(temp, d, chunk); - MD2_Update(&c,temp,chunk); - n -= chunk; - d += chunk; - } - } -#endif - MD2_Final(md,&c); - OPENSSL_cleanse(&c,sizeof(c)); /* Security consideration */ - return(md); - } diff --git a/crypto/openssl/crypto/md32_common.h b/crypto/openssl/crypto/md32_common.h index 61bcd9786f..1cb783944e 100644 --- a/crypto/openssl/crypto/md32_common.h +++ b/crypto/openssl/crypto/md32_common.h @@ -241,11 +241,11 @@ #ifndef PEDANTIC # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) # if defined(__s390x__) -# define HOST_c2l(c,l) ({ asm ("lrv %0,0(%1)" \ - :"=r"(l) : "r"(c)); \ +# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \ + :"=d"(l) :"m"(*(const unsigned int *)(c)));\ (c)+=4; (l); }) -# define HOST_l2c(l,c) ({ asm ("strv %0,0(%1)" \ - : : "r"(l),"r"(c) : "memory"); \ +# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \ + :"=m"(*(unsigned int *)(c)) :"d"(l));\ (c)+=4; (l); }) # endif # endif @@ -293,7 +293,7 @@ int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) * Wei Dai for pointing it out. */ if (l < c->Nl) /* overflow */ c->Nh++; - c->Nh+=(len>>29); /* might cause compiler warning on 16-bit */ + c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bit */ c->Nl=l; n = c->num; @@ -331,7 +331,7 @@ int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) if (len != 0) { p = (unsigned char *)c->data; - c->num = len; + c->num = (unsigned int)len; memcpy (p,data,len); } return 1; diff --git a/crypto/openssl/crypto/md4/md4.h b/crypto/openssl/crypto/md4/md4.h index ba1fe4a6ee..c3ed9b3f75 100644 --- a/crypto/openssl/crypto/md4/md4.h +++ b/crypto/openssl/crypto/md4/md4.h @@ -77,7 +77,7 @@ extern "C" { * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#if defined(__LP32__) #define MD4_LONG unsigned long #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) #define MD4_LONG unsigned long @@ -105,9 +105,6 @@ typedef struct MD4state_st unsigned int num; } MD4_CTX; -#ifdef OPENSSL_FIPS -int private_MD4_Init(MD4_CTX *c); -#endif int MD4_Init(MD4_CTX *c); int MD4_Update(MD4_CTX *c, const void *data, size_t len); int MD4_Final(unsigned char *md, MD4_CTX *c); diff --git a/crypto/openssl/crypto/md4/md4_dgst.c b/crypto/openssl/crypto/md4/md4_dgst.c index 0f5448601d..e0c42e8596 100644 --- a/crypto/openssl/crypto/md4/md4_dgst.c +++ b/crypto/openssl/crypto/md4/md4_dgst.c @@ -59,11 +59,6 @@ #include #include "md4_locl.h" #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT; @@ -75,15 +70,13 @@ const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT; #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -FIPS_NON_FIPS_MD_Init(MD4) +int MD4_Init(MD4_CTX *c) { + memset (c,0,sizeof(*c)); c->A=INIT_DATA_A; c->B=INIT_DATA_B; c->C=INIT_DATA_C; c->D=INIT_DATA_D; - c->Nl=0; - c->Nh=0; - c->num=0; return 1; } diff --git a/crypto/openssl/crypto/md5/md5.h b/crypto/openssl/crypto/md5/md5.h index 0761f84a27..4cbf84386b 100644 --- a/crypto/openssl/crypto/md5/md5.h +++ b/crypto/openssl/crypto/md5/md5.h @@ -77,7 +77,7 @@ extern "C" { * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#if defined(__LP32__) #define MD5_LONG unsigned long #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) #define MD5_LONG unsigned long @@ -105,9 +105,6 @@ typedef struct MD5state_st unsigned int num; } MD5_CTX; -#ifdef OPENSSL_FIPS -int private_MD5_Init(MD5_CTX *c); -#endif int MD5_Init(MD5_CTX *c); int MD5_Update(MD5_CTX *c, const void *data, size_t len); int MD5_Final(unsigned char *md, MD5_CTX *c); diff --git a/crypto/openssl/crypto/md5/md5_dgst.c b/crypto/openssl/crypto/md5/md5_dgst.c index 47bb9020ee..beace632e3 100644 --- a/crypto/openssl/crypto/md5/md5_dgst.c +++ b/crypto/openssl/crypto/md5/md5_dgst.c @@ -59,11 +59,6 @@ #include #include "md5_locl.h" #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; @@ -75,15 +70,13 @@ const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -FIPS_NON_FIPS_MD_Init(MD5) +int MD5_Init(MD5_CTX *c) { + memset (c,0,sizeof(*c)); c->A=INIT_DATA_A; c->B=INIT_DATA_B; c->C=INIT_DATA_C; c->D=INIT_DATA_D; - c->Nl=0; - c->Nh=0; - c->num=0; return 1; } diff --git a/crypto/openssl/crypto/md5/md5_locl.h b/crypto/openssl/crypto/md5/md5_locl.h index 84e81b960d..968d577995 100644 --- a/crypto/openssl/crypto/md5/md5_locl.h +++ b/crypto/openssl/crypto/md5/md5_locl.h @@ -69,6 +69,8 @@ # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) # define md5_block_data_order md5_block_asm_data_order +# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define md5_block_data_order md5_block_asm_data_order # endif #endif diff --git a/crypto/openssl/crypto/mdc2/mdc2.h b/crypto/openssl/crypto/mdc2/mdc2.h index 7e1354116a..72778a5212 100644 --- a/crypto/openssl/crypto/mdc2/mdc2.h +++ b/crypto/openssl/crypto/mdc2/mdc2.h @@ -80,9 +80,7 @@ typedef struct mdc2_ctx_st int pad_type; /* either 1 or 2, default 1 */ } MDC2_CTX; -#ifdef OPENSSL_FIPS -int private_MDC2_Init(MDC2_CTX *c); -#endif + int MDC2_Init(MDC2_CTX *c); int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); int MDC2_Final(unsigned char *md, MDC2_CTX *c); diff --git a/crypto/openssl/crypto/mdc2/mdc2dgst.c b/crypto/openssl/crypto/mdc2/mdc2dgst.c index a36b3f578e..4aa406edc3 100644 --- a/crypto/openssl/crypto/mdc2/mdc2dgst.c +++ b/crypto/openssl/crypto/mdc2/mdc2dgst.c @@ -61,11 +61,6 @@ #include #include #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - #undef c2l #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ @@ -80,7 +75,7 @@ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); -FIPS_NON_FIPS_MD_Init(MDC2) +int MDC2_Init(MDC2_CTX *c) { c->num=0; c->pad_type=1; diff --git a/crypto/openssl/crypto/mem.c b/crypto/openssl/crypto/mem.c index 00ebaf0b9b..6f80dd33eb 100644 --- a/crypto/openssl/crypto/mem.c +++ b/crypto/openssl/crypto/mem.c @@ -101,7 +101,7 @@ static void (*free_locked_func)(void *) = free; /* may be changed as long as 'allow_customize_debug' is set */ /* XXX use correct function pointer types */ -#if defined(CRYPTO_MDEBUG) && !defined(OPENSSL_FIPS) +#ifdef CRYPTO_MDEBUG /* use default functions from mem_dbg.c */ static void (*malloc_debug_func)(void *,int,const char *,int,int) = CRYPTO_dbg_malloc; @@ -110,14 +110,6 @@ static void (*realloc_debug_func)(void *,void *,int,const char *,int,int) static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free; static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options; static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options; - -static int (*push_info_func)(const char *info, const char *file, int line) - = CRYPTO_dbg_push_info; -static int (*pop_info_func)(void) - = CRYPTO_dbg_pop_info; -static int (*remove_all_info_func)(void) - = CRYPTO_dbg_remove_all_info; - #else /* applications can use CRYPTO_malloc_debug_init() to select above case * at run-time */ @@ -127,13 +119,6 @@ static void (*realloc_debug_func)(void *,void *,int,const char *,int,int) static void (*free_debug_func)(void *,int) = NULL; static void (*set_debug_options_func)(long) = NULL; static long (*get_debug_options_func)(void) = NULL; - - -static int (*push_info_func)(const char *info, const char *file, int line) - = NULL; -static int (*pop_info_func)(void) = NULL; -static int (*remove_all_info_func)(void) = NULL; - #endif @@ -209,15 +194,6 @@ int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int), return 1; } -void CRYPTO_set_mem_info_functions( - int (*push_info_fn)(const char *info, const char *file, int line), - int (*pop_info_fn)(void), - int (*remove_all_info_fn)(void)) - { - push_info_func = push_info_fn; - pop_info_func = pop_info_fn; - remove_all_info_func = remove_all_info_fn; - } void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t), void (**f)(void *)) @@ -274,7 +250,6 @@ void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int), void *CRYPTO_malloc_locked(int num, const char *file, int line) { void *ret = NULL; - extern unsigned char cleanse_ctr; if (num <= 0) return NULL; @@ -291,11 +266,15 @@ void *CRYPTO_malloc_locked(int num, const char *file, int line) if (malloc_debug_func != NULL) malloc_debug_func(ret, num, file, line, 1); +#ifndef OPENSSL_CPUID_OBJ /* Create a dependency on the value of 'cleanse_ctr' so our memory * sanitisation function can't be optimised out. NB: We only do * this for >2Kb so the overhead doesn't bother us. */ if(ret && (num > 2048)) + { extern unsigned char cleanse_ctr; ((unsigned char *)ret)[0] = cleanse_ctr; + } +#endif return ret; } @@ -315,7 +294,6 @@ void CRYPTO_free_locked(void *str) void *CRYPTO_malloc(int num, const char *file, int line) { void *ret = NULL; - extern unsigned char cleanse_ctr; if (num <= 0) return NULL; @@ -332,12 +310,23 @@ void *CRYPTO_malloc(int num, const char *file, int line) if (malloc_debug_func != NULL) malloc_debug_func(ret, num, file, line, 1); +#ifndef OPENSSL_CPUID_OBJ /* Create a dependency on the value of 'cleanse_ctr' so our memory * sanitisation function can't be optimised out. NB: We only do * this for >2Kb so the overhead doesn't bother us. */ if(ret && (num > 2048)) + { extern unsigned char cleanse_ctr; ((unsigned char *)ret)[0] = cleanse_ctr; + } +#endif + + return ret; + } +char *CRYPTO_strdup(const char *str, const char *file, int line) + { + char *ret = CRYPTO_malloc(strlen(str)+1, file, line); + strcpy(ret, str); return ret; } @@ -423,24 +412,3 @@ long CRYPTO_get_mem_debug_options(void) return get_debug_options_func(); return 0; } - -int CRYPTO_push_info_(const char *info, const char *file, int line) - { - if (push_info_func) - return push_info_func(info, file, line); - return 1; - } - -int CRYPTO_pop_info(void) - { - if (pop_info_func) - return pop_info_func(); - return 1; - } - -int CRYPTO_remove_all_info(void) - { - if (remove_all_info_func) - return remove_all_info_func(); - return 1; - } diff --git a/crypto/openssl/crypto/mem_dbg.c b/crypto/openssl/crypto/mem_dbg.c index dfeb084799..ac793397f1 100644 --- a/crypto/openssl/crypto/mem_dbg.c +++ b/crypto/openssl/crypto/mem_dbg.c @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 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 #include @@ -81,8 +134,11 @@ static int mh_mode=CRYPTO_MEM_CHECK_OFF; */ static unsigned long order = 0; /* number of memory requests */ -static LHASH *mh=NULL; /* hash-table of memory requests (address as key); - * access requires MALLOC2 lock */ + +DECLARE_LHASH_OF(MEM); +static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests + * (address as key); access requires + * MALLOC2 lock */ typedef struct app_mem_info_st @@ -93,8 +149,8 @@ typedef struct app_mem_info_st * CRYPTO_pop_info() to pop an entry, * CRYPTO_remove_all_info() to pop all entries. */ - { - unsigned long thread; + { + CRYPTO_THREADID threadid; const char *file; int line; const char *info; @@ -104,10 +160,13 @@ typedef struct app_mem_info_st static void app_info_free(APP_INFO *); -static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's - * that are at the top of their thread's stack - * (with `thread' as key); - * access requires MALLOC2 lock */ +DECLARE_LHASH_OF(APP_INFO); +static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those + * app_mem_info_st's that are at + * the top of their thread's + * stack (with `thread' as key); + * access requires MALLOC2 + * lock */ typedef struct mem_st /* memory-block description */ @@ -116,7 +175,7 @@ typedef struct mem_st int num; const char *file; int line; - unsigned long thread; + CRYPTO_THREADID threadid; unsigned long order; time_t time; APP_INFO *app_info; @@ -136,11 +195,11 @@ static unsigned int num_disable = 0; /* num_disable > 0 * iff * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ -static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0. - * CRYPTO_LOCK_MALLOC2 is locked - * exactly in this case (by the - * thread named in disabling_thread). - */ + +/* Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this + * case (by the thread named in disabling_thread). + */ +static CRYPTO_THREADID disabling_threadid; static void app_info_free(APP_INFO *inf) { @@ -177,7 +236,9 @@ int CRYPTO_mem_ctrl(int mode) case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ if (mh_mode & CRYPTO_MEM_CHECK_ON) { - if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */ + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */ { /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if @@ -195,7 +256,7 @@ int CRYPTO_mem_ctrl(int mode) CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; - disabling_thread=CRYPTO_thread_id(); + CRYPTO_THREADID_cpy(&disabling_threadid, &cur); } num_disable++; } @@ -228,10 +289,12 @@ int CRYPTO_is_mem_check_on(void) if (mh_mode & CRYPTO_MEM_CHECK_ON) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) - || (disabling_thread != CRYPTO_thread_id()); + || CRYPTO_THREADID_cmp(&disabling_threadid, &cur); CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); } @@ -249,49 +312,49 @@ long CRYPTO_dbg_get_options(void) return options; } -/* static int mem_cmp(MEM *a, MEM *b) */ -static int mem_cmp(const void *a_void, const void *b_void) +static int mem_cmp(const MEM *a, const MEM *b) { #ifdef _WIN64 - const char *a=(const char *)((const MEM *)a_void)->addr, - *b=(const char *)((const MEM *)b_void)->addr; - if (a==b) return 0; - else if (a>b) return 1; + const char *ap=(const char *)a->addr, + *bp=(const char *)b->addr; + if (ap==bp) return 0; + else if (ap>bp) return 1; else return -1; #else - return((const char *)((const MEM *)a_void)->addr - - (const char *)((const MEM *)b_void)->addr); + return (const char *)a->addr - (const char *)b->addr; #endif } +static IMPLEMENT_LHASH_COMP_FN(mem, MEM) -/* static unsigned long mem_hash(MEM *a) */ -static unsigned long mem_hash(const void *a_void) +static unsigned long mem_hash(const MEM *a) { unsigned long ret; - ret=(unsigned long)((const MEM *)a_void)->addr; + ret=(unsigned long)a->addr; ret=ret*17851+(ret>>14)*7+(ret>>4)*251; return(ret); } +static IMPLEMENT_LHASH_HASH_FN(mem, MEM) /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */ static int app_info_cmp(const void *a_void, const void *b_void) { - return(((const APP_INFO *)a_void)->thread - != ((const APP_INFO *)b_void)->thread); + return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid, + &((const APP_INFO *)b_void)->threadid); } +static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO) -/* static unsigned long app_info_hash(APP_INFO *a) */ -static unsigned long app_info_hash(const void *a_void) +static unsigned long app_info_hash(const APP_INFO *a) { unsigned long ret; - ret=(unsigned long)((const APP_INFO *)a_void)->thread; - + ret = CRYPTO_THREADID_hash(&a->threadid); + /* This is left in as a "who am I to question legacy?" measure */ ret=ret*17851+(ret>>14)*7+(ret>>4)*251; return(ret); } +static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO) static APP_INFO *pop_info(void) { @@ -300,21 +363,22 @@ static APP_INFO *pop_info(void) if (amih != NULL) { - tmp.thread=CRYPTO_thread_id(); - if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL) + CRYPTO_THREADID_current(&tmp.threadid); + if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL) { APP_INFO *next=ret->next; if (next != NULL) { next->references++; - lh_insert(amih,(char *)next); + (void)lh_APP_INFO_insert(amih,next); } #ifdef LEVITTE_DEBUG_MEM - if (ret->thread != tmp.thread) + if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid)) { fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", - ret->thread, tmp.thread); + CRYPTO_THREADID_hash(&ret->threadid), + CRYPTO_THREADID_hash(&tmp.threadid)); abort(); } #endif @@ -330,7 +394,7 @@ static APP_INFO *pop_info(void) return(ret); } -int CRYPTO_dbg_push_info(const char *info, const char *file, int line) +int CRYPTO_push_info_(const char *info, const char *file, int line) { APP_INFO *ami, *amim; int ret=0; @@ -346,7 +410,7 @@ int CRYPTO_dbg_push_info(const char *info, const char *file, int line) } if (amih == NULL) { - if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL) + if ((amih=lh_APP_INFO_new()) == NULL) { OPENSSL_free(ami); ret=0; @@ -354,20 +418,21 @@ int CRYPTO_dbg_push_info(const char *info, const char *file, int line) } } - ami->thread=CRYPTO_thread_id(); + CRYPTO_THREADID_current(&ami->threadid); ami->file=file; ami->line=line; ami->info=info; ami->references=1; ami->next=NULL; - if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL) + if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL) { #ifdef LEVITTE_DEBUG_MEM - if (ami->thread != amim->thread) + if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid)) { fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", - amim->thread, ami->thread); + CRYPTO_THREADID_hash(&amim->threadid), + CRYPTO_THREADID_hash(&ami->threadid)); abort(); } #endif @@ -380,7 +445,7 @@ int CRYPTO_dbg_push_info(const char *info, const char *file, int line) return(ret); } -int CRYPTO_dbg_pop_info(void) +int CRYPTO_pop_info(void) { int ret=0; @@ -395,7 +460,7 @@ int CRYPTO_dbg_pop_info(void) return(ret); } -int CRYPTO_dbg_remove_all_info(void) +int CRYPTO_remove_all_info(void) { int ret=0; @@ -439,7 +504,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, } if (mh == NULL) { - if ((mh=lh_new(mem_hash, mem_cmp)) == NULL) + if ((mh=lh_MEM_new()) == NULL) { OPENSSL_free(addr); OPENSSL_free(m); @@ -453,9 +518,9 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, m->line=line; m->num=num; if (options & V_CRYPTO_MDEBUG_THREAD) - m->thread=CRYPTO_thread_id(); + CRYPTO_THREADID_current(&m->threadid); else - m->thread=0; + memset(&m->threadid, 0, sizeof(m->threadid)); if (order == break_order_num) { @@ -464,7 +529,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, } m->order=order++; #ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n", + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n", m->order, (before_p & 128) ? '*' : '+', m->addr, m->num); @@ -474,16 +539,16 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, else m->time=0; - tmp.thread=CRYPTO_thread_id(); + CRYPTO_THREADID_current(&tmp.threadid); m->app_info=NULL; if (amih != NULL - && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL) + && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL) { m->app_info = amim; amim->references++; } - if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) + if ((mm=lh_MEM_insert(mh, m)) != NULL) { /* Not good, but don't sweat it */ if (mm->app_info != NULL) @@ -516,11 +581,11 @@ void CRYPTO_dbg_free(void *addr, int before_p) MemCheck_off(); /* make sure we hold MALLOC2 lock */ m.addr=addr; - mp=(MEM *)lh_delete(mh,(char *)&m); + mp=lh_MEM_delete(mh,&m); if (mp != NULL) { #ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n", + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n", mp->order, mp->addr, mp->num); #endif if (mp->app_info != NULL) @@ -566,18 +631,18 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, MemCheck_off(); /* make sure we hold MALLOC2 lock */ m.addr=addr1; - mp=(MEM *)lh_delete(mh,(char *)&m); + mp=lh_MEM_delete(mh,&m); if (mp != NULL) { #ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n", + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n", mp->order, mp->addr, mp->num, addr2, num); #endif mp->addr=addr2; mp->num=num; - lh_insert(mh,(char *)mp); + (void)lh_MEM_insert(mh,mp); } MemCheck_on(); /* release MALLOC2 lock @@ -596,14 +661,14 @@ typedef struct mem_leak_st long bytes; } MEM_LEAK; -static void print_leak(const MEM *m, MEM_LEAK *l) +static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) { char buf[1024]; char *bufp = buf; APP_INFO *amip; int ami_cnt; struct tm *lcl = NULL; - unsigned long ti; + CRYPTO_THREADID ti; #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf)) @@ -625,7 +690,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l) if (options & V_CRYPTO_MDEBUG_THREAD) { - BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread); + BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", + CRYPTO_THREADID_hash(&m->threadid)); bufp += strlen(bufp); } @@ -642,8 +708,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l) ami_cnt=0; if (!amip) return; - ti=amip->thread; - + CRYPTO_THREADID_cpy(&ti, &amip->threadid); + do { int buf_len; @@ -653,7 +719,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l) memset(buf,'>',ami_cnt); BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, " thread=%lu, file=%s, line=%d, info=\"", - amip->thread, amip->file, amip->line); + CRYPTO_THREADID_hash(&amip->threadid), amip->file, + amip->line); buf_len=strlen(buf); info_len=strlen(amip->info); if (128 - buf_len - 3 < info_len) @@ -673,8 +740,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l) amip = amip->next; } - while(amip && amip->thread == ti); - + while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); + #ifdef LEVITTE_DEBUG_MEM if (amip) { @@ -684,7 +751,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l) #endif } -static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *) +static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK) void CRYPTO_mem_leaks(BIO *b) { @@ -699,12 +766,15 @@ void CRYPTO_mem_leaks(BIO *b) ml.bytes=0; ml.chunks=0; if (mh != NULL) - lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), - (char *)&ml); + lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK, + &ml); if (ml.chunks != 0) { BIO_printf(b,"%ld bytes leaked in %d chunks\n", ml.bytes,ml.chunks); +#ifdef CRYPTO_MDEBUG_ABORT + abort(); +#endif } else { @@ -717,7 +787,7 @@ void CRYPTO_mem_leaks(BIO *b) * XXX This should be in CRYPTO_mem_leaks_cb, * and CRYPTO_mem_leaks should be implemented by * using CRYPTO_mem_leaks_cb. - * (Also their should be a variant of lh_doall_arg + * (Also there should be a variant of lh_doall_arg * that takes a function pointer instead of a void *; * this would obviate the ugly and illegal * void_fn_to_char kludge in CRYPTO_mem_leaks_cb. @@ -734,14 +804,14 @@ void CRYPTO_mem_leaks(BIO *b) if (mh != NULL) { - lh_free(mh); + lh_MEM_free(mh); mh = NULL; } if (amih != NULL) { - if (lh_num_items(amih) == 0) + if (lh_APP_INFO_num_items(amih) == 0) { - lh_free(amih); + lh_APP_INFO_free(amih); amih = NULL; } } @@ -779,39 +849,26 @@ void CRYPTO_mem_leaks_fp(FILE *fp) /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h * If this code is restructured, remove the callback type if it is no longer * needed. -- Geoff Thorpe */ -static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb) + +/* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it + * is a function pointer and conversion to void * is prohibited. Instead + * pass its address + */ + +typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB; + +static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb) { - (**cb)(m->order,m->file,m->line,m->num,m->addr); + (*cb)(m->order,m->file,m->line,m->num,m->addr); } -static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **) +static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB) void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) { if (mh == NULL) return; CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); - lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb); + lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB, + &cb); CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); } - -void CRYPTO_malloc_debug_init(void) - { - CRYPTO_set_mem_debug_functions( - CRYPTO_dbg_malloc, - CRYPTO_dbg_realloc, - CRYPTO_dbg_free, - CRYPTO_dbg_set_options, - CRYPTO_dbg_get_options); - CRYPTO_set_mem_info_functions( - CRYPTO_dbg_push_info, - CRYPTO_dbg_pop_info, - CRYPTO_dbg_remove_all_info); - } - -char *CRYPTO_strdup(const char *str, const char *file, int line) - { - char *ret = CRYPTO_malloc(strlen(str)+1, file, line); - - strcpy(ret, str); - return ret; - } diff --git a/crypto/openssl/crypto/modes/cbc128.c b/crypto/openssl/crypto/modes/cbc128.c new file mode 100644 index 0000000000..8f8bd563b9 --- /dev/null +++ b/crypto/openssl/crypto/modes/cbc128.c @@ -0,0 +1,206 @@ +/* ==================================================================== + * Copyright (c) 2008 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 "modes.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#define STRICT_ALIGNMENT 1 +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +# define STRICT_ALIGNMENT 0 +#endif + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + const unsigned char *iv = ivec; + + assert(in && out && key && ivec); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (STRICT_ALIGNMENT && + ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { + while (len>=16) { + for(n=0; n<16; ++n) + out[n] = in[n] ^ iv[n]; + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } else { + while (len>=16) { + for(n=0; n<16; n+=sizeof(size_t)) + *(size_t*)(out+n) = + *(size_t*)(in+n) ^ *(size_t*)(iv+n); + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } +#endif + while (len) { + for(n=0; n<16 && n=16) { + (*block)(in, out, key); + for(n=0; n<16; ++n) + out[n] ^= iv[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + else { + while (len>=16) { + (*block)(in, out, key); + for(n=0; n<16; n+=sizeof(size_t)) + *(size_t *)(out+n) ^= *(size_t *)(iv+n); + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + memcpy(ivec,iv,16); + } else { + if (STRICT_ALIGNMENT && + ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { + unsigned char c; + while (len>=16) { + (*block)(in, tmp.c, key); + for(n=0; n<16; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } + else { + size_t c; + while (len>=16) { + (*block)(in, tmp.c, key); + for(n=0; n<16; n+=sizeof(size_t)) { + c = *(size_t *)(in+n); + *(size_t *)(out+n) = + *(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n); + *(size_t *)(ivec+n) = c; + } + len -= 16; + in += 16; + out += 16; + } + } + } +#endif + while (len) { + unsigned char c; + (*block)(in, tmp.c, key); + for(n=0; n<16 && n + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +#endif + +/* The input and output encrypted as though 128bit cfb mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num; + */ +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ivec && num); + + n = *num; + + if (enc) { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16%sizeof(size_t) == 0) do { /* always true actually */ + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n+1) % 16; + } +#if defined(STRICT_ALIGNMENT) + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) + break; +#endif + while (len>=16) { + (*block)(ivec, ivec, key); + for (; n<16; n+=sizeof(size_t)) { + *(size_t*)(out+n) = + *(size_t*)(ivec+n) ^= *(size_t*)(in+n); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + out[n] = ivec[n] ^= in[n]; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l=16) { + (*block)(ivec, ivec, key); + for (; n<16; n+=sizeof(size_t)) { + size_t t = *(size_t*)(in+n); + *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t; + *(size_t*)(ivec+n) = t; + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + unsigned char c; + out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l128) return; + + /* fill in the first half of the new IV with the current IV */ + memcpy(ovec,ivec,16); + /* construct the new IV */ + (*block)(ivec,ivec,key); + num = (nbits+7)/8; + if (enc) /* encrypt the input */ + for(n=0 ; n < num ; ++n) + out[n] = (ovec[16+n] = in[n] ^ ivec[n]); + else /* decrypt the input */ + for(n=0 ; n < num ; ++n) + out[n] = (ovec[16+n] = in[n]) ^ ivec[n]; + /* shift ovec left... */ + rem = nbits%8; + num = nbits/8; + if(rem==0) + memcpy(ivec,ovec+num,16); + else + for(n=0 ; n < 16 ; ++n) + ivec[n] = ovec[n+num]<>(8-rem); + + /* it is not necessary to cleanse ovec, since the IV is not secret */ +} + +/* N.B. This expects the input to be packed, MS bit first */ +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + unsigned char c[1],d[1]; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for(n=0 ; n> (unsigned int)(n%8)); + } +} + +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for(n=0 ; n + +#ifndef MODES_DEBUG # ifndef NDEBUG # define NDEBUG # endif #endif #include -#include -#include "cmll_locl.h" - -/* NOTE: the IV/counter CTR mode is big-endian. The rest of the Camellia code - * is endian-neutral. */ -/* increment counter (128-bit int) by 1 */ -static void Camellia_ctr128_inc(unsigned char *counter) - { - unsigned long c; - - /* Grab bottom dword of counter and increment */ - c = GETU32(counter + 12); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 12, c); - - /* if no overflow, we're done */ - if (c) - return; +typedef unsigned int u32; +typedef unsigned char u8; - /* Grab 1st dword of counter and increment */ - c = GETU32(counter + 8); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 8, c); - - /* if no overflow, we're done */ - if (c) - return; +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +#endif - /* Grab 2nd dword of counter and increment */ - c = GETU32(counter + 4); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 4, c); +/* NOTE: the IV/counter CTR mode is big-endian. The code itself + * is endian-neutral. */ - /* if no overflow, we're done */ - if (c) +/* increment counter (128-bit int) by 1 */ +static void ctr128_inc(unsigned char *counter) { + u32 n=16; + u8 c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) return; + } while (n); +} + +#if !defined(OPENSSL_SMALL_FOOTPRINT) +static void ctr128_inc_aligned(unsigned char *counter) { + size_t *data,c,n; + const union { long one; char little; } is_endian = {1}; + + if (is_endian.little) { + ctr128_inc(counter); return; - - /* Grab top dword of counter and increment */ - c = GETU32(counter + 0); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 0, c); } + data = (size_t *)counter; + n = 16/sizeof(size_t); + do { + --n; + c = data[n]; + ++c; + data[n] = c; + if (c) return; + } while (n); +} +#endif + /* The input encrypted as though 128bit counter mode is being * used. The extra state information to record how much of the * 128bit block we have used is contained in *num, and the * encrypted counter is kept in ecount_buf. Both *num and * ecount_buf must be initialised with zeros before the first - * call to Camellia_ctr128_encrypt(). + * call to CRYPTO_ctr128_encrypt(). * * This algorithm assumes that the counter is in the x lower bits * of the IV (ivec), and that the application has full control over @@ -112,32 +121,64 @@ static void Camellia_ctr128_inc(unsigned char *counter) * responsability for checking that the counter doesn't overflow * into the rest of the IV when incremented. */ -void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const CAMELLIA_KEY *key, - unsigned char ivec[CAMELLIA_BLOCK_SIZE], - unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], - unsigned int *num) - { - +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, block128_f block) +{ unsigned int n; - unsigned long l=length; + size_t l=0; - assert(in && out && key && counter && num); - assert(*num < CAMELLIA_BLOCK_SIZE); + assert(in && out && key && ecount_buf && num); + assert(*num < 16); n = *num; - while (l--) - { - if (n == 0) - { - Camellia_encrypt(ivec, ecount_buf, key); - Camellia_ctr128_inc(ivec); - } - *(out++) = *(in++) ^ ecount_buf[n]; - n = (n+1) % CAMELLIA_BLOCK_SIZE; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16%sizeof(size_t) == 0) do { /* always true actually */ + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n+1) % 16; } - *num=n; +#if defined(STRICT_ALIGNMENT) + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) + break; +#endif + while (len>=16) { + (*block)(ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + for (; n<16; n+=sizeof(size_t)) + *(size_t *)(out+n) = + *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; + return; + } while(0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * Trouble with Ciphertext Stealing, CTS, mode is that there is no + * common official specification, but couple of cipher/application + * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to + * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which + * deviates from mentioned RFCs. Most notably it allows input to be + * of block length and it doesn't flip the order of the last two + * blocks. CTS is being discussed even in ECB context, but it's not + * adopted for any known application. This implementation complies + * with mentioned RFCs and [as such] extends CBC mode. + */ + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ size_t residue, n; + + assert (in && out && key && ivec); + + if (len <= 16) return 0; + + if ((residue=len%16) == 0) residue = 16; + + len -= residue; + + CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block); + + in += len; + out += len; + + for (n=0; n +#include + +/* test vectors from RFC 3962 */ +static const unsigned char test_key[16] = "chicken teriyaki"; +static const unsigned char test_input[64] = + "I would like the" " General Gau's C" + "hicken, please, " "and wonton soup."; +static const unsigned char test_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static const unsigned char vector_17[17] = +{0xc6,0x35,0x35,0x68,0xf2,0xbf,0x8c,0xb4, 0xd8,0xa5,0x80,0x36,0x2d,0xa7,0xff,0x7f, + 0x97}; +static const unsigned char vector_31[31] = +{0xfc,0x00,0x78,0x3e,0x0e,0xfd,0xb2,0xc1, 0xd4,0x45,0xd4,0xc8,0xef,0xf7,0xed,0x22, + 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5}; +static const unsigned char vector_32[32] = +{0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8, + 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84}; +static const unsigned char vector_47[47] = +{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84, + 0xb3,0xff,0xfd,0x94,0x0c,0x16,0xa1,0x8c, 0x1b,0x55,0x49,0xd2,0xf8,0x38,0x02,0x9e, + 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5}; +static const unsigned char vector_48[48] = +{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84, + 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8, + 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8}; +static const unsigned char vector_64[64] = +{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84, + 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8, + 0x48,0x07,0xef,0xe8,0x36,0xee,0x89,0xa5, 0x26,0x73,0x0d,0xbc,0x2f,0x7b,0xc8,0x40, + 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8}; + +static AES_KEY encks, decks; + +void test_vector(const unsigned char *vector,size_t len) +{ unsigned char cleartext[64]; + unsigned char iv[sizeof(test_iv)]; + unsigned char ciphertext[64]; + size_t tail; + + printf("vector_%d\n",len); fflush(stdout); + + if ((tail=len%16) == 0) tail = 16; + tail += 16; + + /* test block-based encryption */ + memcpy(iv,test_iv,sizeof(test_iv)); + CRYPTO_cts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt); + if (memcmp(ciphertext,vector,len)) + fprintf(stderr,"output_%d mismatch\n",len), exit(1); + if (memcmp(iv,vector+len-tail,sizeof(iv))) + fprintf(stderr,"iv_%d mismatch\n",len), exit(1); + + /* test block-based decryption */ + memcpy(iv,test_iv,sizeof(test_iv)); + CRYPTO_cts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt); + if (memcmp(cleartext,test_input,len)) + fprintf(stderr,"input_%d mismatch\n",len), exit(2); + if (memcmp(iv,vector+len-tail,sizeof(iv))) + fprintf(stderr,"iv_%d mismatch\n",len), exit(2); + + /* test streamed encryption */ + memcpy(iv,test_iv,sizeof(test_iv)); + CRYPTO_cts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt); + if (memcmp(ciphertext,vector,len)) + fprintf(stderr,"output_%d mismatch\n",len), exit(3); + if (memcmp(iv,vector+len-tail,sizeof(iv))) + fprintf(stderr,"iv_%d mismatch\n",len), exit(3); + + /* test streamed decryption */ + memcpy(iv,test_iv,sizeof(test_iv)); + CRYPTO_cts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt); + if (memcmp(cleartext,test_input,len)) + fprintf(stderr,"input_%d mismatch\n",len), exit(4); + if (memcmp(iv,vector+len-tail,sizeof(iv))) + fprintf(stderr,"iv_%d mismatch\n",len), exit(4); +} + +main() +{ + AES_set_encrypt_key(test_key,128,&encks); + AES_set_decrypt_key(test_key,128,&decks); + + test_vector(vector_17,sizeof(vector_17)); + test_vector(vector_31,sizeof(vector_31)); + test_vector(vector_32,sizeof(vector_32)); + test_vector(vector_47,sizeof(vector_47)); + test_vector(vector_48,sizeof(vector_48)); + test_vector(vector_64,sizeof(vector_64)); + exit(0); +} +#endif diff --git a/crypto/openssl/crypto/modes/modes.h b/crypto/openssl/crypto/modes/modes.h new file mode 100644 index 0000000000..af8d97d795 --- /dev/null +++ b/crypto/openssl/crypto/modes/modes.h @@ -0,0 +1,59 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include + +typedef void (*block128_f)(const unsigned char in[16], + unsigned char out[16], + const void *key); + +typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, block128_f block); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); diff --git a/crypto/openssl/crypto/o_init.c b/crypto/openssl/crypto/modes/ofb128.c similarity index 58% rename from crypto/openssl/crypto/o_init.c rename to crypto/openssl/crypto/modes/ofb128.c index 2a5f5aac76..c732e2ec58 100644 --- a/crypto/openssl/crypto/o_init.c +++ b/crypto/openssl/crypto/modes/ofb128.c @@ -1,9 +1,5 @@ -/* o_init.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ /* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 2008 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 @@ -50,42 +46,83 @@ * 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 -#include -/* Internal only functions: only ever used here */ -extern void int_ERR_lib_init(void); -extern void int_EVP_MD_init_engine_callbacks(void ); -extern void int_EVP_CIPHER_init_engine_callbacks(void ); -extern void int_RAND_init_engine_callbacks(void ); +#include "modes.h" +#include -/* Perform any essential OpenSSL initialization operations. - * Currently only sets FIPS callbacks - */ +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include -void OPENSSL_init(void) - { -#ifdef OPENSSL_FIPS - static int done = 0; - if (!done) - { - int_ERR_lib_init(); -#ifdef CRYPTO_MDEBUG - CRYPTO_malloc_debug_init(); +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT #endif -#ifndef OPENSSL_NO_ENGINE - int_EVP_MD_init_engine_callbacks(); - int_EVP_CIPHER_init_engine_callbacks(); - int_RAND_init_engine_callbacks(); + +/* The input and output encrypted as though 128bit ofb mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num; + */ +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block) +{ + unsigned int n; + size_t l=0; + + assert(in && out && key && ivec && num); + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16%sizeof(size_t) == 0) do { /* always true actually */ + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n+1) % 16; + } +#if defined(STRICT_ALIGNMENT) + if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) + break; #endif - done = 1; + while (len>=16) { + (*block)(ivec, ivec, key); + for (; n<16; n+=sizeof(size_t)) + *(size_t*)(out+n) = + *(size_t*)(in+n) ^ *(size_t*)(ivec+n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + out[n] = in[n] ^ ivec[n]; + ++n; + } } + *num = n; + return; + } while(0); + /* the rest would be commonly eliminated by x86* compiler */ #endif + while (ltm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + /* Adjust day seconds if overflow */ + if (offset_hms >= SECS_PER_DAY) + { + offset_day++; + offset_hms -= SECS_PER_DAY; + } + else if (offset_hms < 0) + { + offset_day--; + offset_hms += SECS_PER_DAY; + } + + /* Convert date of time structure into a Julian day number. + */ + + time_year = tm->tm_year + 1900; + time_month = tm->tm_mon + 1; + time_day = tm->tm_mday; + + time_jd = date_to_julian(time_year, time_month, time_day); + + /* Work out Julian day of new date */ + time_jd += offset_day; + + if (time_jd < 0) + return 0; + + /* Convert Julian day back to date */ + + julian_to_date(time_jd, &time_year, &time_month, &time_day); + + if (time_year < 1900 || time_year > 9999) + return 0; + + /* Update tm structure */ + + tm->tm_year = time_year - 1900; + tm->tm_mon = time_month - 1; + tm->tm_mday = time_day; + + tm->tm_hour = offset_hms / 3600; + tm->tm_min = (offset_hms / 60) % 60; + tm->tm_sec = offset_hms % 60; + + return 1; + +} + +/* Convert date to and from julian day + * Uses Fliegel & Van Flandern algorithm + */ +static long date_to_julian(int y, int m, int d) +{ + return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + + (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - + (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + + d - 32075; +} + +static void julian_to_date(long jd, int *y, int *m, int *d) + { + long L = jd + 68569; + long n = (4 * L) / 146097; + long i, j; + + L = L - (146097 * n + 3) / 4; + i = (4000 * (L + 1)) / 1461001; + L = L - (1461 * i) / 4 + 31; + j = (80 * L) / 2447; + *d = L - (2447 * j) / 80; + L = j / 11; + *m = j + 2 - (12 * L); + *y = 100 * (n - 49) + i + L; + } + +#ifdef OPENSSL_TIME_TEST + +#include + +/* Time checking test code. Check times are identical for a wide range of + * offsets. This should be run on a machine with 64 bit time_t or it will + * trigger the very errors the routines fix. + */ + +int main(int argc, char **argv) + { + long offset; + for (offset = 0; offset < 1000000; offset++) + { + check_time(offset); + check_time(-offset); + check_time(offset * 1000); + check_time(-offset * 1000); + } + } + +int check_time(long offset) + { + struct tm tm1, tm2; + time_t t1, t2; + time(&t1); + t2 = t1 + offset; + OPENSSL_gmtime(&t2, &tm2); + OPENSSL_gmtime(&t1, &tm1); + OPENSSL_gmtime_adj(&tm1, 0, offset); + if ((tm1.tm_year == tm2.tm_year) && + (tm1.tm_mon == tm2.tm_mon) && + (tm1.tm_mday == tm2.tm_mday) && + (tm1.tm_hour == tm2.tm_hour) && + (tm1.tm_min == tm2.tm_min) && + (tm1.tm_sec == tm2.tm_sec)) + return 1; + fprintf(stderr, "TIME ERROR!!\n"); + fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n", + tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900, + tm2.tm_hour, tm2.tm_min, tm2.tm_sec); + fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n", + tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900, + tm1.tm_hour, tm1.tm_min, tm1.tm_sec); + return 0; + } + +#endif diff --git a/crypto/openssl/crypto/o_time.h b/crypto/openssl/crypto/o_time.h index e66044626d..e391da7508 100644 --- a/crypto/openssl/crypto/o_time.h +++ b/crypto/openssl/crypto/o_time.h @@ -62,5 +62,6 @@ #include struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); #endif diff --git a/crypto/openssl/crypto/objects/o_names.c b/crypto/openssl/crypto/objects/o_names.c index adb5731f76..84380a96a9 100644 --- a/crypto/openssl/crypto/objects/o_names.c +++ b/crypto/openssl/crypto/objects/o_names.c @@ -22,7 +22,8 @@ /* I use the ex_data stuff to manage the identifiers for the obj_name_types * that applications may define. I only really use the free function field. */ -static LHASH *names_lh=NULL; +DECLARE_LHASH_OF(OBJ_NAME); +static LHASH_OF(OBJ_NAME) *names_lh=NULL; static int names_type_num=OBJ_NAME_TYPE_NUM; typedef struct name_funcs_st @@ -46,11 +47,14 @@ static unsigned long obj_name_hash(const void *a_void); /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ static int obj_name_cmp(const void *a_void,const void *b_void); +static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) +static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) + int OBJ_NAME_init(void) { if (names_lh != NULL) return(1); MemCheck_off(); - names_lh=lh_new(obj_name_hash, obj_name_cmp); + names_lh=lh_OBJ_NAME_new(); MemCheck_on(); return(names_lh != NULL); } @@ -164,7 +168,7 @@ const char *OBJ_NAME_get(const char *name, int type) for (;;) { - ret=(OBJ_NAME *)lh_retrieve(names_lh,&on); + ret=lh_OBJ_NAME_retrieve(names_lh,&on); if (ret == NULL) return(NULL); if ((ret->alias) && !alias) { @@ -200,7 +204,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data) onp->type=type; onp->data=data; - ret=(OBJ_NAME *)lh_insert(names_lh,onp); + ret=lh_OBJ_NAME_insert(names_lh,onp); if (ret != NULL) { /* free things */ @@ -217,7 +221,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data) } else { - if (lh_error(names_lh)) + if (lh_OBJ_NAME_error(names_lh)) { /* ERROR */ return(0); @@ -235,7 +239,7 @@ int OBJ_NAME_remove(const char *name, int type) type&= ~OBJ_NAME_ALIAS; on.name=name; on.type=type; - ret=(OBJ_NAME *)lh_delete(names_lh,&on); + ret=lh_OBJ_NAME_delete(names_lh,&on); if (ret != NULL) { /* free things */ @@ -262,13 +266,13 @@ struct doall void *arg; }; -static void do_all_fn(const OBJ_NAME *name,struct doall *d) +static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d) { if(name->type == d->type) d->fn(name,d->arg); } -static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *) +static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg) { @@ -278,7 +282,8 @@ void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg) d.fn=fn; d.arg=arg; - lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d); + lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), + struct doall, &d); } struct doall_sorted @@ -313,7 +318,7 @@ void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg), int n; d.type=type; - d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names); + d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names); d.n=0; OBJ_NAME_do_all(type,do_all_sorted_fn,&d); @@ -327,18 +332,16 @@ void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg), static int free_type; -static void names_lh_free(OBJ_NAME *onp) -{ - if(onp == NULL) +static void names_lh_free_doall(OBJ_NAME *onp) + { + if (onp == NULL) return; - if ((free_type < 0) || (free_type == onp->type)) - { + if (free_type < 0 || free_type == onp->type) OBJ_NAME_remove(onp->name,onp->type); - } } -static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *) +static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) static void name_funcs_free(NAME_FUNCS *ptr) { @@ -352,18 +355,18 @@ void OBJ_NAME_cleanup(int type) if (names_lh == NULL) return; free_type=type; - down_load=names_lh->down_load; - names_lh->down_load=0; + down_load=lh_OBJ_NAME_down_load(names_lh); + lh_OBJ_NAME_down_load(names_lh)=0; - lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); + lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); if (type < 0) { - lh_free(names_lh); + lh_OBJ_NAME_free(names_lh); sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free); names_lh=NULL; name_funcs_stack = NULL; } else - names_lh->down_load=down_load; + lh_OBJ_NAME_down_load(names_lh)=down_load; } diff --git a/crypto/openssl/crypto/objects/obj_dat.c b/crypto/openssl/crypto/objects/obj_dat.c index 760af16dd9..8a342ba3eb 100644 --- a/crypto/openssl/crypto/objects/obj_dat.c +++ b/crypto/openssl/crypto/objects/obj_dat.c @@ -74,16 +74,17 @@ #define NUM_SN 0 #define NUM_LN 0 #define NUM_OBJ 0 -static unsigned char lvalues[1]; -static ASN1_OBJECT nid_objs[1]; -static ASN1_OBJECT *sn_objs[1]; -static ASN1_OBJECT *ln_objs[1]; -static ASN1_OBJECT *obj_objs[1]; +static const unsigned char lvalues[1]; +static const ASN1_OBJECT nid_objs[1]; +static const unsigned int sn_objs[1]; +static const unsigned int ln_objs[1]; +static const unsigned int obj_objs[1]; #endif -static int sn_cmp(const void *a, const void *b); -static int ln_cmp(const void *a, const void *b); -static int obj_cmp(const void *a, const void *b); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); + #define ADDED_DATA 0 #define ADDED_SNAME 1 #define ADDED_LNAME 2 @@ -94,30 +95,27 @@ typedef struct added_obj_st int type; ASN1_OBJECT *obj; } ADDED_OBJ; +DECLARE_LHASH_OF(ADDED_OBJ); static int new_nid=NUM_NID; -static LHASH *added=NULL; +static LHASH_OF(ADDED_OBJ) *added=NULL; -static int sn_cmp(const void *a, const void *b) - { - const ASN1_OBJECT * const *ap = a, * const *bp = b; - return(strcmp((*ap)->sn,(*bp)->sn)); - } +static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b) + { return(strcmp((*a)->sn,nid_objs[*b].sn)); } -static int ln_cmp(const void *a, const void *b) - { - const ASN1_OBJECT * const *ap = a, * const *bp = b; - return(strcmp((*ap)->ln,(*bp)->ln)); - } +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); -/* static unsigned long add_hash(ADDED_OBJ *ca) */ -static unsigned long add_hash(const void *ca_void) +static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b) + { return(strcmp((*a)->ln,nid_objs[*b].ln)); } + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); + +static unsigned long added_obj_hash(const ADDED_OBJ *ca) { const ASN1_OBJECT *a; int i; unsigned long ret=0; unsigned char *p; - const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; a=ca->obj; switch (ca->type) @@ -145,14 +143,12 @@ static unsigned long add_hash(const void *ca_void) ret|=ca->type<<30L; return(ret); } +static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) -/* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */ -static int add_cmp(const void *ca_void, const void *cb_void) +static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) { ASN1_OBJECT *a,*b; int i; - const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; - const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void; i=ca->type-cb->type; if (i) return(i); @@ -179,15 +175,16 @@ static int add_cmp(const void *ca_void, const void *cb_void) return 0; } } +static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) static int init_added(void) { if (added != NULL) return(1); - added=lh_new(add_hash,add_cmp); + added=lh_ADDED_OBJ_new(); return(added != NULL); } -static void cleanup1(ADDED_OBJ *a) +static void cleanup1_doall(ADDED_OBJ *a) { a->obj->nid=0; a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC| @@ -195,28 +192,46 @@ static void cleanup1(ADDED_OBJ *a) ASN1_OBJECT_FLAG_DYNAMIC_DATA; } -static void cleanup2(ADDED_OBJ *a) +static void cleanup2_doall(ADDED_OBJ *a) { a->obj->nid++; } -static void cleanup3(ADDED_OBJ *a) +static void cleanup3_doall(ADDED_OBJ *a) { if (--a->obj->nid == 0) ASN1_OBJECT_free(a->obj); OPENSSL_free(a); } -static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *) -static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *) -static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *) +static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) + +/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting + * to use freed up OIDs. If neccessary the actual freeing up of OIDs is + * delayed. + */ + +int obj_cleanup_defer = 0; + +void check_defer(int nid) + { + if (!obj_cleanup_defer && nid >= NUM_NID) + obj_cleanup_defer = 1; + } void OBJ_cleanup(void) { + if (obj_cleanup_defer) + { + obj_cleanup_defer = 2; + return ; + } if (added == NULL) return; - added->down_load=0; - lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ - lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ - lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ - lh_free(added); + lh_ADDED_OBJ_down_load(added) = 0; + lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ + lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ + lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ + lh_ADDED_OBJ_free(added); added=NULL; } @@ -252,7 +267,7 @@ int OBJ_add_object(const ASN1_OBJECT *obj) { ao[i]->type=i; ao[i]->obj=o; - aop=(ADDED_OBJ *)lh_insert(added,ao[i]); + aop=lh_ADDED_OBJ_insert(added,ao[i]); /* memory leak, buit should not normally matter */ if (aop != NULL) OPENSSL_free(aop); @@ -292,7 +307,7 @@ ASN1_OBJECT *OBJ_nid2obj(int n) ad.type=ADDED_NID; ad.obj= &ob; ob.nid=n; - adp=(ADDED_OBJ *)lh_retrieve(added,&ad); + adp=lh_ADDED_OBJ_retrieve(added,&ad); if (adp != NULL) return(adp->obj); else @@ -324,7 +339,7 @@ const char *OBJ_nid2sn(int n) ad.type=ADDED_NID; ad.obj= &ob; ob.nid=n; - adp=(ADDED_OBJ *)lh_retrieve(added,&ad); + adp=lh_ADDED_OBJ_retrieve(added,&ad); if (adp != NULL) return(adp->obj->sn); else @@ -356,7 +371,7 @@ const char *OBJ_nid2ln(int n) ad.type=ADDED_NID; ad.obj= &ob; ob.nid=n; - adp=(ADDED_OBJ *)lh_retrieve(added,&ad); + adp=lh_ADDED_OBJ_retrieve(added,&ad); if (adp != NULL) return(adp->obj->ln); else @@ -367,9 +382,22 @@ const char *OBJ_nid2ln(int n) } } +static int obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp) + { + int j; + const ASN1_OBJECT *a= *ap; + const ASN1_OBJECT *b= &nid_objs[*bp]; + + j=(a->length - b->length); + if (j) return(j); + return(memcmp(a->data,b->data,a->length)); + } + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); + int OBJ_obj2nid(const ASN1_OBJECT *a) { - ASN1_OBJECT **op; + const unsigned int *op; ADDED_OBJ ad,*adp; if (a == NULL) @@ -381,14 +409,13 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) { ad.type=ADDED_DATA; ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */ - adp=(ADDED_OBJ *)lh_retrieve(added,&ad); + adp=lh_ADDED_OBJ_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } - op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs, - NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp); + op=OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); if (op == NULL) return(NID_undef); - return((*op)->nid); + return(nid_objs[*op].nid); } /* Convert an object name into an ASN1_OBJECT @@ -441,7 +468,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) int i,n=0,len,nid, first, use_bn; BIGNUM *bl; unsigned long l; - unsigned char *p; + const unsigned char *p; char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; if ((a == NULL) || (a->data == NULL)) { @@ -610,62 +637,56 @@ int OBJ_txt2nid(const char *s) int OBJ_ln2nid(const char *s) { - ASN1_OBJECT o,*oo= &o,**op; + ASN1_OBJECT o; + const ASN1_OBJECT *oo= &o; ADDED_OBJ ad,*adp; + const unsigned int *op; o.ln=s; if (added != NULL) { ad.type=ADDED_LNAME; ad.obj= &o; - adp=(ADDED_OBJ *)lh_retrieve(added,&ad); + adp=lh_ADDED_OBJ_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } - op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN, - sizeof(ASN1_OBJECT *),ln_cmp); + op=OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); if (op == NULL) return(NID_undef); - return((*op)->nid); + return(nid_objs[*op].nid); } int OBJ_sn2nid(const char *s) { - ASN1_OBJECT o,*oo= &o,**op; + ASN1_OBJECT o; + const ASN1_OBJECT *oo= &o; ADDED_OBJ ad,*adp; + const unsigned int *op; o.sn=s; if (added != NULL) { ad.type=ADDED_SNAME; ad.obj= &o; - adp=(ADDED_OBJ *)lh_retrieve(added,&ad); + adp=lh_ADDED_OBJ_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } - op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN, - sizeof(ASN1_OBJECT *),sn_cmp); + op=OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); if (op == NULL) return(NID_undef); - return((*op)->nid); + return(nid_objs[*op].nid); } -static int obj_cmp(const void *ap, const void *bp) - { - int j; - const ASN1_OBJECT *a= *(ASN1_OBJECT * const *)ap; - const ASN1_OBJECT *b= *(ASN1_OBJECT * const *)bp; - - j=(a->length - b->length); - if (j) return(j); - return(memcmp(a->data,b->data,a->length)); - } - -const char *OBJ_bsearch(const char *key, const char *base, int num, int size, - int (*cmp)(const void *, const void *)) +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp)(const void *, const void *)) { - return OBJ_bsearch_ex(key, base, num, size, cmp, 0); + return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); } -const char *OBJ_bsearch_ex(const char *key, const char *base, int num, - int size, int (*cmp)(const void *, const void *), int flags) +const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, + int size, + int (*cmp)(const void *, const void *), + int flags) { + const char *base=base_; int l,h,i=0,c=0; const char *p = NULL; diff --git a/crypto/openssl/crypto/objects/obj_dat.h b/crypto/openssl/crypto/objects/obj_dat.h index 23bdb4603a..6449be6071 100644 --- a/crypto/openssl/crypto/objects/obj_dat.h +++ b/crypto/openssl/crypto/objects/obj_dat.h @@ -67,7 +67,7 @@ #define NUM_LN 886 #define NUM_OBJ 840 -static unsigned char lvalues[5824]={ +static const unsigned char lvalues[5824]={ 0x00, /* [ 0] OBJ_undef */ 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */ @@ -910,7 +910,7 @@ static unsigned char lvalues[5824]={ 0x55,0x04,0x36, /* [5820] OBJ_dmdName */ }; -static ASN1_OBJECT nid_objs[NUM_NID]={ +static const ASN1_OBJECT nid_objs[NUM_NID]={ {"UNDEF","undefined",NID_undef,1,&(lvalues[0]),0}, {"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[1]),0}, {"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[7]),0}, @@ -2353,2624 +2353,2624 @@ static ASN1_OBJECT nid_objs[NUM_NID]={ {"dmdName","dmdName",NID_dmdName,3,&(lvalues[5820]),0}, }; -static ASN1_OBJECT *sn_objs[NUM_SN]={ -&(nid_objs[364]),/* "AD_DVCS" */ -&(nid_objs[419]),/* "AES-128-CBC" */ -&(nid_objs[421]),/* "AES-128-CFB" */ -&(nid_objs[650]),/* "AES-128-CFB1" */ -&(nid_objs[653]),/* "AES-128-CFB8" */ -&(nid_objs[418]),/* "AES-128-ECB" */ -&(nid_objs[420]),/* "AES-128-OFB" */ -&(nid_objs[423]),/* "AES-192-CBC" */ -&(nid_objs[425]),/* "AES-192-CFB" */ -&(nid_objs[651]),/* "AES-192-CFB1" */ -&(nid_objs[654]),/* "AES-192-CFB8" */ -&(nid_objs[422]),/* "AES-192-ECB" */ -&(nid_objs[424]),/* "AES-192-OFB" */ -&(nid_objs[427]),/* "AES-256-CBC" */ -&(nid_objs[429]),/* "AES-256-CFB" */ -&(nid_objs[652]),/* "AES-256-CFB1" */ -&(nid_objs[655]),/* "AES-256-CFB8" */ -&(nid_objs[426]),/* "AES-256-ECB" */ -&(nid_objs[428]),/* "AES-256-OFB" */ -&(nid_objs[91]),/* "BF-CBC" */ -&(nid_objs[93]),/* "BF-CFB" */ -&(nid_objs[92]),/* "BF-ECB" */ -&(nid_objs[94]),/* "BF-OFB" */ -&(nid_objs[14]),/* "C" */ -&(nid_objs[751]),/* "CAMELLIA-128-CBC" */ -&(nid_objs[757]),/* "CAMELLIA-128-CFB" */ -&(nid_objs[760]),/* "CAMELLIA-128-CFB1" */ -&(nid_objs[763]),/* "CAMELLIA-128-CFB8" */ -&(nid_objs[754]),/* "CAMELLIA-128-ECB" */ -&(nid_objs[766]),/* "CAMELLIA-128-OFB" */ -&(nid_objs[752]),/* "CAMELLIA-192-CBC" */ -&(nid_objs[758]),/* "CAMELLIA-192-CFB" */ -&(nid_objs[761]),/* "CAMELLIA-192-CFB1" */ -&(nid_objs[764]),/* "CAMELLIA-192-CFB8" */ -&(nid_objs[755]),/* "CAMELLIA-192-ECB" */ -&(nid_objs[767]),/* "CAMELLIA-192-OFB" */ -&(nid_objs[753]),/* "CAMELLIA-256-CBC" */ -&(nid_objs[759]),/* "CAMELLIA-256-CFB" */ -&(nid_objs[762]),/* "CAMELLIA-256-CFB1" */ -&(nid_objs[765]),/* "CAMELLIA-256-CFB8" */ -&(nid_objs[756]),/* "CAMELLIA-256-ECB" */ -&(nid_objs[768]),/* "CAMELLIA-256-OFB" */ -&(nid_objs[108]),/* "CAST5-CBC" */ -&(nid_objs[110]),/* "CAST5-CFB" */ -&(nid_objs[109]),/* "CAST5-ECB" */ -&(nid_objs[111]),/* "CAST5-OFB" */ -&(nid_objs[13]),/* "CN" */ -&(nid_objs[141]),/* "CRLReason" */ -&(nid_objs[417]),/* "CSPName" */ -&(nid_objs[367]),/* "CrlID" */ -&(nid_objs[391]),/* "DC" */ -&(nid_objs[31]),/* "DES-CBC" */ -&(nid_objs[643]),/* "DES-CDMF" */ -&(nid_objs[30]),/* "DES-CFB" */ -&(nid_objs[656]),/* "DES-CFB1" */ -&(nid_objs[657]),/* "DES-CFB8" */ -&(nid_objs[29]),/* "DES-ECB" */ -&(nid_objs[32]),/* "DES-EDE" */ -&(nid_objs[43]),/* "DES-EDE-CBC" */ -&(nid_objs[60]),/* "DES-EDE-CFB" */ -&(nid_objs[62]),/* "DES-EDE-OFB" */ -&(nid_objs[33]),/* "DES-EDE3" */ -&(nid_objs[44]),/* "DES-EDE3-CBC" */ -&(nid_objs[61]),/* "DES-EDE3-CFB" */ -&(nid_objs[658]),/* "DES-EDE3-CFB1" */ -&(nid_objs[659]),/* "DES-EDE3-CFB8" */ -&(nid_objs[63]),/* "DES-EDE3-OFB" */ -&(nid_objs[45]),/* "DES-OFB" */ -&(nid_objs[80]),/* "DESX-CBC" */ -&(nid_objs[380]),/* "DOD" */ -&(nid_objs[116]),/* "DSA" */ -&(nid_objs[66]),/* "DSA-SHA" */ -&(nid_objs[113]),/* "DSA-SHA1" */ -&(nid_objs[70]),/* "DSA-SHA1-old" */ -&(nid_objs[67]),/* "DSA-old" */ -&(nid_objs[297]),/* "DVCS" */ -&(nid_objs[99]),/* "GN" */ -&(nid_objs[855]),/* "HMAC" */ -&(nid_objs[780]),/* "HMAC-MD5" */ -&(nid_objs[781]),/* "HMAC-SHA1" */ -&(nid_objs[381]),/* "IANA" */ -&(nid_objs[34]),/* "IDEA-CBC" */ -&(nid_objs[35]),/* "IDEA-CFB" */ -&(nid_objs[36]),/* "IDEA-ECB" */ -&(nid_objs[46]),/* "IDEA-OFB" */ -&(nid_objs[181]),/* "ISO" */ -&(nid_objs[183]),/* "ISO-US" */ -&(nid_objs[645]),/* "ITU-T" */ -&(nid_objs[646]),/* "JOINT-ISO-ITU-T" */ -&(nid_objs[773]),/* "KISA" */ -&(nid_objs[15]),/* "L" */ -&(nid_objs[856]),/* "LocalKeySet" */ -&(nid_objs[ 3]),/* "MD2" */ -&(nid_objs[257]),/* "MD4" */ -&(nid_objs[ 4]),/* "MD5" */ -&(nid_objs[114]),/* "MD5-SHA1" */ -&(nid_objs[95]),/* "MDC2" */ -&(nid_objs[388]),/* "Mail" */ -&(nid_objs[393]),/* "NULL" */ -&(nid_objs[404]),/* "NULL" */ -&(nid_objs[57]),/* "Netscape" */ -&(nid_objs[366]),/* "Nonce" */ -&(nid_objs[17]),/* "O" */ -&(nid_objs[178]),/* "OCSP" */ -&(nid_objs[180]),/* "OCSPSigning" */ -&(nid_objs[379]),/* "ORG" */ -&(nid_objs[18]),/* "OU" */ -&(nid_objs[749]),/* "Oakley-EC2N-3" */ -&(nid_objs[750]),/* "Oakley-EC2N-4" */ -&(nid_objs[ 9]),/* "PBE-MD2-DES" */ -&(nid_objs[168]),/* "PBE-MD2-RC2-64" */ -&(nid_objs[10]),/* "PBE-MD5-DES" */ -&(nid_objs[169]),/* "PBE-MD5-RC2-64" */ -&(nid_objs[147]),/* "PBE-SHA1-2DES" */ -&(nid_objs[146]),/* "PBE-SHA1-3DES" */ -&(nid_objs[170]),/* "PBE-SHA1-DES" */ -&(nid_objs[148]),/* "PBE-SHA1-RC2-128" */ -&(nid_objs[149]),/* "PBE-SHA1-RC2-40" */ -&(nid_objs[68]),/* "PBE-SHA1-RC2-64" */ -&(nid_objs[144]),/* "PBE-SHA1-RC4-128" */ -&(nid_objs[145]),/* "PBE-SHA1-RC4-40" */ -&(nid_objs[161]),/* "PBES2" */ -&(nid_objs[69]),/* "PBKDF2" */ -&(nid_objs[162]),/* "PBMAC1" */ -&(nid_objs[127]),/* "PKIX" */ -&(nid_objs[98]),/* "RC2-40-CBC" */ -&(nid_objs[166]),/* "RC2-64-CBC" */ -&(nid_objs[37]),/* "RC2-CBC" */ -&(nid_objs[39]),/* "RC2-CFB" */ -&(nid_objs[38]),/* "RC2-ECB" */ -&(nid_objs[40]),/* "RC2-OFB" */ -&(nid_objs[ 5]),/* "RC4" */ -&(nid_objs[97]),/* "RC4-40" */ -&(nid_objs[120]),/* "RC5-CBC" */ -&(nid_objs[122]),/* "RC5-CFB" */ -&(nid_objs[121]),/* "RC5-ECB" */ -&(nid_objs[123]),/* "RC5-OFB" */ -&(nid_objs[117]),/* "RIPEMD160" */ -&(nid_objs[124]),/* "RLE" */ -&(nid_objs[19]),/* "RSA" */ -&(nid_objs[ 7]),/* "RSA-MD2" */ -&(nid_objs[396]),/* "RSA-MD4" */ -&(nid_objs[ 8]),/* "RSA-MD5" */ -&(nid_objs[96]),/* "RSA-MDC2" */ -&(nid_objs[104]),/* "RSA-NP-MD5" */ -&(nid_objs[119]),/* "RSA-RIPEMD160" */ -&(nid_objs[42]),/* "RSA-SHA" */ -&(nid_objs[65]),/* "RSA-SHA1" */ -&(nid_objs[115]),/* "RSA-SHA1-2" */ -&(nid_objs[671]),/* "RSA-SHA224" */ -&(nid_objs[668]),/* "RSA-SHA256" */ -&(nid_objs[669]),/* "RSA-SHA384" */ -&(nid_objs[670]),/* "RSA-SHA512" */ -&(nid_objs[777]),/* "SEED-CBC" */ -&(nid_objs[779]),/* "SEED-CFB" */ -&(nid_objs[776]),/* "SEED-ECB" */ -&(nid_objs[778]),/* "SEED-OFB" */ -&(nid_objs[41]),/* "SHA" */ -&(nid_objs[64]),/* "SHA1" */ -&(nid_objs[675]),/* "SHA224" */ -&(nid_objs[672]),/* "SHA256" */ -&(nid_objs[673]),/* "SHA384" */ -&(nid_objs[674]),/* "SHA512" */ -&(nid_objs[188]),/* "SMIME" */ -&(nid_objs[167]),/* "SMIME-CAPS" */ -&(nid_objs[100]),/* "SN" */ -&(nid_objs[16]),/* "ST" */ -&(nid_objs[143]),/* "SXNetID" */ -&(nid_objs[458]),/* "UID" */ -&(nid_objs[ 0]),/* "UNDEF" */ -&(nid_objs[11]),/* "X500" */ -&(nid_objs[378]),/* "X500algorithms" */ -&(nid_objs[12]),/* "X509" */ -&(nid_objs[184]),/* "X9-57" */ -&(nid_objs[185]),/* "X9cm" */ -&(nid_objs[125]),/* "ZLIB" */ -&(nid_objs[478]),/* "aRecord" */ -&(nid_objs[289]),/* "aaControls" */ -&(nid_objs[287]),/* "ac-auditEntity" */ -&(nid_objs[397]),/* "ac-proxying" */ -&(nid_objs[288]),/* "ac-targeting" */ -&(nid_objs[368]),/* "acceptableResponses" */ -&(nid_objs[446]),/* "account" */ -&(nid_objs[363]),/* "ad_timestamping" */ -&(nid_objs[376]),/* "algorithm" */ -&(nid_objs[405]),/* "ansi-X9-62" */ -&(nid_objs[746]),/* "anyPolicy" */ -&(nid_objs[370]),/* "archiveCutoff" */ -&(nid_objs[484]),/* "associatedDomain" */ -&(nid_objs[485]),/* "associatedName" */ -&(nid_objs[501]),/* "audio" */ -&(nid_objs[177]),/* "authorityInfoAccess" */ -&(nid_objs[90]),/* "authorityKeyIdentifier" */ -&(nid_objs[882]),/* "authorityRevocationList" */ -&(nid_objs[87]),/* "basicConstraints" */ -&(nid_objs[365]),/* "basicOCSPResponse" */ -&(nid_objs[285]),/* "biometricInfo" */ -&(nid_objs[494]),/* "buildingName" */ -&(nid_objs[860]),/* "businessCategory" */ -&(nid_objs[691]),/* "c2onb191v4" */ -&(nid_objs[692]),/* "c2onb191v5" */ -&(nid_objs[697]),/* "c2onb239v4" */ -&(nid_objs[698]),/* "c2onb239v5" */ -&(nid_objs[684]),/* "c2pnb163v1" */ -&(nid_objs[685]),/* "c2pnb163v2" */ -&(nid_objs[686]),/* "c2pnb163v3" */ -&(nid_objs[687]),/* "c2pnb176v1" */ -&(nid_objs[693]),/* "c2pnb208w1" */ -&(nid_objs[699]),/* "c2pnb272w1" */ -&(nid_objs[700]),/* "c2pnb304w1" */ -&(nid_objs[702]),/* "c2pnb368w1" */ -&(nid_objs[688]),/* "c2tnb191v1" */ -&(nid_objs[689]),/* "c2tnb191v2" */ -&(nid_objs[690]),/* "c2tnb191v3" */ -&(nid_objs[694]),/* "c2tnb239v1" */ -&(nid_objs[695]),/* "c2tnb239v2" */ -&(nid_objs[696]),/* "c2tnb239v3" */ -&(nid_objs[701]),/* "c2tnb359v1" */ -&(nid_objs[703]),/* "c2tnb431r1" */ -&(nid_objs[881]),/* "cACertificate" */ -&(nid_objs[483]),/* "cNAMERecord" */ -&(nid_objs[179]),/* "caIssuers" */ -&(nid_objs[785]),/* "caRepository" */ -&(nid_objs[443]),/* "caseIgnoreIA5StringSyntax" */ -&(nid_objs[152]),/* "certBag" */ -&(nid_objs[677]),/* "certicom-arc" */ -&(nid_objs[771]),/* "certificateIssuer" */ -&(nid_objs[89]),/* "certificatePolicies" */ -&(nid_objs[883]),/* "certificateRevocationList" */ -&(nid_objs[54]),/* "challengePassword" */ -&(nid_objs[407]),/* "characteristic-two-field" */ -&(nid_objs[395]),/* "clearance" */ -&(nid_objs[130]),/* "clientAuth" */ -&(nid_objs[131]),/* "codeSigning" */ -&(nid_objs[50]),/* "contentType" */ -&(nid_objs[53]),/* "countersignature" */ -&(nid_objs[153]),/* "crlBag" */ -&(nid_objs[103]),/* "crlDistributionPoints" */ -&(nid_objs[88]),/* "crlNumber" */ -&(nid_objs[884]),/* "crossCertificatePair" */ -&(nid_objs[806]),/* "cryptocom" */ -&(nid_objs[805]),/* "cryptopro" */ -&(nid_objs[500]),/* "dITRedirect" */ -&(nid_objs[451]),/* "dNSDomain" */ -&(nid_objs[495]),/* "dSAQuality" */ -&(nid_objs[434]),/* "data" */ -&(nid_objs[390]),/* "dcobject" */ -&(nid_objs[140]),/* "deltaCRL" */ -&(nid_objs[891]),/* "deltaRevocationList" */ -&(nid_objs[107]),/* "description" */ -&(nid_objs[871]),/* "destinationIndicator" */ -&(nid_objs[28]),/* "dhKeyAgreement" */ -&(nid_objs[382]),/* "directory" */ -&(nid_objs[887]),/* "distinguishedName" */ -&(nid_objs[892]),/* "dmdName" */ -&(nid_objs[174]),/* "dnQualifier" */ -&(nid_objs[447]),/* "document" */ -&(nid_objs[471]),/* "documentAuthor" */ -&(nid_objs[468]),/* "documentIdentifier" */ -&(nid_objs[472]),/* "documentLocation" */ -&(nid_objs[502]),/* "documentPublisher" */ -&(nid_objs[449]),/* "documentSeries" */ -&(nid_objs[469]),/* "documentTitle" */ -&(nid_objs[470]),/* "documentVersion" */ -&(nid_objs[392]),/* "domain" */ -&(nid_objs[452]),/* "domainRelatedObject" */ -&(nid_objs[802]),/* "dsa_with_SHA224" */ -&(nid_objs[803]),/* "dsa_with_SHA256" */ -&(nid_objs[791]),/* "ecdsa-with-Recommended" */ -&(nid_objs[416]),/* "ecdsa-with-SHA1" */ -&(nid_objs[793]),/* "ecdsa-with-SHA224" */ -&(nid_objs[794]),/* "ecdsa-with-SHA256" */ -&(nid_objs[795]),/* "ecdsa-with-SHA384" */ -&(nid_objs[796]),/* "ecdsa-with-SHA512" */ -&(nid_objs[792]),/* "ecdsa-with-Specified" */ -&(nid_objs[48]),/* "emailAddress" */ -&(nid_objs[132]),/* "emailProtection" */ -&(nid_objs[885]),/* "enhancedSearchGuide" */ -&(nid_objs[389]),/* "enterprises" */ -&(nid_objs[384]),/* "experimental" */ -&(nid_objs[172]),/* "extReq" */ -&(nid_objs[56]),/* "extendedCertificateAttributes" */ -&(nid_objs[126]),/* "extendedKeyUsage" */ -&(nid_objs[372]),/* "extendedStatus" */ -&(nid_objs[867]),/* "facsimileTelephoneNumber" */ -&(nid_objs[462]),/* "favouriteDrink" */ -&(nid_objs[857]),/* "freshestCRL" */ -&(nid_objs[453]),/* "friendlyCountry" */ -&(nid_objs[490]),/* "friendlyCountryName" */ -&(nid_objs[156]),/* "friendlyName" */ -&(nid_objs[509]),/* "generationQualifier" */ -&(nid_objs[815]),/* "gost-mac" */ -&(nid_objs[811]),/* "gost2001" */ -&(nid_objs[851]),/* "gost2001cc" */ -&(nid_objs[813]),/* "gost89" */ -&(nid_objs[814]),/* "gost89-cnt" */ -&(nid_objs[812]),/* "gost94" */ -&(nid_objs[850]),/* "gost94cc" */ -&(nid_objs[797]),/* "hmacWithMD5" */ -&(nid_objs[163]),/* "hmacWithSHA1" */ -&(nid_objs[798]),/* "hmacWithSHA224" */ -&(nid_objs[799]),/* "hmacWithSHA256" */ -&(nid_objs[800]),/* "hmacWithSHA384" */ -&(nid_objs[801]),/* "hmacWithSHA512" */ -&(nid_objs[432]),/* "holdInstructionCallIssuer" */ -&(nid_objs[430]),/* "holdInstructionCode" */ -&(nid_objs[431]),/* "holdInstructionNone" */ -&(nid_objs[433]),/* "holdInstructionReject" */ -&(nid_objs[486]),/* "homePostalAddress" */ -&(nid_objs[473]),/* "homeTelephoneNumber" */ -&(nid_objs[466]),/* "host" */ -&(nid_objs[889]),/* "houseIdentifier" */ -&(nid_objs[442]),/* "iA5StringSyntax" */ -&(nid_objs[783]),/* "id-DHBasedMac" */ -&(nid_objs[824]),/* "id-Gost28147-89-CryptoPro-A-ParamSet" */ -&(nid_objs[825]),/* "id-Gost28147-89-CryptoPro-B-ParamSet" */ -&(nid_objs[826]),/* "id-Gost28147-89-CryptoPro-C-ParamSet" */ -&(nid_objs[827]),/* "id-Gost28147-89-CryptoPro-D-ParamSet" */ -&(nid_objs[819]),/* "id-Gost28147-89-CryptoPro-KeyMeshing" */ -&(nid_objs[829]),/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ -&(nid_objs[828]),/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ -&(nid_objs[830]),/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ -&(nid_objs[820]),/* "id-Gost28147-89-None-KeyMeshing" */ -&(nid_objs[823]),/* "id-Gost28147-89-TestParamSet" */ -&(nid_objs[849]),/* "id-Gost28147-89-cc" */ -&(nid_objs[840]),/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ -&(nid_objs[841]),/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ -&(nid_objs[842]),/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ -&(nid_objs[843]),/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ -&(nid_objs[844]),/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ -&(nid_objs[854]),/* "id-GostR3410-2001-ParamSet-cc" */ -&(nid_objs[839]),/* "id-GostR3410-2001-TestParamSet" */ -&(nid_objs[817]),/* "id-GostR3410-2001DH" */ -&(nid_objs[832]),/* "id-GostR3410-94-CryptoPro-A-ParamSet" */ -&(nid_objs[833]),/* "id-GostR3410-94-CryptoPro-B-ParamSet" */ -&(nid_objs[834]),/* "id-GostR3410-94-CryptoPro-C-ParamSet" */ -&(nid_objs[835]),/* "id-GostR3410-94-CryptoPro-D-ParamSet" */ -&(nid_objs[836]),/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ -&(nid_objs[837]),/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ -&(nid_objs[838]),/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ -&(nid_objs[831]),/* "id-GostR3410-94-TestParamSet" */ -&(nid_objs[845]),/* "id-GostR3410-94-a" */ -&(nid_objs[846]),/* "id-GostR3410-94-aBis" */ -&(nid_objs[847]),/* "id-GostR3410-94-b" */ -&(nid_objs[848]),/* "id-GostR3410-94-bBis" */ -&(nid_objs[818]),/* "id-GostR3410-94DH" */ -&(nid_objs[822]),/* "id-GostR3411-94-CryptoProParamSet" */ -&(nid_objs[821]),/* "id-GostR3411-94-TestParamSet" */ -&(nid_objs[807]),/* "id-GostR3411-94-with-GostR3410-2001" */ -&(nid_objs[853]),/* "id-GostR3411-94-with-GostR3410-2001-cc" */ -&(nid_objs[808]),/* "id-GostR3411-94-with-GostR3410-94" */ -&(nid_objs[852]),/* "id-GostR3411-94-with-GostR3410-94-cc" */ -&(nid_objs[810]),/* "id-HMACGostR3411-94" */ -&(nid_objs[782]),/* "id-PasswordBasedMAC" */ -&(nid_objs[266]),/* "id-aca" */ -&(nid_objs[355]),/* "id-aca-accessIdentity" */ -&(nid_objs[354]),/* "id-aca-authenticationInfo" */ -&(nid_objs[356]),/* "id-aca-chargingIdentity" */ -&(nid_objs[399]),/* "id-aca-encAttrs" */ -&(nid_objs[357]),/* "id-aca-group" */ -&(nid_objs[358]),/* "id-aca-role" */ -&(nid_objs[176]),/* "id-ad" */ -&(nid_objs[788]),/* "id-aes128-wrap" */ -&(nid_objs[789]),/* "id-aes192-wrap" */ -&(nid_objs[790]),/* "id-aes256-wrap" */ -&(nid_objs[262]),/* "id-alg" */ -&(nid_objs[323]),/* "id-alg-des40" */ -&(nid_objs[326]),/* "id-alg-dh-pop" */ -&(nid_objs[325]),/* "id-alg-dh-sig-hmac-sha1" */ -&(nid_objs[324]),/* "id-alg-noSignature" */ -&(nid_objs[268]),/* "id-cct" */ -&(nid_objs[361]),/* "id-cct-PKIData" */ -&(nid_objs[362]),/* "id-cct-PKIResponse" */ -&(nid_objs[360]),/* "id-cct-crs" */ -&(nid_objs[81]),/* "id-ce" */ -&(nid_objs[680]),/* "id-characteristic-two-basis" */ -&(nid_objs[263]),/* "id-cmc" */ -&(nid_objs[334]),/* "id-cmc-addExtensions" */ -&(nid_objs[346]),/* "id-cmc-confirmCertAcceptance" */ -&(nid_objs[330]),/* "id-cmc-dataReturn" */ -&(nid_objs[336]),/* "id-cmc-decryptedPOP" */ -&(nid_objs[335]),/* "id-cmc-encryptedPOP" */ -&(nid_objs[339]),/* "id-cmc-getCRL" */ -&(nid_objs[338]),/* "id-cmc-getCert" */ -&(nid_objs[328]),/* "id-cmc-identification" */ -&(nid_objs[329]),/* "id-cmc-identityProof" */ -&(nid_objs[337]),/* "id-cmc-lraPOPWitness" */ -&(nid_objs[344]),/* "id-cmc-popLinkRandom" */ -&(nid_objs[345]),/* "id-cmc-popLinkWitness" */ -&(nid_objs[343]),/* "id-cmc-queryPending" */ -&(nid_objs[333]),/* "id-cmc-recipientNonce" */ -&(nid_objs[341]),/* "id-cmc-regInfo" */ -&(nid_objs[342]),/* "id-cmc-responseInfo" */ -&(nid_objs[340]),/* "id-cmc-revokeRequest" */ -&(nid_objs[332]),/* "id-cmc-senderNonce" */ -&(nid_objs[327]),/* "id-cmc-statusInfo" */ -&(nid_objs[331]),/* "id-cmc-transactionId" */ -&(nid_objs[787]),/* "id-ct-asciiTextWithCRLF" */ -&(nid_objs[408]),/* "id-ecPublicKey" */ -&(nid_objs[508]),/* "id-hex-multipart-message" */ -&(nid_objs[507]),/* "id-hex-partial-message" */ -&(nid_objs[260]),/* "id-it" */ -&(nid_objs[302]),/* "id-it-caKeyUpdateInfo" */ -&(nid_objs[298]),/* "id-it-caProtEncCert" */ -&(nid_objs[311]),/* "id-it-confirmWaitTime" */ -&(nid_objs[303]),/* "id-it-currentCRL" */ -&(nid_objs[300]),/* "id-it-encKeyPairTypes" */ -&(nid_objs[310]),/* "id-it-implicitConfirm" */ -&(nid_objs[308]),/* "id-it-keyPairParamRep" */ -&(nid_objs[307]),/* "id-it-keyPairParamReq" */ -&(nid_objs[312]),/* "id-it-origPKIMessage" */ -&(nid_objs[301]),/* "id-it-preferredSymmAlg" */ -&(nid_objs[309]),/* "id-it-revPassphrase" */ -&(nid_objs[299]),/* "id-it-signKeyPairTypes" */ -&(nid_objs[305]),/* "id-it-subscriptionRequest" */ -&(nid_objs[306]),/* "id-it-subscriptionResponse" */ -&(nid_objs[784]),/* "id-it-suppLangTags" */ -&(nid_objs[304]),/* "id-it-unsupportedOIDs" */ -&(nid_objs[128]),/* "id-kp" */ -&(nid_objs[280]),/* "id-mod-attribute-cert" */ -&(nid_objs[274]),/* "id-mod-cmc" */ -&(nid_objs[277]),/* "id-mod-cmp" */ -&(nid_objs[284]),/* "id-mod-cmp2000" */ -&(nid_objs[273]),/* "id-mod-crmf" */ -&(nid_objs[283]),/* "id-mod-dvcs" */ -&(nid_objs[275]),/* "id-mod-kea-profile-88" */ -&(nid_objs[276]),/* "id-mod-kea-profile-93" */ -&(nid_objs[282]),/* "id-mod-ocsp" */ -&(nid_objs[278]),/* "id-mod-qualified-cert-88" */ -&(nid_objs[279]),/* "id-mod-qualified-cert-93" */ -&(nid_objs[281]),/* "id-mod-timestamp-protocol" */ -&(nid_objs[264]),/* "id-on" */ -&(nid_objs[858]),/* "id-on-permanentIdentifier" */ -&(nid_objs[347]),/* "id-on-personalData" */ -&(nid_objs[265]),/* "id-pda" */ -&(nid_objs[352]),/* "id-pda-countryOfCitizenship" */ -&(nid_objs[353]),/* "id-pda-countryOfResidence" */ -&(nid_objs[348]),/* "id-pda-dateOfBirth" */ -&(nid_objs[351]),/* "id-pda-gender" */ -&(nid_objs[349]),/* "id-pda-placeOfBirth" */ -&(nid_objs[175]),/* "id-pe" */ -&(nid_objs[261]),/* "id-pkip" */ -&(nid_objs[258]),/* "id-pkix-mod" */ -&(nid_objs[269]),/* "id-pkix1-explicit-88" */ -&(nid_objs[271]),/* "id-pkix1-explicit-93" */ -&(nid_objs[270]),/* "id-pkix1-implicit-88" */ -&(nid_objs[272]),/* "id-pkix1-implicit-93" */ -&(nid_objs[662]),/* "id-ppl" */ -&(nid_objs[664]),/* "id-ppl-anyLanguage" */ -&(nid_objs[667]),/* "id-ppl-independent" */ -&(nid_objs[665]),/* "id-ppl-inheritAll" */ -&(nid_objs[267]),/* "id-qcs" */ -&(nid_objs[359]),/* "id-qcs-pkixQCSyntax-v1" */ -&(nid_objs[259]),/* "id-qt" */ -&(nid_objs[164]),/* "id-qt-cps" */ -&(nid_objs[165]),/* "id-qt-unotice" */ -&(nid_objs[313]),/* "id-regCtrl" */ -&(nid_objs[316]),/* "id-regCtrl-authenticator" */ -&(nid_objs[319]),/* "id-regCtrl-oldCertID" */ -&(nid_objs[318]),/* "id-regCtrl-pkiArchiveOptions" */ -&(nid_objs[317]),/* "id-regCtrl-pkiPublicationInfo" */ -&(nid_objs[320]),/* "id-regCtrl-protocolEncrKey" */ -&(nid_objs[315]),/* "id-regCtrl-regToken" */ -&(nid_objs[314]),/* "id-regInfo" */ -&(nid_objs[322]),/* "id-regInfo-certReq" */ -&(nid_objs[321]),/* "id-regInfo-utf8Pairs" */ -&(nid_objs[512]),/* "id-set" */ -&(nid_objs[191]),/* "id-smime-aa" */ -&(nid_objs[215]),/* "id-smime-aa-contentHint" */ -&(nid_objs[218]),/* "id-smime-aa-contentIdentifier" */ -&(nid_objs[221]),/* "id-smime-aa-contentReference" */ -&(nid_objs[240]),/* "id-smime-aa-dvcs-dvc" */ -&(nid_objs[217]),/* "id-smime-aa-encapContentType" */ -&(nid_objs[222]),/* "id-smime-aa-encrypKeyPref" */ -&(nid_objs[220]),/* "id-smime-aa-equivalentLabels" */ -&(nid_objs[232]),/* "id-smime-aa-ets-CertificateRefs" */ -&(nid_objs[233]),/* "id-smime-aa-ets-RevocationRefs" */ -&(nid_objs[238]),/* "id-smime-aa-ets-archiveTimeStamp" */ -&(nid_objs[237]),/* "id-smime-aa-ets-certCRLTimestamp" */ -&(nid_objs[234]),/* "id-smime-aa-ets-certValues" */ -&(nid_objs[227]),/* "id-smime-aa-ets-commitmentType" */ -&(nid_objs[231]),/* "id-smime-aa-ets-contentTimestamp" */ -&(nid_objs[236]),/* "id-smime-aa-ets-escTimeStamp" */ -&(nid_objs[230]),/* "id-smime-aa-ets-otherSigCert" */ -&(nid_objs[235]),/* "id-smime-aa-ets-revocationValues" */ -&(nid_objs[226]),/* "id-smime-aa-ets-sigPolicyId" */ -&(nid_objs[229]),/* "id-smime-aa-ets-signerAttr" */ -&(nid_objs[228]),/* "id-smime-aa-ets-signerLocation" */ -&(nid_objs[219]),/* "id-smime-aa-macValue" */ -&(nid_objs[214]),/* "id-smime-aa-mlExpandHistory" */ -&(nid_objs[216]),/* "id-smime-aa-msgSigDigest" */ -&(nid_objs[212]),/* "id-smime-aa-receiptRequest" */ -&(nid_objs[213]),/* "id-smime-aa-securityLabel" */ -&(nid_objs[239]),/* "id-smime-aa-signatureType" */ -&(nid_objs[223]),/* "id-smime-aa-signingCertificate" */ -&(nid_objs[224]),/* "id-smime-aa-smimeEncryptCerts" */ -&(nid_objs[225]),/* "id-smime-aa-timeStampToken" */ -&(nid_objs[192]),/* "id-smime-alg" */ -&(nid_objs[243]),/* "id-smime-alg-3DESwrap" */ -&(nid_objs[246]),/* "id-smime-alg-CMS3DESwrap" */ -&(nid_objs[247]),/* "id-smime-alg-CMSRC2wrap" */ -&(nid_objs[245]),/* "id-smime-alg-ESDH" */ -&(nid_objs[241]),/* "id-smime-alg-ESDHwith3DES" */ -&(nid_objs[242]),/* "id-smime-alg-ESDHwithRC2" */ -&(nid_objs[244]),/* "id-smime-alg-RC2wrap" */ -&(nid_objs[193]),/* "id-smime-cd" */ -&(nid_objs[248]),/* "id-smime-cd-ldap" */ -&(nid_objs[190]),/* "id-smime-ct" */ -&(nid_objs[210]),/* "id-smime-ct-DVCSRequestData" */ -&(nid_objs[211]),/* "id-smime-ct-DVCSResponseData" */ -&(nid_objs[208]),/* "id-smime-ct-TDTInfo" */ -&(nid_objs[207]),/* "id-smime-ct-TSTInfo" */ -&(nid_objs[205]),/* "id-smime-ct-authData" */ -&(nid_objs[786]),/* "id-smime-ct-compressedData" */ -&(nid_objs[209]),/* "id-smime-ct-contentInfo" */ -&(nid_objs[206]),/* "id-smime-ct-publishCert" */ -&(nid_objs[204]),/* "id-smime-ct-receipt" */ -&(nid_objs[195]),/* "id-smime-cti" */ -&(nid_objs[255]),/* "id-smime-cti-ets-proofOfApproval" */ -&(nid_objs[256]),/* "id-smime-cti-ets-proofOfCreation" */ -&(nid_objs[253]),/* "id-smime-cti-ets-proofOfDelivery" */ -&(nid_objs[251]),/* "id-smime-cti-ets-proofOfOrigin" */ -&(nid_objs[252]),/* "id-smime-cti-ets-proofOfReceipt" */ -&(nid_objs[254]),/* "id-smime-cti-ets-proofOfSender" */ -&(nid_objs[189]),/* "id-smime-mod" */ -&(nid_objs[196]),/* "id-smime-mod-cms" */ -&(nid_objs[197]),/* "id-smime-mod-ess" */ -&(nid_objs[202]),/* "id-smime-mod-ets-eSigPolicy-88" */ -&(nid_objs[203]),/* "id-smime-mod-ets-eSigPolicy-97" */ -&(nid_objs[200]),/* "id-smime-mod-ets-eSignature-88" */ -&(nid_objs[201]),/* "id-smime-mod-ets-eSignature-97" */ -&(nid_objs[199]),/* "id-smime-mod-msg-v3" */ -&(nid_objs[198]),/* "id-smime-mod-oid" */ -&(nid_objs[194]),/* "id-smime-spq" */ -&(nid_objs[250]),/* "id-smime-spq-ets-sqt-unotice" */ -&(nid_objs[249]),/* "id-smime-spq-ets-sqt-uri" */ -&(nid_objs[676]),/* "identified-organization" */ -&(nid_objs[461]),/* "info" */ -&(nid_objs[748]),/* "inhibitAnyPolicy" */ -&(nid_objs[101]),/* "initials" */ -&(nid_objs[647]),/* "international-organizations" */ -&(nid_objs[869]),/* "internationaliSDNNumber" */ -&(nid_objs[142]),/* "invalidityDate" */ -&(nid_objs[294]),/* "ipsecEndSystem" */ -&(nid_objs[295]),/* "ipsecTunnel" */ -&(nid_objs[296]),/* "ipsecUser" */ -&(nid_objs[86]),/* "issuerAltName" */ -&(nid_objs[770]),/* "issuingDistributionPoint" */ -&(nid_objs[492]),/* "janetMailbox" */ -&(nid_objs[150]),/* "keyBag" */ -&(nid_objs[83]),/* "keyUsage" */ -&(nid_objs[477]),/* "lastModifiedBy" */ -&(nid_objs[476]),/* "lastModifiedTime" */ -&(nid_objs[157]),/* "localKeyID" */ -&(nid_objs[480]),/* "mXRecord" */ -&(nid_objs[460]),/* "mail" */ -&(nid_objs[493]),/* "mailPreferenceOption" */ -&(nid_objs[467]),/* "manager" */ -&(nid_objs[809]),/* "md_gost94" */ -&(nid_objs[875]),/* "member" */ -&(nid_objs[182]),/* "member-body" */ -&(nid_objs[51]),/* "messageDigest" */ -&(nid_objs[383]),/* "mgmt" */ -&(nid_objs[504]),/* "mime-mhs" */ -&(nid_objs[506]),/* "mime-mhs-bodies" */ -&(nid_objs[505]),/* "mime-mhs-headings" */ -&(nid_objs[488]),/* "mobileTelephoneNumber" */ -&(nid_objs[136]),/* "msCTLSign" */ -&(nid_objs[135]),/* "msCodeCom" */ -&(nid_objs[134]),/* "msCodeInd" */ -&(nid_objs[138]),/* "msEFS" */ -&(nid_objs[171]),/* "msExtReq" */ -&(nid_objs[137]),/* "msSGC" */ -&(nid_objs[648]),/* "msSmartcardLogin" */ -&(nid_objs[649]),/* "msUPN" */ -&(nid_objs[481]),/* "nSRecord" */ -&(nid_objs[173]),/* "name" */ -&(nid_objs[666]),/* "nameConstraints" */ -&(nid_objs[369]),/* "noCheck" */ -&(nid_objs[403]),/* "noRevAvail" */ -&(nid_objs[72]),/* "nsBaseUrl" */ -&(nid_objs[76]),/* "nsCaPolicyUrl" */ -&(nid_objs[74]),/* "nsCaRevocationUrl" */ -&(nid_objs[58]),/* "nsCertExt" */ -&(nid_objs[79]),/* "nsCertSequence" */ -&(nid_objs[71]),/* "nsCertType" */ -&(nid_objs[78]),/* "nsComment" */ -&(nid_objs[59]),/* "nsDataType" */ -&(nid_objs[75]),/* "nsRenewalUrl" */ -&(nid_objs[73]),/* "nsRevocationUrl" */ -&(nid_objs[139]),/* "nsSGC" */ -&(nid_objs[77]),/* "nsSslServerName" */ -&(nid_objs[681]),/* "onBasis" */ -&(nid_objs[491]),/* "organizationalStatus" */ -&(nid_objs[475]),/* "otherMailbox" */ -&(nid_objs[876]),/* "owner" */ -&(nid_objs[489]),/* "pagerTelephoneNumber" */ -&(nid_objs[374]),/* "path" */ -&(nid_objs[112]),/* "pbeWithMD5AndCast5CBC" */ -&(nid_objs[499]),/* "personalSignature" */ -&(nid_objs[487]),/* "personalTitle" */ -&(nid_objs[464]),/* "photo" */ -&(nid_objs[863]),/* "physicalDeliveryOfficeName" */ -&(nid_objs[437]),/* "pilot" */ -&(nid_objs[439]),/* "pilotAttributeSyntax" */ -&(nid_objs[438]),/* "pilotAttributeType" */ -&(nid_objs[479]),/* "pilotAttributeType27" */ -&(nid_objs[456]),/* "pilotDSA" */ -&(nid_objs[441]),/* "pilotGroups" */ -&(nid_objs[444]),/* "pilotObject" */ -&(nid_objs[440]),/* "pilotObjectClass" */ -&(nid_objs[455]),/* "pilotOrganization" */ -&(nid_objs[445]),/* "pilotPerson" */ -&(nid_objs[ 2]),/* "pkcs" */ -&(nid_objs[186]),/* "pkcs1" */ -&(nid_objs[27]),/* "pkcs3" */ -&(nid_objs[187]),/* "pkcs5" */ -&(nid_objs[20]),/* "pkcs7" */ -&(nid_objs[21]),/* "pkcs7-data" */ -&(nid_objs[25]),/* "pkcs7-digestData" */ -&(nid_objs[26]),/* "pkcs7-encryptedData" */ -&(nid_objs[23]),/* "pkcs7-envelopedData" */ -&(nid_objs[24]),/* "pkcs7-signedAndEnvelopedData" */ -&(nid_objs[22]),/* "pkcs7-signedData" */ -&(nid_objs[151]),/* "pkcs8ShroudedKeyBag" */ -&(nid_objs[47]),/* "pkcs9" */ -&(nid_objs[401]),/* "policyConstraints" */ -&(nid_objs[747]),/* "policyMappings" */ -&(nid_objs[862]),/* "postOfficeBox" */ -&(nid_objs[861]),/* "postalAddress" */ -&(nid_objs[661]),/* "postalCode" */ -&(nid_objs[683]),/* "ppBasis" */ -&(nid_objs[872]),/* "preferredDeliveryMethod" */ -&(nid_objs[873]),/* "presentationAddress" */ -&(nid_objs[816]),/* "prf-gostr3411-94" */ -&(nid_objs[406]),/* "prime-field" */ -&(nid_objs[409]),/* "prime192v1" */ -&(nid_objs[410]),/* "prime192v2" */ -&(nid_objs[411]),/* "prime192v3" */ -&(nid_objs[412]),/* "prime239v1" */ -&(nid_objs[413]),/* "prime239v2" */ -&(nid_objs[414]),/* "prime239v3" */ -&(nid_objs[415]),/* "prime256v1" */ -&(nid_objs[385]),/* "private" */ -&(nid_objs[84]),/* "privateKeyUsagePeriod" */ -&(nid_objs[886]),/* "protocolInformation" */ -&(nid_objs[663]),/* "proxyCertInfo" */ -&(nid_objs[510]),/* "pseudonym" */ -&(nid_objs[435]),/* "pss" */ -&(nid_objs[286]),/* "qcStatements" */ -&(nid_objs[457]),/* "qualityLabelledData" */ -&(nid_objs[450]),/* "rFC822localPart" */ -&(nid_objs[870]),/* "registeredAddress" */ -&(nid_objs[400]),/* "role" */ -&(nid_objs[877]),/* "roleOccupant" */ -&(nid_objs[448]),/* "room" */ -&(nid_objs[463]),/* "roomNumber" */ -&(nid_objs[ 6]),/* "rsaEncryption" */ -&(nid_objs[644]),/* "rsaOAEPEncryptionSET" */ -&(nid_objs[377]),/* "rsaSignature" */ -&(nid_objs[ 1]),/* "rsadsi" */ -&(nid_objs[482]),/* "sOARecord" */ -&(nid_objs[155]),/* "safeContentsBag" */ -&(nid_objs[291]),/* "sbgp-autonomousSysNum" */ -&(nid_objs[290]),/* "sbgp-ipAddrBlock" */ -&(nid_objs[292]),/* "sbgp-routerIdentifier" */ -&(nid_objs[159]),/* "sdsiCertificate" */ -&(nid_objs[859]),/* "searchGuide" */ -&(nid_objs[704]),/* "secp112r1" */ -&(nid_objs[705]),/* "secp112r2" */ -&(nid_objs[706]),/* "secp128r1" */ -&(nid_objs[707]),/* "secp128r2" */ -&(nid_objs[708]),/* "secp160k1" */ -&(nid_objs[709]),/* "secp160r1" */ -&(nid_objs[710]),/* "secp160r2" */ -&(nid_objs[711]),/* "secp192k1" */ -&(nid_objs[712]),/* "secp224k1" */ -&(nid_objs[713]),/* "secp224r1" */ -&(nid_objs[714]),/* "secp256k1" */ -&(nid_objs[715]),/* "secp384r1" */ -&(nid_objs[716]),/* "secp521r1" */ -&(nid_objs[154]),/* "secretBag" */ -&(nid_objs[474]),/* "secretary" */ -&(nid_objs[717]),/* "sect113r1" */ -&(nid_objs[718]),/* "sect113r2" */ -&(nid_objs[719]),/* "sect131r1" */ -&(nid_objs[720]),/* "sect131r2" */ -&(nid_objs[721]),/* "sect163k1" */ -&(nid_objs[722]),/* "sect163r1" */ -&(nid_objs[723]),/* "sect163r2" */ -&(nid_objs[724]),/* "sect193r1" */ -&(nid_objs[725]),/* "sect193r2" */ -&(nid_objs[726]),/* "sect233k1" */ -&(nid_objs[727]),/* "sect233r1" */ -&(nid_objs[728]),/* "sect239k1" */ -&(nid_objs[729]),/* "sect283k1" */ -&(nid_objs[730]),/* "sect283r1" */ -&(nid_objs[731]),/* "sect409k1" */ -&(nid_objs[732]),/* "sect409r1" */ -&(nid_objs[733]),/* "sect571k1" */ -&(nid_objs[734]),/* "sect571r1" */ -&(nid_objs[386]),/* "security" */ -&(nid_objs[878]),/* "seeAlso" */ -&(nid_objs[394]),/* "selected-attribute-types" */ -&(nid_objs[105]),/* "serialNumber" */ -&(nid_objs[129]),/* "serverAuth" */ -&(nid_objs[371]),/* "serviceLocator" */ -&(nid_objs[625]),/* "set-addPolicy" */ -&(nid_objs[515]),/* "set-attr" */ -&(nid_objs[518]),/* "set-brand" */ -&(nid_objs[638]),/* "set-brand-AmericanExpress" */ -&(nid_objs[637]),/* "set-brand-Diners" */ -&(nid_objs[636]),/* "set-brand-IATA-ATA" */ -&(nid_objs[639]),/* "set-brand-JCB" */ -&(nid_objs[641]),/* "set-brand-MasterCard" */ -&(nid_objs[642]),/* "set-brand-Novus" */ -&(nid_objs[640]),/* "set-brand-Visa" */ -&(nid_objs[517]),/* "set-certExt" */ -&(nid_objs[513]),/* "set-ctype" */ -&(nid_objs[514]),/* "set-msgExt" */ -&(nid_objs[516]),/* "set-policy" */ -&(nid_objs[607]),/* "set-policy-root" */ -&(nid_objs[624]),/* "set-rootKeyThumb" */ -&(nid_objs[620]),/* "setAttr-Cert" */ -&(nid_objs[631]),/* "setAttr-GenCryptgrm" */ -&(nid_objs[623]),/* "setAttr-IssCap" */ -&(nid_objs[628]),/* "setAttr-IssCap-CVM" */ -&(nid_objs[630]),/* "setAttr-IssCap-Sig" */ -&(nid_objs[629]),/* "setAttr-IssCap-T2" */ -&(nid_objs[621]),/* "setAttr-PGWYcap" */ -&(nid_objs[635]),/* "setAttr-SecDevSig" */ -&(nid_objs[632]),/* "setAttr-T2Enc" */ -&(nid_objs[633]),/* "setAttr-T2cleartxt" */ -&(nid_objs[634]),/* "setAttr-TokICCsig" */ -&(nid_objs[627]),/* "setAttr-Token-B0Prime" */ -&(nid_objs[626]),/* "setAttr-Token-EMV" */ -&(nid_objs[622]),/* "setAttr-TokenType" */ -&(nid_objs[619]),/* "setCext-IssuerCapabilities" */ -&(nid_objs[615]),/* "setCext-PGWYcapabilities" */ -&(nid_objs[616]),/* "setCext-TokenIdentifier" */ -&(nid_objs[618]),/* "setCext-TokenType" */ -&(nid_objs[617]),/* "setCext-Track2Data" */ -&(nid_objs[611]),/* "setCext-cCertRequired" */ -&(nid_objs[609]),/* "setCext-certType" */ -&(nid_objs[608]),/* "setCext-hashedRoot" */ -&(nid_objs[610]),/* "setCext-merchData" */ -&(nid_objs[613]),/* "setCext-setExt" */ -&(nid_objs[614]),/* "setCext-setQualf" */ -&(nid_objs[612]),/* "setCext-tunneling" */ -&(nid_objs[540]),/* "setct-AcqCardCodeMsg" */ -&(nid_objs[576]),/* "setct-AcqCardCodeMsgTBE" */ -&(nid_objs[570]),/* "setct-AuthReqTBE" */ -&(nid_objs[534]),/* "setct-AuthReqTBS" */ -&(nid_objs[527]),/* "setct-AuthResBaggage" */ -&(nid_objs[571]),/* "setct-AuthResTBE" */ -&(nid_objs[572]),/* "setct-AuthResTBEX" */ -&(nid_objs[535]),/* "setct-AuthResTBS" */ -&(nid_objs[536]),/* "setct-AuthResTBSX" */ -&(nid_objs[528]),/* "setct-AuthRevReqBaggage" */ -&(nid_objs[577]),/* "setct-AuthRevReqTBE" */ -&(nid_objs[541]),/* "setct-AuthRevReqTBS" */ -&(nid_objs[529]),/* "setct-AuthRevResBaggage" */ -&(nid_objs[542]),/* "setct-AuthRevResData" */ -&(nid_objs[578]),/* "setct-AuthRevResTBE" */ -&(nid_objs[579]),/* "setct-AuthRevResTBEB" */ -&(nid_objs[543]),/* "setct-AuthRevResTBS" */ -&(nid_objs[573]),/* "setct-AuthTokenTBE" */ -&(nid_objs[537]),/* "setct-AuthTokenTBS" */ -&(nid_objs[600]),/* "setct-BCIDistributionTBS" */ -&(nid_objs[558]),/* "setct-BatchAdminReqData" */ -&(nid_objs[592]),/* "setct-BatchAdminReqTBE" */ -&(nid_objs[559]),/* "setct-BatchAdminResData" */ -&(nid_objs[593]),/* "setct-BatchAdminResTBE" */ -&(nid_objs[599]),/* "setct-CRLNotificationResTBS" */ -&(nid_objs[598]),/* "setct-CRLNotificationTBS" */ -&(nid_objs[580]),/* "setct-CapReqTBE" */ -&(nid_objs[581]),/* "setct-CapReqTBEX" */ -&(nid_objs[544]),/* "setct-CapReqTBS" */ -&(nid_objs[545]),/* "setct-CapReqTBSX" */ -&(nid_objs[546]),/* "setct-CapResData" */ -&(nid_objs[582]),/* "setct-CapResTBE" */ -&(nid_objs[583]),/* "setct-CapRevReqTBE" */ -&(nid_objs[584]),/* "setct-CapRevReqTBEX" */ -&(nid_objs[547]),/* "setct-CapRevReqTBS" */ -&(nid_objs[548]),/* "setct-CapRevReqTBSX" */ -&(nid_objs[549]),/* "setct-CapRevResData" */ -&(nid_objs[585]),/* "setct-CapRevResTBE" */ -&(nid_objs[538]),/* "setct-CapTokenData" */ -&(nid_objs[530]),/* "setct-CapTokenSeq" */ -&(nid_objs[574]),/* "setct-CapTokenTBE" */ -&(nid_objs[575]),/* "setct-CapTokenTBEX" */ -&(nid_objs[539]),/* "setct-CapTokenTBS" */ -&(nid_objs[560]),/* "setct-CardCInitResTBS" */ -&(nid_objs[566]),/* "setct-CertInqReqTBS" */ -&(nid_objs[563]),/* "setct-CertReqData" */ -&(nid_objs[595]),/* "setct-CertReqTBE" */ -&(nid_objs[596]),/* "setct-CertReqTBEX" */ -&(nid_objs[564]),/* "setct-CertReqTBS" */ -&(nid_objs[565]),/* "setct-CertResData" */ -&(nid_objs[597]),/* "setct-CertResTBE" */ -&(nid_objs[586]),/* "setct-CredReqTBE" */ -&(nid_objs[587]),/* "setct-CredReqTBEX" */ -&(nid_objs[550]),/* "setct-CredReqTBS" */ -&(nid_objs[551]),/* "setct-CredReqTBSX" */ -&(nid_objs[552]),/* "setct-CredResData" */ -&(nid_objs[588]),/* "setct-CredResTBE" */ -&(nid_objs[589]),/* "setct-CredRevReqTBE" */ -&(nid_objs[590]),/* "setct-CredRevReqTBEX" */ -&(nid_objs[553]),/* "setct-CredRevReqTBS" */ -&(nid_objs[554]),/* "setct-CredRevReqTBSX" */ -&(nid_objs[555]),/* "setct-CredRevResData" */ -&(nid_objs[591]),/* "setct-CredRevResTBE" */ -&(nid_objs[567]),/* "setct-ErrorTBS" */ -&(nid_objs[526]),/* "setct-HODInput" */ -&(nid_objs[561]),/* "setct-MeAqCInitResTBS" */ -&(nid_objs[522]),/* "setct-OIData" */ -&(nid_objs[519]),/* "setct-PANData" */ -&(nid_objs[521]),/* "setct-PANOnly" */ -&(nid_objs[520]),/* "setct-PANToken" */ -&(nid_objs[556]),/* "setct-PCertReqData" */ -&(nid_objs[557]),/* "setct-PCertResTBS" */ -&(nid_objs[523]),/* "setct-PI" */ -&(nid_objs[532]),/* "setct-PI-TBS" */ -&(nid_objs[524]),/* "setct-PIData" */ -&(nid_objs[525]),/* "setct-PIDataUnsigned" */ -&(nid_objs[568]),/* "setct-PIDualSignedTBE" */ -&(nid_objs[569]),/* "setct-PIUnsignedTBE" */ -&(nid_objs[531]),/* "setct-PInitResData" */ -&(nid_objs[533]),/* "setct-PResData" */ -&(nid_objs[594]),/* "setct-RegFormReqTBE" */ -&(nid_objs[562]),/* "setct-RegFormResTBS" */ -&(nid_objs[606]),/* "setext-cv" */ -&(nid_objs[601]),/* "setext-genCrypt" */ -&(nid_objs[602]),/* "setext-miAuth" */ -&(nid_objs[604]),/* "setext-pinAny" */ -&(nid_objs[603]),/* "setext-pinSecure" */ -&(nid_objs[605]),/* "setext-track2" */ -&(nid_objs[52]),/* "signingTime" */ -&(nid_objs[454]),/* "simpleSecurityObject" */ -&(nid_objs[496]),/* "singleLevelQuality" */ -&(nid_objs[387]),/* "snmpv2" */ -&(nid_objs[660]),/* "street" */ -&(nid_objs[85]),/* "subjectAltName" */ -&(nid_objs[769]),/* "subjectDirectoryAttributes" */ -&(nid_objs[398]),/* "subjectInfoAccess" */ -&(nid_objs[82]),/* "subjectKeyIdentifier" */ -&(nid_objs[498]),/* "subtreeMaximumQuality" */ -&(nid_objs[497]),/* "subtreeMinimumQuality" */ -&(nid_objs[890]),/* "supportedAlgorithms" */ -&(nid_objs[874]),/* "supportedApplicationContext" */ -&(nid_objs[402]),/* "targetInformation" */ -&(nid_objs[864]),/* "telephoneNumber" */ -&(nid_objs[866]),/* "teletexTerminalIdentifier" */ -&(nid_objs[865]),/* "telexNumber" */ -&(nid_objs[459]),/* "textEncodedORAddress" */ -&(nid_objs[293]),/* "textNotice" */ -&(nid_objs[133]),/* "timeStamping" */ -&(nid_objs[106]),/* "title" */ -&(nid_objs[682]),/* "tpBasis" */ -&(nid_objs[375]),/* "trustRoot" */ -&(nid_objs[436]),/* "ucl" */ -&(nid_objs[888]),/* "uniqueMember" */ -&(nid_objs[55]),/* "unstructuredAddress" */ -&(nid_objs[49]),/* "unstructuredName" */ -&(nid_objs[880]),/* "userCertificate" */ -&(nid_objs[465]),/* "userClass" */ -&(nid_objs[879]),/* "userPassword" */ -&(nid_objs[373]),/* "valid" */ -&(nid_objs[678]),/* "wap" */ -&(nid_objs[679]),/* "wap-wsg" */ -&(nid_objs[735]),/* "wap-wsg-idm-ecid-wtls1" */ -&(nid_objs[743]),/* "wap-wsg-idm-ecid-wtls10" */ -&(nid_objs[744]),/* "wap-wsg-idm-ecid-wtls11" */ -&(nid_objs[745]),/* "wap-wsg-idm-ecid-wtls12" */ -&(nid_objs[736]),/* "wap-wsg-idm-ecid-wtls3" */ -&(nid_objs[737]),/* "wap-wsg-idm-ecid-wtls4" */ -&(nid_objs[738]),/* "wap-wsg-idm-ecid-wtls5" */ -&(nid_objs[739]),/* "wap-wsg-idm-ecid-wtls6" */ -&(nid_objs[740]),/* "wap-wsg-idm-ecid-wtls7" */ -&(nid_objs[741]),/* "wap-wsg-idm-ecid-wtls8" */ -&(nid_objs[742]),/* "wap-wsg-idm-ecid-wtls9" */ -&(nid_objs[804]),/* "whirlpool" */ -&(nid_objs[868]),/* "x121Address" */ -&(nid_objs[503]),/* "x500UniqueIdentifier" */ -&(nid_objs[158]),/* "x509Certificate" */ -&(nid_objs[160]),/* "x509Crl" */ +static const unsigned int sn_objs[NUM_SN]={ +364, /* "AD_DVCS" */ +419, /* "AES-128-CBC" */ +421, /* "AES-128-CFB" */ +650, /* "AES-128-CFB1" */ +653, /* "AES-128-CFB8" */ +418, /* "AES-128-ECB" */ +420, /* "AES-128-OFB" */ +423, /* "AES-192-CBC" */ +425, /* "AES-192-CFB" */ +651, /* "AES-192-CFB1" */ +654, /* "AES-192-CFB8" */ +422, /* "AES-192-ECB" */ +424, /* "AES-192-OFB" */ +427, /* "AES-256-CBC" */ +429, /* "AES-256-CFB" */ +652, /* "AES-256-CFB1" */ +655, /* "AES-256-CFB8" */ +426, /* "AES-256-ECB" */ +428, /* "AES-256-OFB" */ +91, /* "BF-CBC" */ +93, /* "BF-CFB" */ +92, /* "BF-ECB" */ +94, /* "BF-OFB" */ +14, /* "C" */ +751, /* "CAMELLIA-128-CBC" */ +757, /* "CAMELLIA-128-CFB" */ +760, /* "CAMELLIA-128-CFB1" */ +763, /* "CAMELLIA-128-CFB8" */ +754, /* "CAMELLIA-128-ECB" */ +766, /* "CAMELLIA-128-OFB" */ +752, /* "CAMELLIA-192-CBC" */ +758, /* "CAMELLIA-192-CFB" */ +761, /* "CAMELLIA-192-CFB1" */ +764, /* "CAMELLIA-192-CFB8" */ +755, /* "CAMELLIA-192-ECB" */ +767, /* "CAMELLIA-192-OFB" */ +753, /* "CAMELLIA-256-CBC" */ +759, /* "CAMELLIA-256-CFB" */ +762, /* "CAMELLIA-256-CFB1" */ +765, /* "CAMELLIA-256-CFB8" */ +756, /* "CAMELLIA-256-ECB" */ +768, /* "CAMELLIA-256-OFB" */ +108, /* "CAST5-CBC" */ +110, /* "CAST5-CFB" */ +109, /* "CAST5-ECB" */ +111, /* "CAST5-OFB" */ +13, /* "CN" */ +141, /* "CRLReason" */ +417, /* "CSPName" */ +367, /* "CrlID" */ +391, /* "DC" */ +31, /* "DES-CBC" */ +643, /* "DES-CDMF" */ +30, /* "DES-CFB" */ +656, /* "DES-CFB1" */ +657, /* "DES-CFB8" */ +29, /* "DES-ECB" */ +32, /* "DES-EDE" */ +43, /* "DES-EDE-CBC" */ +60, /* "DES-EDE-CFB" */ +62, /* "DES-EDE-OFB" */ +33, /* "DES-EDE3" */ +44, /* "DES-EDE3-CBC" */ +61, /* "DES-EDE3-CFB" */ +658, /* "DES-EDE3-CFB1" */ +659, /* "DES-EDE3-CFB8" */ +63, /* "DES-EDE3-OFB" */ +45, /* "DES-OFB" */ +80, /* "DESX-CBC" */ +380, /* "DOD" */ +116, /* "DSA" */ +66, /* "DSA-SHA" */ +113, /* "DSA-SHA1" */ +70, /* "DSA-SHA1-old" */ +67, /* "DSA-old" */ +297, /* "DVCS" */ +99, /* "GN" */ +855, /* "HMAC" */ +780, /* "HMAC-MD5" */ +781, /* "HMAC-SHA1" */ +381, /* "IANA" */ +34, /* "IDEA-CBC" */ +35, /* "IDEA-CFB" */ +36, /* "IDEA-ECB" */ +46, /* "IDEA-OFB" */ +181, /* "ISO" */ +183, /* "ISO-US" */ +645, /* "ITU-T" */ +646, /* "JOINT-ISO-ITU-T" */ +773, /* "KISA" */ +15, /* "L" */ +856, /* "LocalKeySet" */ + 3, /* "MD2" */ +257, /* "MD4" */ + 4, /* "MD5" */ +114, /* "MD5-SHA1" */ +95, /* "MDC2" */ +388, /* "Mail" */ +393, /* "NULL" */ +404, /* "NULL" */ +57, /* "Netscape" */ +366, /* "Nonce" */ +17, /* "O" */ +178, /* "OCSP" */ +180, /* "OCSPSigning" */ +379, /* "ORG" */ +18, /* "OU" */ +749, /* "Oakley-EC2N-3" */ +750, /* "Oakley-EC2N-4" */ + 9, /* "PBE-MD2-DES" */ +168, /* "PBE-MD2-RC2-64" */ +10, /* "PBE-MD5-DES" */ +169, /* "PBE-MD5-RC2-64" */ +147, /* "PBE-SHA1-2DES" */ +146, /* "PBE-SHA1-3DES" */ +170, /* "PBE-SHA1-DES" */ +148, /* "PBE-SHA1-RC2-128" */ +149, /* "PBE-SHA1-RC2-40" */ +68, /* "PBE-SHA1-RC2-64" */ +144, /* "PBE-SHA1-RC4-128" */ +145, /* "PBE-SHA1-RC4-40" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +98, /* "RC2-40-CBC" */ +166, /* "RC2-64-CBC" */ +37, /* "RC2-CBC" */ +39, /* "RC2-CFB" */ +38, /* "RC2-ECB" */ +40, /* "RC2-OFB" */ + 5, /* "RC4" */ +97, /* "RC4-40" */ +120, /* "RC5-CBC" */ +122, /* "RC5-CFB" */ +121, /* "RC5-ECB" */ +123, /* "RC5-OFB" */ +117, /* "RIPEMD160" */ +124, /* "RLE" */ +19, /* "RSA" */ + 7, /* "RSA-MD2" */ +396, /* "RSA-MD4" */ + 8, /* "RSA-MD5" */ +96, /* "RSA-MDC2" */ +104, /* "RSA-NP-MD5" */ +119, /* "RSA-RIPEMD160" */ +42, /* "RSA-SHA" */ +65, /* "RSA-SHA1" */ +115, /* "RSA-SHA1-2" */ +671, /* "RSA-SHA224" */ +668, /* "RSA-SHA256" */ +669, /* "RSA-SHA384" */ +670, /* "RSA-SHA512" */ +777, /* "SEED-CBC" */ +779, /* "SEED-CFB" */ +776, /* "SEED-ECB" */ +778, /* "SEED-OFB" */ +41, /* "SHA" */ +64, /* "SHA1" */ +675, /* "SHA224" */ +672, /* "SHA256" */ +673, /* "SHA384" */ +674, /* "SHA512" */ +188, /* "SMIME" */ +167, /* "SMIME-CAPS" */ +100, /* "SN" */ +16, /* "ST" */ +143, /* "SXNetID" */ +458, /* "UID" */ + 0, /* "UNDEF" */ +11, /* "X500" */ +378, /* "X500algorithms" */ +12, /* "X509" */ +184, /* "X9-57" */ +185, /* "X9cm" */ +125, /* "ZLIB" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +368, /* "acceptableResponses" */ +446, /* "account" */ +363, /* "ad_timestamping" */ +376, /* "algorithm" */ +405, /* "ansi-X9-62" */ +746, /* "anyPolicy" */ +370, /* "archiveCutoff" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +177, /* "authorityInfoAccess" */ +90, /* "authorityKeyIdentifier" */ +882, /* "authorityRevocationList" */ +87, /* "basicConstraints" */ +365, /* "basicOCSPResponse" */ +285, /* "biometricInfo" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +179, /* "caIssuers" */ +785, /* "caRepository" */ +443, /* "caseIgnoreIA5StringSyntax" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +771, /* "certificateIssuer" */ +89, /* "certificatePolicies" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +130, /* "clientAuth" */ +131, /* "codeSigning" */ +50, /* "contentType" */ +53, /* "countersignature" */ +153, /* "crlBag" */ +103, /* "crlDistributionPoints" */ +88, /* "crlNumber" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcobject" */ +140, /* "deltaCRL" */ +891, /* "deltaRevocationList" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +28, /* "dhKeyAgreement" */ +382, /* "directory" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +392, /* "domain" */ +452, /* "domainRelatedObject" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +132, /* "emailProtection" */ +885, /* "enhancedSearchGuide" */ +389, /* "enterprises" */ +384, /* "experimental" */ +172, /* "extReq" */ +56, /* "extendedCertificateAttributes" */ +126, /* "extendedKeyUsage" */ +372, /* "extendedStatus" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +857, /* "freshestCRL" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +509, /* "generationQualifier" */ +815, /* "gost-mac" */ +811, /* "gost2001" */ +851, /* "gost2001cc" */ +813, /* "gost89" */ +814, /* "gost89-cnt" */ +812, /* "gost94" */ +850, /* "gost94cc" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +432, /* "holdInstructionCallIssuer" */ +430, /* "holdInstructionCode" */ +431, /* "holdInstructionNone" */ +433, /* "holdInstructionReject" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +783, /* "id-DHBasedMac" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +849, /* "id-Gost28147-89-cc" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +854, /* "id-GostR3410-2001-ParamSet-cc" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +817, /* "id-GostR3410-2001DH" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +818, /* "id-GostR3410-94DH" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +807, /* "id-GostR3411-94-with-GostR3410-2001" */ +853, /* "id-GostR3411-94-with-GostR3410-2001-cc" */ +808, /* "id-GostR3411-94-with-GostR3410-94" */ +852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ +810, /* "id-HMACGostR3411-94" */ +782, /* "id-PasswordBasedMAC" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +788, /* "id-aes128-wrap" */ +789, /* "id-aes192-wrap" */ +790, /* "id-aes256-wrap" */ +262, /* "id-alg" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +787, /* "id-ct-asciiTextWithCRLF" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +858, /* "id-on-permanentIdentifier" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +664, /* "id-ppl-anyLanguage" */ +667, /* "id-ppl-independent" */ +665, /* "id-ppl-inheritAll" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +164, /* "id-qt-cps" */ +165, /* "id-qt-unotice" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +512, /* "id-set" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +676, /* "identified-organization" */ +461, /* "info" */ +748, /* "inhibitAnyPolicy" */ +101, /* "initials" */ +647, /* "international-organizations" */ +869, /* "internationaliSDNNumber" */ +142, /* "invalidityDate" */ +294, /* "ipsecEndSystem" */ +295, /* "ipsecTunnel" */ +296, /* "ipsecUser" */ +86, /* "issuerAltName" */ +770, /* "issuingDistributionPoint" */ +492, /* "janetMailbox" */ +150, /* "keyBag" */ +83, /* "keyUsage" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +480, /* "mXRecord" */ +460, /* "mail" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ +809, /* "md_gost94" */ +875, /* "member" */ +182, /* "member-body" */ +51, /* "messageDigest" */ +383, /* "mgmt" */ +504, /* "mime-mhs" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +136, /* "msCTLSign" */ +135, /* "msCodeCom" */ +134, /* "msCodeInd" */ +138, /* "msEFS" */ +171, /* "msExtReq" */ +137, /* "msSGC" */ +648, /* "msSmartcardLogin" */ +649, /* "msUPN" */ +481, /* "nSRecord" */ +173, /* "name" */ +666, /* "nameConstraints" */ +369, /* "noCheck" */ +403, /* "noRevAvail" */ +72, /* "nsBaseUrl" */ +76, /* "nsCaPolicyUrl" */ +74, /* "nsCaRevocationUrl" */ +58, /* "nsCertExt" */ +79, /* "nsCertSequence" */ +71, /* "nsCertType" */ +78, /* "nsComment" */ +59, /* "nsDataType" */ +75, /* "nsRenewalUrl" */ +73, /* "nsRevocationUrl" */ +139, /* "nsSGC" */ +77, /* "nsSslServerName" */ +681, /* "onBasis" */ +491, /* "organizationalStatus" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +489, /* "pagerTelephoneNumber" */ +374, /* "path" */ +112, /* "pbeWithMD5AndCast5CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ + 2, /* "pkcs" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +401, /* "policyConstraints" */ +747, /* "policyMappings" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +816, /* "prf-gostr3411-94" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +385, /* "private" */ +84, /* "privateKeyUsagePeriod" */ +886, /* "protocolInformation" */ +663, /* "proxyCertInfo" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +870, /* "registeredAddress" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ + 1, /* "rsadsi" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +290, /* "sbgp-ipAddrBlock" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +386, /* "security" */ +878, /* "seeAlso" */ +394, /* "selected-attribute-types" */ +105, /* "serialNumber" */ +129, /* "serverAuth" */ +371, /* "serviceLocator" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +517, /* "set-certExt" */ +513, /* "set-ctype" */ +514, /* "set-msgExt" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +631, /* "setAttr-GenCryptgrm" */ +623, /* "setAttr-IssCap" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +621, /* "setAttr-PGWYcap" */ +635, /* "setAttr-SecDevSig" */ +632, /* "setAttr-T2Enc" */ +633, /* "setAttr-T2cleartxt" */ +634, /* "setAttr-TokICCsig" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +606, /* "setext-cv" */ +601, /* "setext-genCrypt" */ +602, /* "setext-miAuth" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +387, /* "snmpv2" */ +660, /* "street" */ +85, /* "subjectAltName" */ +769, /* "subjectDirectoryAttributes" */ +398, /* "subjectInfoAccess" */ +82, /* "subjectKeyIdentifier" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +402, /* "targetInformation" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +133, /* "timeStamping" */ +106, /* "title" */ +682, /* "tpBasis" */ +375, /* "trustRoot" */ +436, /* "ucl" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ }; -static ASN1_OBJECT *ln_objs[NUM_LN]={ -&(nid_objs[363]),/* "AD Time Stamping" */ -&(nid_objs[405]),/* "ANSI X9.62" */ -&(nid_objs[368]),/* "Acceptable OCSP Responses" */ -&(nid_objs[664]),/* "Any language" */ -&(nid_objs[177]),/* "Authority Information Access" */ -&(nid_objs[365]),/* "Basic OCSP Response" */ -&(nid_objs[285]),/* "Biometric Info" */ -&(nid_objs[179]),/* "CA Issuers" */ -&(nid_objs[785]),/* "CA Repository" */ -&(nid_objs[131]),/* "Code Signing" */ -&(nid_objs[783]),/* "Diffie-Hellman based MAC" */ -&(nid_objs[382]),/* "Directory" */ -&(nid_objs[392]),/* "Domain" */ -&(nid_objs[132]),/* "E-mail Protection" */ -&(nid_objs[389]),/* "Enterprises" */ -&(nid_objs[384]),/* "Experimental" */ -&(nid_objs[372]),/* "Extended OCSP Status" */ -&(nid_objs[172]),/* "Extension Request" */ -&(nid_objs[813]),/* "GOST 28147-89" */ -&(nid_objs[849]),/* "GOST 28147-89 Cryptocom ParamSet" */ -&(nid_objs[815]),/* "GOST 28147-89 MAC" */ -&(nid_objs[851]),/* "GOST 34.10-2001 Cryptocom" */ -&(nid_objs[850]),/* "GOST 34.10-94 Cryptocom" */ -&(nid_objs[811]),/* "GOST R 34.10-2001" */ -&(nid_objs[817]),/* "GOST R 34.10-2001 DH" */ -&(nid_objs[812]),/* "GOST R 34.10-94" */ -&(nid_objs[818]),/* "GOST R 34.10-94 DH" */ -&(nid_objs[809]),/* "GOST R 34.11-94" */ -&(nid_objs[816]),/* "GOST R 34.11-94 PRF" */ -&(nid_objs[807]),/* "GOST R 34.11-94 with GOST R 34.10-2001" */ -&(nid_objs[853]),/* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ -&(nid_objs[808]),/* "GOST R 34.11-94 with GOST R 34.10-94" */ -&(nid_objs[852]),/* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ -&(nid_objs[854]),/* "GOST R 3410-2001 Parameter Set Cryptocom" */ -&(nid_objs[810]),/* "HMAC GOST 34.11-94" */ -&(nid_objs[432]),/* "Hold Instruction Call Issuer" */ -&(nid_objs[430]),/* "Hold Instruction Code" */ -&(nid_objs[431]),/* "Hold Instruction None" */ -&(nid_objs[433]),/* "Hold Instruction Reject" */ -&(nid_objs[634]),/* "ICC or token signature" */ -&(nid_objs[294]),/* "IPSec End System" */ -&(nid_objs[295]),/* "IPSec Tunnel" */ -&(nid_objs[296]),/* "IPSec User" */ -&(nid_objs[182]),/* "ISO Member Body" */ -&(nid_objs[183]),/* "ISO US Member Body" */ -&(nid_objs[667]),/* "Independent" */ -&(nid_objs[665]),/* "Inherit all" */ -&(nid_objs[647]),/* "International Organizations" */ -&(nid_objs[142]),/* "Invalidity Date" */ -&(nid_objs[504]),/* "MIME MHS" */ -&(nid_objs[388]),/* "Mail" */ -&(nid_objs[383]),/* "Management" */ -&(nid_objs[417]),/* "Microsoft CSP Name" */ -&(nid_objs[135]),/* "Microsoft Commercial Code Signing" */ -&(nid_objs[138]),/* "Microsoft Encrypted File System" */ -&(nid_objs[171]),/* "Microsoft Extension Request" */ -&(nid_objs[134]),/* "Microsoft Individual Code Signing" */ -&(nid_objs[856]),/* "Microsoft Local Key set" */ -&(nid_objs[137]),/* "Microsoft Server Gated Crypto" */ -&(nid_objs[648]),/* "Microsoft Smartcardlogin" */ -&(nid_objs[136]),/* "Microsoft Trust List Signing" */ -&(nid_objs[649]),/* "Microsoft Universal Principal Name" */ -&(nid_objs[393]),/* "NULL" */ -&(nid_objs[404]),/* "NULL" */ -&(nid_objs[72]),/* "Netscape Base Url" */ -&(nid_objs[76]),/* "Netscape CA Policy Url" */ -&(nid_objs[74]),/* "Netscape CA Revocation Url" */ -&(nid_objs[71]),/* "Netscape Cert Type" */ -&(nid_objs[58]),/* "Netscape Certificate Extension" */ -&(nid_objs[79]),/* "Netscape Certificate Sequence" */ -&(nid_objs[78]),/* "Netscape Comment" */ -&(nid_objs[57]),/* "Netscape Communications Corp." */ -&(nid_objs[59]),/* "Netscape Data Type" */ -&(nid_objs[75]),/* "Netscape Renewal Url" */ -&(nid_objs[73]),/* "Netscape Revocation Url" */ -&(nid_objs[77]),/* "Netscape SSL Server Name" */ -&(nid_objs[139]),/* "Netscape Server Gated Crypto" */ -&(nid_objs[178]),/* "OCSP" */ -&(nid_objs[370]),/* "OCSP Archive Cutoff" */ -&(nid_objs[367]),/* "OCSP CRL ID" */ -&(nid_objs[369]),/* "OCSP No Check" */ -&(nid_objs[366]),/* "OCSP Nonce" */ -&(nid_objs[371]),/* "OCSP Service Locator" */ -&(nid_objs[180]),/* "OCSP Signing" */ -&(nid_objs[161]),/* "PBES2" */ -&(nid_objs[69]),/* "PBKDF2" */ -&(nid_objs[162]),/* "PBMAC1" */ -&(nid_objs[127]),/* "PKIX" */ -&(nid_objs[858]),/* "Permanent Identifier" */ -&(nid_objs[164]),/* "Policy Qualifier CPS" */ -&(nid_objs[165]),/* "Policy Qualifier User Notice" */ -&(nid_objs[385]),/* "Private" */ -&(nid_objs[663]),/* "Proxy Certificate Information" */ -&(nid_objs[ 1]),/* "RSA Data Security, Inc." */ -&(nid_objs[ 2]),/* "RSA Data Security, Inc. PKCS" */ -&(nid_objs[188]),/* "S/MIME" */ -&(nid_objs[167]),/* "S/MIME Capabilities" */ -&(nid_objs[387]),/* "SNMPv2" */ -&(nid_objs[512]),/* "Secure Electronic Transactions" */ -&(nid_objs[386]),/* "Security" */ -&(nid_objs[394]),/* "Selected Attribute Types" */ -&(nid_objs[143]),/* "Strong Extranet ID" */ -&(nid_objs[398]),/* "Subject Information Access" */ -&(nid_objs[130]),/* "TLS Web Client Authentication" */ -&(nid_objs[129]),/* "TLS Web Server Authentication" */ -&(nid_objs[133]),/* "Time Stamping" */ -&(nid_objs[375]),/* "Trust Root" */ -&(nid_objs[12]),/* "X509" */ -&(nid_objs[402]),/* "X509v3 AC Targeting" */ -&(nid_objs[746]),/* "X509v3 Any Policy" */ -&(nid_objs[90]),/* "X509v3 Authority Key Identifier" */ -&(nid_objs[87]),/* "X509v3 Basic Constraints" */ -&(nid_objs[103]),/* "X509v3 CRL Distribution Points" */ -&(nid_objs[88]),/* "X509v3 CRL Number" */ -&(nid_objs[141]),/* "X509v3 CRL Reason Code" */ -&(nid_objs[771]),/* "X509v3 Certificate Issuer" */ -&(nid_objs[89]),/* "X509v3 Certificate Policies" */ -&(nid_objs[140]),/* "X509v3 Delta CRL Indicator" */ -&(nid_objs[126]),/* "X509v3 Extended Key Usage" */ -&(nid_objs[857]),/* "X509v3 Freshest CRL" */ -&(nid_objs[748]),/* "X509v3 Inhibit Any Policy" */ -&(nid_objs[86]),/* "X509v3 Issuer Alternative Name" */ -&(nid_objs[770]),/* "X509v3 Issuing Distrubution Point" */ -&(nid_objs[83]),/* "X509v3 Key Usage" */ -&(nid_objs[666]),/* "X509v3 Name Constraints" */ -&(nid_objs[403]),/* "X509v3 No Revocation Available" */ -&(nid_objs[401]),/* "X509v3 Policy Constraints" */ -&(nid_objs[747]),/* "X509v3 Policy Mappings" */ -&(nid_objs[84]),/* "X509v3 Private Key Usage Period" */ -&(nid_objs[85]),/* "X509v3 Subject Alternative Name" */ -&(nid_objs[769]),/* "X509v3 Subject Directory Attributes" */ -&(nid_objs[82]),/* "X509v3 Subject Key Identifier" */ -&(nid_objs[184]),/* "X9.57" */ -&(nid_objs[185]),/* "X9.57 CM ?" */ -&(nid_objs[478]),/* "aRecord" */ -&(nid_objs[289]),/* "aaControls" */ -&(nid_objs[287]),/* "ac-auditEntity" */ -&(nid_objs[397]),/* "ac-proxying" */ -&(nid_objs[288]),/* "ac-targeting" */ -&(nid_objs[446]),/* "account" */ -&(nid_objs[364]),/* "ad dvcs" */ -&(nid_objs[606]),/* "additional verification" */ -&(nid_objs[419]),/* "aes-128-cbc" */ -&(nid_objs[421]),/* "aes-128-cfb" */ -&(nid_objs[650]),/* "aes-128-cfb1" */ -&(nid_objs[653]),/* "aes-128-cfb8" */ -&(nid_objs[418]),/* "aes-128-ecb" */ -&(nid_objs[420]),/* "aes-128-ofb" */ -&(nid_objs[423]),/* "aes-192-cbc" */ -&(nid_objs[425]),/* "aes-192-cfb" */ -&(nid_objs[651]),/* "aes-192-cfb1" */ -&(nid_objs[654]),/* "aes-192-cfb8" */ -&(nid_objs[422]),/* "aes-192-ecb" */ -&(nid_objs[424]),/* "aes-192-ofb" */ -&(nid_objs[427]),/* "aes-256-cbc" */ -&(nid_objs[429]),/* "aes-256-cfb" */ -&(nid_objs[652]),/* "aes-256-cfb1" */ -&(nid_objs[655]),/* "aes-256-cfb8" */ -&(nid_objs[426]),/* "aes-256-ecb" */ -&(nid_objs[428]),/* "aes-256-ofb" */ -&(nid_objs[376]),/* "algorithm" */ -&(nid_objs[484]),/* "associatedDomain" */ -&(nid_objs[485]),/* "associatedName" */ -&(nid_objs[501]),/* "audio" */ -&(nid_objs[882]),/* "authorityRevocationList" */ -&(nid_objs[91]),/* "bf-cbc" */ -&(nid_objs[93]),/* "bf-cfb" */ -&(nid_objs[92]),/* "bf-ecb" */ -&(nid_objs[94]),/* "bf-ofb" */ -&(nid_objs[494]),/* "buildingName" */ -&(nid_objs[860]),/* "businessCategory" */ -&(nid_objs[691]),/* "c2onb191v4" */ -&(nid_objs[692]),/* "c2onb191v5" */ -&(nid_objs[697]),/* "c2onb239v4" */ -&(nid_objs[698]),/* "c2onb239v5" */ -&(nid_objs[684]),/* "c2pnb163v1" */ -&(nid_objs[685]),/* "c2pnb163v2" */ -&(nid_objs[686]),/* "c2pnb163v3" */ -&(nid_objs[687]),/* "c2pnb176v1" */ -&(nid_objs[693]),/* "c2pnb208w1" */ -&(nid_objs[699]),/* "c2pnb272w1" */ -&(nid_objs[700]),/* "c2pnb304w1" */ -&(nid_objs[702]),/* "c2pnb368w1" */ -&(nid_objs[688]),/* "c2tnb191v1" */ -&(nid_objs[689]),/* "c2tnb191v2" */ -&(nid_objs[690]),/* "c2tnb191v3" */ -&(nid_objs[694]),/* "c2tnb239v1" */ -&(nid_objs[695]),/* "c2tnb239v2" */ -&(nid_objs[696]),/* "c2tnb239v3" */ -&(nid_objs[701]),/* "c2tnb359v1" */ -&(nid_objs[703]),/* "c2tnb431r1" */ -&(nid_objs[881]),/* "cACertificate" */ -&(nid_objs[483]),/* "cNAMERecord" */ -&(nid_objs[751]),/* "camellia-128-cbc" */ -&(nid_objs[757]),/* "camellia-128-cfb" */ -&(nid_objs[760]),/* "camellia-128-cfb1" */ -&(nid_objs[763]),/* "camellia-128-cfb8" */ -&(nid_objs[754]),/* "camellia-128-ecb" */ -&(nid_objs[766]),/* "camellia-128-ofb" */ -&(nid_objs[752]),/* "camellia-192-cbc" */ -&(nid_objs[758]),/* "camellia-192-cfb" */ -&(nid_objs[761]),/* "camellia-192-cfb1" */ -&(nid_objs[764]),/* "camellia-192-cfb8" */ -&(nid_objs[755]),/* "camellia-192-ecb" */ -&(nid_objs[767]),/* "camellia-192-ofb" */ -&(nid_objs[753]),/* "camellia-256-cbc" */ -&(nid_objs[759]),/* "camellia-256-cfb" */ -&(nid_objs[762]),/* "camellia-256-cfb1" */ -&(nid_objs[765]),/* "camellia-256-cfb8" */ -&(nid_objs[756]),/* "camellia-256-ecb" */ -&(nid_objs[768]),/* "camellia-256-ofb" */ -&(nid_objs[443]),/* "caseIgnoreIA5StringSyntax" */ -&(nid_objs[108]),/* "cast5-cbc" */ -&(nid_objs[110]),/* "cast5-cfb" */ -&(nid_objs[109]),/* "cast5-ecb" */ -&(nid_objs[111]),/* "cast5-ofb" */ -&(nid_objs[152]),/* "certBag" */ -&(nid_objs[677]),/* "certicom-arc" */ -&(nid_objs[517]),/* "certificate extensions" */ -&(nid_objs[883]),/* "certificateRevocationList" */ -&(nid_objs[54]),/* "challengePassword" */ -&(nid_objs[407]),/* "characteristic-two-field" */ -&(nid_objs[395]),/* "clearance" */ -&(nid_objs[633]),/* "cleartext track 2" */ -&(nid_objs[13]),/* "commonName" */ -&(nid_objs[513]),/* "content types" */ -&(nid_objs[50]),/* "contentType" */ -&(nid_objs[53]),/* "countersignature" */ -&(nid_objs[14]),/* "countryName" */ -&(nid_objs[153]),/* "crlBag" */ -&(nid_objs[884]),/* "crossCertificatePair" */ -&(nid_objs[806]),/* "cryptocom" */ -&(nid_objs[805]),/* "cryptopro" */ -&(nid_objs[500]),/* "dITRedirect" */ -&(nid_objs[451]),/* "dNSDomain" */ -&(nid_objs[495]),/* "dSAQuality" */ -&(nid_objs[434]),/* "data" */ -&(nid_objs[390]),/* "dcObject" */ -&(nid_objs[891]),/* "deltaRevocationList" */ -&(nid_objs[31]),/* "des-cbc" */ -&(nid_objs[643]),/* "des-cdmf" */ -&(nid_objs[30]),/* "des-cfb" */ -&(nid_objs[656]),/* "des-cfb1" */ -&(nid_objs[657]),/* "des-cfb8" */ -&(nid_objs[29]),/* "des-ecb" */ -&(nid_objs[32]),/* "des-ede" */ -&(nid_objs[43]),/* "des-ede-cbc" */ -&(nid_objs[60]),/* "des-ede-cfb" */ -&(nid_objs[62]),/* "des-ede-ofb" */ -&(nid_objs[33]),/* "des-ede3" */ -&(nid_objs[44]),/* "des-ede3-cbc" */ -&(nid_objs[61]),/* "des-ede3-cfb" */ -&(nid_objs[658]),/* "des-ede3-cfb1" */ -&(nid_objs[659]),/* "des-ede3-cfb8" */ -&(nid_objs[63]),/* "des-ede3-ofb" */ -&(nid_objs[45]),/* "des-ofb" */ -&(nid_objs[107]),/* "description" */ -&(nid_objs[871]),/* "destinationIndicator" */ -&(nid_objs[80]),/* "desx-cbc" */ -&(nid_objs[28]),/* "dhKeyAgreement" */ -&(nid_objs[11]),/* "directory services (X.500)" */ -&(nid_objs[378]),/* "directory services - algorithms" */ -&(nid_objs[887]),/* "distinguishedName" */ -&(nid_objs[892]),/* "dmdName" */ -&(nid_objs[174]),/* "dnQualifier" */ -&(nid_objs[447]),/* "document" */ -&(nid_objs[471]),/* "documentAuthor" */ -&(nid_objs[468]),/* "documentIdentifier" */ -&(nid_objs[472]),/* "documentLocation" */ -&(nid_objs[502]),/* "documentPublisher" */ -&(nid_objs[449]),/* "documentSeries" */ -&(nid_objs[469]),/* "documentTitle" */ -&(nid_objs[470]),/* "documentVersion" */ -&(nid_objs[380]),/* "dod" */ -&(nid_objs[391]),/* "domainComponent" */ -&(nid_objs[452]),/* "domainRelatedObject" */ -&(nid_objs[116]),/* "dsaEncryption" */ -&(nid_objs[67]),/* "dsaEncryption-old" */ -&(nid_objs[66]),/* "dsaWithSHA" */ -&(nid_objs[113]),/* "dsaWithSHA1" */ -&(nid_objs[70]),/* "dsaWithSHA1-old" */ -&(nid_objs[802]),/* "dsa_with_SHA224" */ -&(nid_objs[803]),/* "dsa_with_SHA256" */ -&(nid_objs[297]),/* "dvcs" */ -&(nid_objs[791]),/* "ecdsa-with-Recommended" */ -&(nid_objs[416]),/* "ecdsa-with-SHA1" */ -&(nid_objs[793]),/* "ecdsa-with-SHA224" */ -&(nid_objs[794]),/* "ecdsa-with-SHA256" */ -&(nid_objs[795]),/* "ecdsa-with-SHA384" */ -&(nid_objs[796]),/* "ecdsa-with-SHA512" */ -&(nid_objs[792]),/* "ecdsa-with-Specified" */ -&(nid_objs[48]),/* "emailAddress" */ -&(nid_objs[632]),/* "encrypted track 2" */ -&(nid_objs[885]),/* "enhancedSearchGuide" */ -&(nid_objs[56]),/* "extendedCertificateAttributes" */ -&(nid_objs[867]),/* "facsimileTelephoneNumber" */ -&(nid_objs[462]),/* "favouriteDrink" */ -&(nid_objs[453]),/* "friendlyCountry" */ -&(nid_objs[490]),/* "friendlyCountryName" */ -&(nid_objs[156]),/* "friendlyName" */ -&(nid_objs[631]),/* "generate cryptogram" */ -&(nid_objs[509]),/* "generationQualifier" */ -&(nid_objs[601]),/* "generic cryptogram" */ -&(nid_objs[99]),/* "givenName" */ -&(nid_objs[814]),/* "gost89-cnt" */ -&(nid_objs[855]),/* "hmac" */ -&(nid_objs[780]),/* "hmac-md5" */ -&(nid_objs[781]),/* "hmac-sha1" */ -&(nid_objs[797]),/* "hmacWithMD5" */ -&(nid_objs[163]),/* "hmacWithSHA1" */ -&(nid_objs[798]),/* "hmacWithSHA224" */ -&(nid_objs[799]),/* "hmacWithSHA256" */ -&(nid_objs[800]),/* "hmacWithSHA384" */ -&(nid_objs[801]),/* "hmacWithSHA512" */ -&(nid_objs[486]),/* "homePostalAddress" */ -&(nid_objs[473]),/* "homeTelephoneNumber" */ -&(nid_objs[466]),/* "host" */ -&(nid_objs[889]),/* "houseIdentifier" */ -&(nid_objs[442]),/* "iA5StringSyntax" */ -&(nid_objs[381]),/* "iana" */ -&(nid_objs[824]),/* "id-Gost28147-89-CryptoPro-A-ParamSet" */ -&(nid_objs[825]),/* "id-Gost28147-89-CryptoPro-B-ParamSet" */ -&(nid_objs[826]),/* "id-Gost28147-89-CryptoPro-C-ParamSet" */ -&(nid_objs[827]),/* "id-Gost28147-89-CryptoPro-D-ParamSet" */ -&(nid_objs[819]),/* "id-Gost28147-89-CryptoPro-KeyMeshing" */ -&(nid_objs[829]),/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ -&(nid_objs[828]),/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ -&(nid_objs[830]),/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ -&(nid_objs[820]),/* "id-Gost28147-89-None-KeyMeshing" */ -&(nid_objs[823]),/* "id-Gost28147-89-TestParamSet" */ -&(nid_objs[840]),/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ -&(nid_objs[841]),/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ -&(nid_objs[842]),/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ -&(nid_objs[843]),/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ -&(nid_objs[844]),/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ -&(nid_objs[839]),/* "id-GostR3410-2001-TestParamSet" */ -&(nid_objs[832]),/* "id-GostR3410-94-CryptoPro-A-ParamSet" */ -&(nid_objs[833]),/* "id-GostR3410-94-CryptoPro-B-ParamSet" */ -&(nid_objs[834]),/* "id-GostR3410-94-CryptoPro-C-ParamSet" */ -&(nid_objs[835]),/* "id-GostR3410-94-CryptoPro-D-ParamSet" */ -&(nid_objs[836]),/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ -&(nid_objs[837]),/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ -&(nid_objs[838]),/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ -&(nid_objs[831]),/* "id-GostR3410-94-TestParamSet" */ -&(nid_objs[845]),/* "id-GostR3410-94-a" */ -&(nid_objs[846]),/* "id-GostR3410-94-aBis" */ -&(nid_objs[847]),/* "id-GostR3410-94-b" */ -&(nid_objs[848]),/* "id-GostR3410-94-bBis" */ -&(nid_objs[822]),/* "id-GostR3411-94-CryptoProParamSet" */ -&(nid_objs[821]),/* "id-GostR3411-94-TestParamSet" */ -&(nid_objs[266]),/* "id-aca" */ -&(nid_objs[355]),/* "id-aca-accessIdentity" */ -&(nid_objs[354]),/* "id-aca-authenticationInfo" */ -&(nid_objs[356]),/* "id-aca-chargingIdentity" */ -&(nid_objs[399]),/* "id-aca-encAttrs" */ -&(nid_objs[357]),/* "id-aca-group" */ -&(nid_objs[358]),/* "id-aca-role" */ -&(nid_objs[176]),/* "id-ad" */ -&(nid_objs[788]),/* "id-aes128-wrap" */ -&(nid_objs[789]),/* "id-aes192-wrap" */ -&(nid_objs[790]),/* "id-aes256-wrap" */ -&(nid_objs[262]),/* "id-alg" */ -&(nid_objs[323]),/* "id-alg-des40" */ -&(nid_objs[326]),/* "id-alg-dh-pop" */ -&(nid_objs[325]),/* "id-alg-dh-sig-hmac-sha1" */ -&(nid_objs[324]),/* "id-alg-noSignature" */ -&(nid_objs[268]),/* "id-cct" */ -&(nid_objs[361]),/* "id-cct-PKIData" */ -&(nid_objs[362]),/* "id-cct-PKIResponse" */ -&(nid_objs[360]),/* "id-cct-crs" */ -&(nid_objs[81]),/* "id-ce" */ -&(nid_objs[680]),/* "id-characteristic-two-basis" */ -&(nid_objs[263]),/* "id-cmc" */ -&(nid_objs[334]),/* "id-cmc-addExtensions" */ -&(nid_objs[346]),/* "id-cmc-confirmCertAcceptance" */ -&(nid_objs[330]),/* "id-cmc-dataReturn" */ -&(nid_objs[336]),/* "id-cmc-decryptedPOP" */ -&(nid_objs[335]),/* "id-cmc-encryptedPOP" */ -&(nid_objs[339]),/* "id-cmc-getCRL" */ -&(nid_objs[338]),/* "id-cmc-getCert" */ -&(nid_objs[328]),/* "id-cmc-identification" */ -&(nid_objs[329]),/* "id-cmc-identityProof" */ -&(nid_objs[337]),/* "id-cmc-lraPOPWitness" */ -&(nid_objs[344]),/* "id-cmc-popLinkRandom" */ -&(nid_objs[345]),/* "id-cmc-popLinkWitness" */ -&(nid_objs[343]),/* "id-cmc-queryPending" */ -&(nid_objs[333]),/* "id-cmc-recipientNonce" */ -&(nid_objs[341]),/* "id-cmc-regInfo" */ -&(nid_objs[342]),/* "id-cmc-responseInfo" */ -&(nid_objs[340]),/* "id-cmc-revokeRequest" */ -&(nid_objs[332]),/* "id-cmc-senderNonce" */ -&(nid_objs[327]),/* "id-cmc-statusInfo" */ -&(nid_objs[331]),/* "id-cmc-transactionId" */ -&(nid_objs[787]),/* "id-ct-asciiTextWithCRLF" */ -&(nid_objs[408]),/* "id-ecPublicKey" */ -&(nid_objs[508]),/* "id-hex-multipart-message" */ -&(nid_objs[507]),/* "id-hex-partial-message" */ -&(nid_objs[260]),/* "id-it" */ -&(nid_objs[302]),/* "id-it-caKeyUpdateInfo" */ -&(nid_objs[298]),/* "id-it-caProtEncCert" */ -&(nid_objs[311]),/* "id-it-confirmWaitTime" */ -&(nid_objs[303]),/* "id-it-currentCRL" */ -&(nid_objs[300]),/* "id-it-encKeyPairTypes" */ -&(nid_objs[310]),/* "id-it-implicitConfirm" */ -&(nid_objs[308]),/* "id-it-keyPairParamRep" */ -&(nid_objs[307]),/* "id-it-keyPairParamReq" */ -&(nid_objs[312]),/* "id-it-origPKIMessage" */ -&(nid_objs[301]),/* "id-it-preferredSymmAlg" */ -&(nid_objs[309]),/* "id-it-revPassphrase" */ -&(nid_objs[299]),/* "id-it-signKeyPairTypes" */ -&(nid_objs[305]),/* "id-it-subscriptionRequest" */ -&(nid_objs[306]),/* "id-it-subscriptionResponse" */ -&(nid_objs[784]),/* "id-it-suppLangTags" */ -&(nid_objs[304]),/* "id-it-unsupportedOIDs" */ -&(nid_objs[128]),/* "id-kp" */ -&(nid_objs[280]),/* "id-mod-attribute-cert" */ -&(nid_objs[274]),/* "id-mod-cmc" */ -&(nid_objs[277]),/* "id-mod-cmp" */ -&(nid_objs[284]),/* "id-mod-cmp2000" */ -&(nid_objs[273]),/* "id-mod-crmf" */ -&(nid_objs[283]),/* "id-mod-dvcs" */ -&(nid_objs[275]),/* "id-mod-kea-profile-88" */ -&(nid_objs[276]),/* "id-mod-kea-profile-93" */ -&(nid_objs[282]),/* "id-mod-ocsp" */ -&(nid_objs[278]),/* "id-mod-qualified-cert-88" */ -&(nid_objs[279]),/* "id-mod-qualified-cert-93" */ -&(nid_objs[281]),/* "id-mod-timestamp-protocol" */ -&(nid_objs[264]),/* "id-on" */ -&(nid_objs[347]),/* "id-on-personalData" */ -&(nid_objs[265]),/* "id-pda" */ -&(nid_objs[352]),/* "id-pda-countryOfCitizenship" */ -&(nid_objs[353]),/* "id-pda-countryOfResidence" */ -&(nid_objs[348]),/* "id-pda-dateOfBirth" */ -&(nid_objs[351]),/* "id-pda-gender" */ -&(nid_objs[349]),/* "id-pda-placeOfBirth" */ -&(nid_objs[175]),/* "id-pe" */ -&(nid_objs[261]),/* "id-pkip" */ -&(nid_objs[258]),/* "id-pkix-mod" */ -&(nid_objs[269]),/* "id-pkix1-explicit-88" */ -&(nid_objs[271]),/* "id-pkix1-explicit-93" */ -&(nid_objs[270]),/* "id-pkix1-implicit-88" */ -&(nid_objs[272]),/* "id-pkix1-implicit-93" */ -&(nid_objs[662]),/* "id-ppl" */ -&(nid_objs[267]),/* "id-qcs" */ -&(nid_objs[359]),/* "id-qcs-pkixQCSyntax-v1" */ -&(nid_objs[259]),/* "id-qt" */ -&(nid_objs[313]),/* "id-regCtrl" */ -&(nid_objs[316]),/* "id-regCtrl-authenticator" */ -&(nid_objs[319]),/* "id-regCtrl-oldCertID" */ -&(nid_objs[318]),/* "id-regCtrl-pkiArchiveOptions" */ -&(nid_objs[317]),/* "id-regCtrl-pkiPublicationInfo" */ -&(nid_objs[320]),/* "id-regCtrl-protocolEncrKey" */ -&(nid_objs[315]),/* "id-regCtrl-regToken" */ -&(nid_objs[314]),/* "id-regInfo" */ -&(nid_objs[322]),/* "id-regInfo-certReq" */ -&(nid_objs[321]),/* "id-regInfo-utf8Pairs" */ -&(nid_objs[191]),/* "id-smime-aa" */ -&(nid_objs[215]),/* "id-smime-aa-contentHint" */ -&(nid_objs[218]),/* "id-smime-aa-contentIdentifier" */ -&(nid_objs[221]),/* "id-smime-aa-contentReference" */ -&(nid_objs[240]),/* "id-smime-aa-dvcs-dvc" */ -&(nid_objs[217]),/* "id-smime-aa-encapContentType" */ -&(nid_objs[222]),/* "id-smime-aa-encrypKeyPref" */ -&(nid_objs[220]),/* "id-smime-aa-equivalentLabels" */ -&(nid_objs[232]),/* "id-smime-aa-ets-CertificateRefs" */ -&(nid_objs[233]),/* "id-smime-aa-ets-RevocationRefs" */ -&(nid_objs[238]),/* "id-smime-aa-ets-archiveTimeStamp" */ -&(nid_objs[237]),/* "id-smime-aa-ets-certCRLTimestamp" */ -&(nid_objs[234]),/* "id-smime-aa-ets-certValues" */ -&(nid_objs[227]),/* "id-smime-aa-ets-commitmentType" */ -&(nid_objs[231]),/* "id-smime-aa-ets-contentTimestamp" */ -&(nid_objs[236]),/* "id-smime-aa-ets-escTimeStamp" */ -&(nid_objs[230]),/* "id-smime-aa-ets-otherSigCert" */ -&(nid_objs[235]),/* "id-smime-aa-ets-revocationValues" */ -&(nid_objs[226]),/* "id-smime-aa-ets-sigPolicyId" */ -&(nid_objs[229]),/* "id-smime-aa-ets-signerAttr" */ -&(nid_objs[228]),/* "id-smime-aa-ets-signerLocation" */ -&(nid_objs[219]),/* "id-smime-aa-macValue" */ -&(nid_objs[214]),/* "id-smime-aa-mlExpandHistory" */ -&(nid_objs[216]),/* "id-smime-aa-msgSigDigest" */ -&(nid_objs[212]),/* "id-smime-aa-receiptRequest" */ -&(nid_objs[213]),/* "id-smime-aa-securityLabel" */ -&(nid_objs[239]),/* "id-smime-aa-signatureType" */ -&(nid_objs[223]),/* "id-smime-aa-signingCertificate" */ -&(nid_objs[224]),/* "id-smime-aa-smimeEncryptCerts" */ -&(nid_objs[225]),/* "id-smime-aa-timeStampToken" */ -&(nid_objs[192]),/* "id-smime-alg" */ -&(nid_objs[243]),/* "id-smime-alg-3DESwrap" */ -&(nid_objs[246]),/* "id-smime-alg-CMS3DESwrap" */ -&(nid_objs[247]),/* "id-smime-alg-CMSRC2wrap" */ -&(nid_objs[245]),/* "id-smime-alg-ESDH" */ -&(nid_objs[241]),/* "id-smime-alg-ESDHwith3DES" */ -&(nid_objs[242]),/* "id-smime-alg-ESDHwithRC2" */ -&(nid_objs[244]),/* "id-smime-alg-RC2wrap" */ -&(nid_objs[193]),/* "id-smime-cd" */ -&(nid_objs[248]),/* "id-smime-cd-ldap" */ -&(nid_objs[190]),/* "id-smime-ct" */ -&(nid_objs[210]),/* "id-smime-ct-DVCSRequestData" */ -&(nid_objs[211]),/* "id-smime-ct-DVCSResponseData" */ -&(nid_objs[208]),/* "id-smime-ct-TDTInfo" */ -&(nid_objs[207]),/* "id-smime-ct-TSTInfo" */ -&(nid_objs[205]),/* "id-smime-ct-authData" */ -&(nid_objs[786]),/* "id-smime-ct-compressedData" */ -&(nid_objs[209]),/* "id-smime-ct-contentInfo" */ -&(nid_objs[206]),/* "id-smime-ct-publishCert" */ -&(nid_objs[204]),/* "id-smime-ct-receipt" */ -&(nid_objs[195]),/* "id-smime-cti" */ -&(nid_objs[255]),/* "id-smime-cti-ets-proofOfApproval" */ -&(nid_objs[256]),/* "id-smime-cti-ets-proofOfCreation" */ -&(nid_objs[253]),/* "id-smime-cti-ets-proofOfDelivery" */ -&(nid_objs[251]),/* "id-smime-cti-ets-proofOfOrigin" */ -&(nid_objs[252]),/* "id-smime-cti-ets-proofOfReceipt" */ -&(nid_objs[254]),/* "id-smime-cti-ets-proofOfSender" */ -&(nid_objs[189]),/* "id-smime-mod" */ -&(nid_objs[196]),/* "id-smime-mod-cms" */ -&(nid_objs[197]),/* "id-smime-mod-ess" */ -&(nid_objs[202]),/* "id-smime-mod-ets-eSigPolicy-88" */ -&(nid_objs[203]),/* "id-smime-mod-ets-eSigPolicy-97" */ -&(nid_objs[200]),/* "id-smime-mod-ets-eSignature-88" */ -&(nid_objs[201]),/* "id-smime-mod-ets-eSignature-97" */ -&(nid_objs[199]),/* "id-smime-mod-msg-v3" */ -&(nid_objs[198]),/* "id-smime-mod-oid" */ -&(nid_objs[194]),/* "id-smime-spq" */ -&(nid_objs[250]),/* "id-smime-spq-ets-sqt-unotice" */ -&(nid_objs[249]),/* "id-smime-spq-ets-sqt-uri" */ -&(nid_objs[34]),/* "idea-cbc" */ -&(nid_objs[35]),/* "idea-cfb" */ -&(nid_objs[36]),/* "idea-ecb" */ -&(nid_objs[46]),/* "idea-ofb" */ -&(nid_objs[676]),/* "identified-organization" */ -&(nid_objs[461]),/* "info" */ -&(nid_objs[101]),/* "initials" */ -&(nid_objs[869]),/* "internationaliSDNNumber" */ -&(nid_objs[749]),/* "ipsec3" */ -&(nid_objs[750]),/* "ipsec4" */ -&(nid_objs[181]),/* "iso" */ -&(nid_objs[623]),/* "issuer capabilities" */ -&(nid_objs[645]),/* "itu-t" */ -&(nid_objs[492]),/* "janetMailbox" */ -&(nid_objs[646]),/* "joint-iso-itu-t" */ -&(nid_objs[150]),/* "keyBag" */ -&(nid_objs[773]),/* "kisa" */ -&(nid_objs[477]),/* "lastModifiedBy" */ -&(nid_objs[476]),/* "lastModifiedTime" */ -&(nid_objs[157]),/* "localKeyID" */ -&(nid_objs[15]),/* "localityName" */ -&(nid_objs[480]),/* "mXRecord" */ -&(nid_objs[493]),/* "mailPreferenceOption" */ -&(nid_objs[467]),/* "manager" */ -&(nid_objs[ 3]),/* "md2" */ -&(nid_objs[ 7]),/* "md2WithRSAEncryption" */ -&(nid_objs[257]),/* "md4" */ -&(nid_objs[396]),/* "md4WithRSAEncryption" */ -&(nid_objs[ 4]),/* "md5" */ -&(nid_objs[114]),/* "md5-sha1" */ -&(nid_objs[104]),/* "md5WithRSA" */ -&(nid_objs[ 8]),/* "md5WithRSAEncryption" */ -&(nid_objs[95]),/* "mdc2" */ -&(nid_objs[96]),/* "mdc2WithRSA" */ -&(nid_objs[875]),/* "member" */ -&(nid_objs[602]),/* "merchant initiated auth" */ -&(nid_objs[514]),/* "message extensions" */ -&(nid_objs[51]),/* "messageDigest" */ -&(nid_objs[506]),/* "mime-mhs-bodies" */ -&(nid_objs[505]),/* "mime-mhs-headings" */ -&(nid_objs[488]),/* "mobileTelephoneNumber" */ -&(nid_objs[481]),/* "nSRecord" */ -&(nid_objs[173]),/* "name" */ -&(nid_objs[681]),/* "onBasis" */ -&(nid_objs[379]),/* "org" */ -&(nid_objs[17]),/* "organizationName" */ -&(nid_objs[491]),/* "organizationalStatus" */ -&(nid_objs[18]),/* "organizationalUnitName" */ -&(nid_objs[475]),/* "otherMailbox" */ -&(nid_objs[876]),/* "owner" */ -&(nid_objs[489]),/* "pagerTelephoneNumber" */ -&(nid_objs[782]),/* "password based MAC" */ -&(nid_objs[374]),/* "path" */ -&(nid_objs[621]),/* "payment gateway capabilities" */ -&(nid_objs[ 9]),/* "pbeWithMD2AndDES-CBC" */ -&(nid_objs[168]),/* "pbeWithMD2AndRC2-CBC" */ -&(nid_objs[112]),/* "pbeWithMD5AndCast5CBC" */ -&(nid_objs[10]),/* "pbeWithMD5AndDES-CBC" */ -&(nid_objs[169]),/* "pbeWithMD5AndRC2-CBC" */ -&(nid_objs[148]),/* "pbeWithSHA1And128BitRC2-CBC" */ -&(nid_objs[144]),/* "pbeWithSHA1And128BitRC4" */ -&(nid_objs[147]),/* "pbeWithSHA1And2-KeyTripleDES-CBC" */ -&(nid_objs[146]),/* "pbeWithSHA1And3-KeyTripleDES-CBC" */ -&(nid_objs[149]),/* "pbeWithSHA1And40BitRC2-CBC" */ -&(nid_objs[145]),/* "pbeWithSHA1And40BitRC4" */ -&(nid_objs[170]),/* "pbeWithSHA1AndDES-CBC" */ -&(nid_objs[68]),/* "pbeWithSHA1AndRC2-CBC" */ -&(nid_objs[499]),/* "personalSignature" */ -&(nid_objs[487]),/* "personalTitle" */ -&(nid_objs[464]),/* "photo" */ -&(nid_objs[863]),/* "physicalDeliveryOfficeName" */ -&(nid_objs[437]),/* "pilot" */ -&(nid_objs[439]),/* "pilotAttributeSyntax" */ -&(nid_objs[438]),/* "pilotAttributeType" */ -&(nid_objs[479]),/* "pilotAttributeType27" */ -&(nid_objs[456]),/* "pilotDSA" */ -&(nid_objs[441]),/* "pilotGroups" */ -&(nid_objs[444]),/* "pilotObject" */ -&(nid_objs[440]),/* "pilotObjectClass" */ -&(nid_objs[455]),/* "pilotOrganization" */ -&(nid_objs[445]),/* "pilotPerson" */ -&(nid_objs[186]),/* "pkcs1" */ -&(nid_objs[27]),/* "pkcs3" */ -&(nid_objs[187]),/* "pkcs5" */ -&(nid_objs[20]),/* "pkcs7" */ -&(nid_objs[21]),/* "pkcs7-data" */ -&(nid_objs[25]),/* "pkcs7-digestData" */ -&(nid_objs[26]),/* "pkcs7-encryptedData" */ -&(nid_objs[23]),/* "pkcs7-envelopedData" */ -&(nid_objs[24]),/* "pkcs7-signedAndEnvelopedData" */ -&(nid_objs[22]),/* "pkcs7-signedData" */ -&(nid_objs[151]),/* "pkcs8ShroudedKeyBag" */ -&(nid_objs[47]),/* "pkcs9" */ -&(nid_objs[862]),/* "postOfficeBox" */ -&(nid_objs[861]),/* "postalAddress" */ -&(nid_objs[661]),/* "postalCode" */ -&(nid_objs[683]),/* "ppBasis" */ -&(nid_objs[872]),/* "preferredDeliveryMethod" */ -&(nid_objs[873]),/* "presentationAddress" */ -&(nid_objs[406]),/* "prime-field" */ -&(nid_objs[409]),/* "prime192v1" */ -&(nid_objs[410]),/* "prime192v2" */ -&(nid_objs[411]),/* "prime192v3" */ -&(nid_objs[412]),/* "prime239v1" */ -&(nid_objs[413]),/* "prime239v2" */ -&(nid_objs[414]),/* "prime239v3" */ -&(nid_objs[415]),/* "prime256v1" */ -&(nid_objs[886]),/* "protocolInformation" */ -&(nid_objs[510]),/* "pseudonym" */ -&(nid_objs[435]),/* "pss" */ -&(nid_objs[286]),/* "qcStatements" */ -&(nid_objs[457]),/* "qualityLabelledData" */ -&(nid_objs[450]),/* "rFC822localPart" */ -&(nid_objs[98]),/* "rc2-40-cbc" */ -&(nid_objs[166]),/* "rc2-64-cbc" */ -&(nid_objs[37]),/* "rc2-cbc" */ -&(nid_objs[39]),/* "rc2-cfb" */ -&(nid_objs[38]),/* "rc2-ecb" */ -&(nid_objs[40]),/* "rc2-ofb" */ -&(nid_objs[ 5]),/* "rc4" */ -&(nid_objs[97]),/* "rc4-40" */ -&(nid_objs[120]),/* "rc5-cbc" */ -&(nid_objs[122]),/* "rc5-cfb" */ -&(nid_objs[121]),/* "rc5-ecb" */ -&(nid_objs[123]),/* "rc5-ofb" */ -&(nid_objs[870]),/* "registeredAddress" */ -&(nid_objs[460]),/* "rfc822Mailbox" */ -&(nid_objs[117]),/* "ripemd160" */ -&(nid_objs[119]),/* "ripemd160WithRSA" */ -&(nid_objs[400]),/* "role" */ -&(nid_objs[877]),/* "roleOccupant" */ -&(nid_objs[448]),/* "room" */ -&(nid_objs[463]),/* "roomNumber" */ -&(nid_objs[19]),/* "rsa" */ -&(nid_objs[ 6]),/* "rsaEncryption" */ -&(nid_objs[644]),/* "rsaOAEPEncryptionSET" */ -&(nid_objs[377]),/* "rsaSignature" */ -&(nid_objs[124]),/* "run length compression" */ -&(nid_objs[482]),/* "sOARecord" */ -&(nid_objs[155]),/* "safeContentsBag" */ -&(nid_objs[291]),/* "sbgp-autonomousSysNum" */ -&(nid_objs[290]),/* "sbgp-ipAddrBlock" */ -&(nid_objs[292]),/* "sbgp-routerIdentifier" */ -&(nid_objs[159]),/* "sdsiCertificate" */ -&(nid_objs[859]),/* "searchGuide" */ -&(nid_objs[704]),/* "secp112r1" */ -&(nid_objs[705]),/* "secp112r2" */ -&(nid_objs[706]),/* "secp128r1" */ -&(nid_objs[707]),/* "secp128r2" */ -&(nid_objs[708]),/* "secp160k1" */ -&(nid_objs[709]),/* "secp160r1" */ -&(nid_objs[710]),/* "secp160r2" */ -&(nid_objs[711]),/* "secp192k1" */ -&(nid_objs[712]),/* "secp224k1" */ -&(nid_objs[713]),/* "secp224r1" */ -&(nid_objs[714]),/* "secp256k1" */ -&(nid_objs[715]),/* "secp384r1" */ -&(nid_objs[716]),/* "secp521r1" */ -&(nid_objs[154]),/* "secretBag" */ -&(nid_objs[474]),/* "secretary" */ -&(nid_objs[717]),/* "sect113r1" */ -&(nid_objs[718]),/* "sect113r2" */ -&(nid_objs[719]),/* "sect131r1" */ -&(nid_objs[720]),/* "sect131r2" */ -&(nid_objs[721]),/* "sect163k1" */ -&(nid_objs[722]),/* "sect163r1" */ -&(nid_objs[723]),/* "sect163r2" */ -&(nid_objs[724]),/* "sect193r1" */ -&(nid_objs[725]),/* "sect193r2" */ -&(nid_objs[726]),/* "sect233k1" */ -&(nid_objs[727]),/* "sect233r1" */ -&(nid_objs[728]),/* "sect239k1" */ -&(nid_objs[729]),/* "sect283k1" */ -&(nid_objs[730]),/* "sect283r1" */ -&(nid_objs[731]),/* "sect409k1" */ -&(nid_objs[732]),/* "sect409r1" */ -&(nid_objs[733]),/* "sect571k1" */ -&(nid_objs[734]),/* "sect571r1" */ -&(nid_objs[635]),/* "secure device signature" */ -&(nid_objs[878]),/* "seeAlso" */ -&(nid_objs[777]),/* "seed-cbc" */ -&(nid_objs[779]),/* "seed-cfb" */ -&(nid_objs[776]),/* "seed-ecb" */ -&(nid_objs[778]),/* "seed-ofb" */ -&(nid_objs[105]),/* "serialNumber" */ -&(nid_objs[625]),/* "set-addPolicy" */ -&(nid_objs[515]),/* "set-attr" */ -&(nid_objs[518]),/* "set-brand" */ -&(nid_objs[638]),/* "set-brand-AmericanExpress" */ -&(nid_objs[637]),/* "set-brand-Diners" */ -&(nid_objs[636]),/* "set-brand-IATA-ATA" */ -&(nid_objs[639]),/* "set-brand-JCB" */ -&(nid_objs[641]),/* "set-brand-MasterCard" */ -&(nid_objs[642]),/* "set-brand-Novus" */ -&(nid_objs[640]),/* "set-brand-Visa" */ -&(nid_objs[516]),/* "set-policy" */ -&(nid_objs[607]),/* "set-policy-root" */ -&(nid_objs[624]),/* "set-rootKeyThumb" */ -&(nid_objs[620]),/* "setAttr-Cert" */ -&(nid_objs[628]),/* "setAttr-IssCap-CVM" */ -&(nid_objs[630]),/* "setAttr-IssCap-Sig" */ -&(nid_objs[629]),/* "setAttr-IssCap-T2" */ -&(nid_objs[627]),/* "setAttr-Token-B0Prime" */ -&(nid_objs[626]),/* "setAttr-Token-EMV" */ -&(nid_objs[622]),/* "setAttr-TokenType" */ -&(nid_objs[619]),/* "setCext-IssuerCapabilities" */ -&(nid_objs[615]),/* "setCext-PGWYcapabilities" */ -&(nid_objs[616]),/* "setCext-TokenIdentifier" */ -&(nid_objs[618]),/* "setCext-TokenType" */ -&(nid_objs[617]),/* "setCext-Track2Data" */ -&(nid_objs[611]),/* "setCext-cCertRequired" */ -&(nid_objs[609]),/* "setCext-certType" */ -&(nid_objs[608]),/* "setCext-hashedRoot" */ -&(nid_objs[610]),/* "setCext-merchData" */ -&(nid_objs[613]),/* "setCext-setExt" */ -&(nid_objs[614]),/* "setCext-setQualf" */ -&(nid_objs[612]),/* "setCext-tunneling" */ -&(nid_objs[540]),/* "setct-AcqCardCodeMsg" */ -&(nid_objs[576]),/* "setct-AcqCardCodeMsgTBE" */ -&(nid_objs[570]),/* "setct-AuthReqTBE" */ -&(nid_objs[534]),/* "setct-AuthReqTBS" */ -&(nid_objs[527]),/* "setct-AuthResBaggage" */ -&(nid_objs[571]),/* "setct-AuthResTBE" */ -&(nid_objs[572]),/* "setct-AuthResTBEX" */ -&(nid_objs[535]),/* "setct-AuthResTBS" */ -&(nid_objs[536]),/* "setct-AuthResTBSX" */ -&(nid_objs[528]),/* "setct-AuthRevReqBaggage" */ -&(nid_objs[577]),/* "setct-AuthRevReqTBE" */ -&(nid_objs[541]),/* "setct-AuthRevReqTBS" */ -&(nid_objs[529]),/* "setct-AuthRevResBaggage" */ -&(nid_objs[542]),/* "setct-AuthRevResData" */ -&(nid_objs[578]),/* "setct-AuthRevResTBE" */ -&(nid_objs[579]),/* "setct-AuthRevResTBEB" */ -&(nid_objs[543]),/* "setct-AuthRevResTBS" */ -&(nid_objs[573]),/* "setct-AuthTokenTBE" */ -&(nid_objs[537]),/* "setct-AuthTokenTBS" */ -&(nid_objs[600]),/* "setct-BCIDistributionTBS" */ -&(nid_objs[558]),/* "setct-BatchAdminReqData" */ -&(nid_objs[592]),/* "setct-BatchAdminReqTBE" */ -&(nid_objs[559]),/* "setct-BatchAdminResData" */ -&(nid_objs[593]),/* "setct-BatchAdminResTBE" */ -&(nid_objs[599]),/* "setct-CRLNotificationResTBS" */ -&(nid_objs[598]),/* "setct-CRLNotificationTBS" */ -&(nid_objs[580]),/* "setct-CapReqTBE" */ -&(nid_objs[581]),/* "setct-CapReqTBEX" */ -&(nid_objs[544]),/* "setct-CapReqTBS" */ -&(nid_objs[545]),/* "setct-CapReqTBSX" */ -&(nid_objs[546]),/* "setct-CapResData" */ -&(nid_objs[582]),/* "setct-CapResTBE" */ -&(nid_objs[583]),/* "setct-CapRevReqTBE" */ -&(nid_objs[584]),/* "setct-CapRevReqTBEX" */ -&(nid_objs[547]),/* "setct-CapRevReqTBS" */ -&(nid_objs[548]),/* "setct-CapRevReqTBSX" */ -&(nid_objs[549]),/* "setct-CapRevResData" */ -&(nid_objs[585]),/* "setct-CapRevResTBE" */ -&(nid_objs[538]),/* "setct-CapTokenData" */ -&(nid_objs[530]),/* "setct-CapTokenSeq" */ -&(nid_objs[574]),/* "setct-CapTokenTBE" */ -&(nid_objs[575]),/* "setct-CapTokenTBEX" */ -&(nid_objs[539]),/* "setct-CapTokenTBS" */ -&(nid_objs[560]),/* "setct-CardCInitResTBS" */ -&(nid_objs[566]),/* "setct-CertInqReqTBS" */ -&(nid_objs[563]),/* "setct-CertReqData" */ -&(nid_objs[595]),/* "setct-CertReqTBE" */ -&(nid_objs[596]),/* "setct-CertReqTBEX" */ -&(nid_objs[564]),/* "setct-CertReqTBS" */ -&(nid_objs[565]),/* "setct-CertResData" */ -&(nid_objs[597]),/* "setct-CertResTBE" */ -&(nid_objs[586]),/* "setct-CredReqTBE" */ -&(nid_objs[587]),/* "setct-CredReqTBEX" */ -&(nid_objs[550]),/* "setct-CredReqTBS" */ -&(nid_objs[551]),/* "setct-CredReqTBSX" */ -&(nid_objs[552]),/* "setct-CredResData" */ -&(nid_objs[588]),/* "setct-CredResTBE" */ -&(nid_objs[589]),/* "setct-CredRevReqTBE" */ -&(nid_objs[590]),/* "setct-CredRevReqTBEX" */ -&(nid_objs[553]),/* "setct-CredRevReqTBS" */ -&(nid_objs[554]),/* "setct-CredRevReqTBSX" */ -&(nid_objs[555]),/* "setct-CredRevResData" */ -&(nid_objs[591]),/* "setct-CredRevResTBE" */ -&(nid_objs[567]),/* "setct-ErrorTBS" */ -&(nid_objs[526]),/* "setct-HODInput" */ -&(nid_objs[561]),/* "setct-MeAqCInitResTBS" */ -&(nid_objs[522]),/* "setct-OIData" */ -&(nid_objs[519]),/* "setct-PANData" */ -&(nid_objs[521]),/* "setct-PANOnly" */ -&(nid_objs[520]),/* "setct-PANToken" */ -&(nid_objs[556]),/* "setct-PCertReqData" */ -&(nid_objs[557]),/* "setct-PCertResTBS" */ -&(nid_objs[523]),/* "setct-PI" */ -&(nid_objs[532]),/* "setct-PI-TBS" */ -&(nid_objs[524]),/* "setct-PIData" */ -&(nid_objs[525]),/* "setct-PIDataUnsigned" */ -&(nid_objs[568]),/* "setct-PIDualSignedTBE" */ -&(nid_objs[569]),/* "setct-PIUnsignedTBE" */ -&(nid_objs[531]),/* "setct-PInitResData" */ -&(nid_objs[533]),/* "setct-PResData" */ -&(nid_objs[594]),/* "setct-RegFormReqTBE" */ -&(nid_objs[562]),/* "setct-RegFormResTBS" */ -&(nid_objs[604]),/* "setext-pinAny" */ -&(nid_objs[603]),/* "setext-pinSecure" */ -&(nid_objs[605]),/* "setext-track2" */ -&(nid_objs[41]),/* "sha" */ -&(nid_objs[64]),/* "sha1" */ -&(nid_objs[115]),/* "sha1WithRSA" */ -&(nid_objs[65]),/* "sha1WithRSAEncryption" */ -&(nid_objs[675]),/* "sha224" */ -&(nid_objs[671]),/* "sha224WithRSAEncryption" */ -&(nid_objs[672]),/* "sha256" */ -&(nid_objs[668]),/* "sha256WithRSAEncryption" */ -&(nid_objs[673]),/* "sha384" */ -&(nid_objs[669]),/* "sha384WithRSAEncryption" */ -&(nid_objs[674]),/* "sha512" */ -&(nid_objs[670]),/* "sha512WithRSAEncryption" */ -&(nid_objs[42]),/* "shaWithRSAEncryption" */ -&(nid_objs[52]),/* "signingTime" */ -&(nid_objs[454]),/* "simpleSecurityObject" */ -&(nid_objs[496]),/* "singleLevelQuality" */ -&(nid_objs[16]),/* "stateOrProvinceName" */ -&(nid_objs[660]),/* "streetAddress" */ -&(nid_objs[498]),/* "subtreeMaximumQuality" */ -&(nid_objs[497]),/* "subtreeMinimumQuality" */ -&(nid_objs[890]),/* "supportedAlgorithms" */ -&(nid_objs[874]),/* "supportedApplicationContext" */ -&(nid_objs[100]),/* "surname" */ -&(nid_objs[864]),/* "telephoneNumber" */ -&(nid_objs[866]),/* "teletexTerminalIdentifier" */ -&(nid_objs[865]),/* "telexNumber" */ -&(nid_objs[459]),/* "textEncodedORAddress" */ -&(nid_objs[293]),/* "textNotice" */ -&(nid_objs[106]),/* "title" */ -&(nid_objs[682]),/* "tpBasis" */ -&(nid_objs[436]),/* "ucl" */ -&(nid_objs[ 0]),/* "undefined" */ -&(nid_objs[888]),/* "uniqueMember" */ -&(nid_objs[55]),/* "unstructuredAddress" */ -&(nid_objs[49]),/* "unstructuredName" */ -&(nid_objs[880]),/* "userCertificate" */ -&(nid_objs[465]),/* "userClass" */ -&(nid_objs[458]),/* "userId" */ -&(nid_objs[879]),/* "userPassword" */ -&(nid_objs[373]),/* "valid" */ -&(nid_objs[678]),/* "wap" */ -&(nid_objs[679]),/* "wap-wsg" */ -&(nid_objs[735]),/* "wap-wsg-idm-ecid-wtls1" */ -&(nid_objs[743]),/* "wap-wsg-idm-ecid-wtls10" */ -&(nid_objs[744]),/* "wap-wsg-idm-ecid-wtls11" */ -&(nid_objs[745]),/* "wap-wsg-idm-ecid-wtls12" */ -&(nid_objs[736]),/* "wap-wsg-idm-ecid-wtls3" */ -&(nid_objs[737]),/* "wap-wsg-idm-ecid-wtls4" */ -&(nid_objs[738]),/* "wap-wsg-idm-ecid-wtls5" */ -&(nid_objs[739]),/* "wap-wsg-idm-ecid-wtls6" */ -&(nid_objs[740]),/* "wap-wsg-idm-ecid-wtls7" */ -&(nid_objs[741]),/* "wap-wsg-idm-ecid-wtls8" */ -&(nid_objs[742]),/* "wap-wsg-idm-ecid-wtls9" */ -&(nid_objs[804]),/* "whirlpool" */ -&(nid_objs[868]),/* "x121Address" */ -&(nid_objs[503]),/* "x500UniqueIdentifier" */ -&(nid_objs[158]),/* "x509Certificate" */ -&(nid_objs[160]),/* "x509Crl" */ -&(nid_objs[125]),/* "zlib compression" */ +static const unsigned int ln_objs[NUM_LN]={ +363, /* "AD Time Stamping" */ +405, /* "ANSI X9.62" */ +368, /* "Acceptable OCSP Responses" */ +664, /* "Any language" */ +177, /* "Authority Information Access" */ +365, /* "Basic OCSP Response" */ +285, /* "Biometric Info" */ +179, /* "CA Issuers" */ +785, /* "CA Repository" */ +131, /* "Code Signing" */ +783, /* "Diffie-Hellman based MAC" */ +382, /* "Directory" */ +392, /* "Domain" */ +132, /* "E-mail Protection" */ +389, /* "Enterprises" */ +384, /* "Experimental" */ +372, /* "Extended OCSP Status" */ +172, /* "Extension Request" */ +813, /* "GOST 28147-89" */ +849, /* "GOST 28147-89 Cryptocom ParamSet" */ +815, /* "GOST 28147-89 MAC" */ +851, /* "GOST 34.10-2001 Cryptocom" */ +850, /* "GOST 34.10-94 Cryptocom" */ +811, /* "GOST R 34.10-2001" */ +817, /* "GOST R 34.10-2001 DH" */ +812, /* "GOST R 34.10-94" */ +818, /* "GOST R 34.10-94 DH" */ +809, /* "GOST R 34.11-94" */ +816, /* "GOST R 34.11-94 PRF" */ +807, /* "GOST R 34.11-94 with GOST R 34.10-2001" */ +853, /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ +808, /* "GOST R 34.11-94 with GOST R 34.10-94" */ +852, /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ +854, /* "GOST R 3410-2001 Parameter Set Cryptocom" */ +810, /* "HMAC GOST 34.11-94" */ +432, /* "Hold Instruction Call Issuer" */ +430, /* "Hold Instruction Code" */ +431, /* "Hold Instruction None" */ +433, /* "Hold Instruction Reject" */ +634, /* "ICC or token signature" */ +294, /* "IPSec End System" */ +295, /* "IPSec Tunnel" */ +296, /* "IPSec User" */ +182, /* "ISO Member Body" */ +183, /* "ISO US Member Body" */ +667, /* "Independent" */ +665, /* "Inherit all" */ +647, /* "International Organizations" */ +142, /* "Invalidity Date" */ +504, /* "MIME MHS" */ +388, /* "Mail" */ +383, /* "Management" */ +417, /* "Microsoft CSP Name" */ +135, /* "Microsoft Commercial Code Signing" */ +138, /* "Microsoft Encrypted File System" */ +171, /* "Microsoft Extension Request" */ +134, /* "Microsoft Individual Code Signing" */ +856, /* "Microsoft Local Key set" */ +137, /* "Microsoft Server Gated Crypto" */ +648, /* "Microsoft Smartcardlogin" */ +136, /* "Microsoft Trust List Signing" */ +649, /* "Microsoft Universal Principal Name" */ +393, /* "NULL" */ +404, /* "NULL" */ +72, /* "Netscape Base Url" */ +76, /* "Netscape CA Policy Url" */ +74, /* "Netscape CA Revocation Url" */ +71, /* "Netscape Cert Type" */ +58, /* "Netscape Certificate Extension" */ +79, /* "Netscape Certificate Sequence" */ +78, /* "Netscape Comment" */ +57, /* "Netscape Communications Corp." */ +59, /* "Netscape Data Type" */ +75, /* "Netscape Renewal Url" */ +73, /* "Netscape Revocation Url" */ +77, /* "Netscape SSL Server Name" */ +139, /* "Netscape Server Gated Crypto" */ +178, /* "OCSP" */ +370, /* "OCSP Archive Cutoff" */ +367, /* "OCSP CRL ID" */ +369, /* "OCSP No Check" */ +366, /* "OCSP Nonce" */ +371, /* "OCSP Service Locator" */ +180, /* "OCSP Signing" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +858, /* "Permanent Identifier" */ +164, /* "Policy Qualifier CPS" */ +165, /* "Policy Qualifier User Notice" */ +385, /* "Private" */ +663, /* "Proxy Certificate Information" */ + 1, /* "RSA Data Security, Inc." */ + 2, /* "RSA Data Security, Inc. PKCS" */ +188, /* "S/MIME" */ +167, /* "S/MIME Capabilities" */ +387, /* "SNMPv2" */ +512, /* "Secure Electronic Transactions" */ +386, /* "Security" */ +394, /* "Selected Attribute Types" */ +143, /* "Strong Extranet ID" */ +398, /* "Subject Information Access" */ +130, /* "TLS Web Client Authentication" */ +129, /* "TLS Web Server Authentication" */ +133, /* "Time Stamping" */ +375, /* "Trust Root" */ +12, /* "X509" */ +402, /* "X509v3 AC Targeting" */ +746, /* "X509v3 Any Policy" */ +90, /* "X509v3 Authority Key Identifier" */ +87, /* "X509v3 Basic Constraints" */ +103, /* "X509v3 CRL Distribution Points" */ +88, /* "X509v3 CRL Number" */ +141, /* "X509v3 CRL Reason Code" */ +771, /* "X509v3 Certificate Issuer" */ +89, /* "X509v3 Certificate Policies" */ +140, /* "X509v3 Delta CRL Indicator" */ +126, /* "X509v3 Extended Key Usage" */ +857, /* "X509v3 Freshest CRL" */ +748, /* "X509v3 Inhibit Any Policy" */ +86, /* "X509v3 Issuer Alternative Name" */ +770, /* "X509v3 Issuing Distrubution Point" */ +83, /* "X509v3 Key Usage" */ +666, /* "X509v3 Name Constraints" */ +403, /* "X509v3 No Revocation Available" */ +401, /* "X509v3 Policy Constraints" */ +747, /* "X509v3 Policy Mappings" */ +84, /* "X509v3 Private Key Usage Period" */ +85, /* "X509v3 Subject Alternative Name" */ +769, /* "X509v3 Subject Directory Attributes" */ +82, /* "X509v3 Subject Key Identifier" */ +184, /* "X9.57" */ +185, /* "X9.57 CM ?" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +446, /* "account" */ +364, /* "ad dvcs" */ +606, /* "additional verification" */ +419, /* "aes-128-cbc" */ +421, /* "aes-128-cfb" */ +650, /* "aes-128-cfb1" */ +653, /* "aes-128-cfb8" */ +418, /* "aes-128-ecb" */ +420, /* "aes-128-ofb" */ +423, /* "aes-192-cbc" */ +425, /* "aes-192-cfb" */ +651, /* "aes-192-cfb1" */ +654, /* "aes-192-cfb8" */ +422, /* "aes-192-ecb" */ +424, /* "aes-192-ofb" */ +427, /* "aes-256-cbc" */ +429, /* "aes-256-cfb" */ +652, /* "aes-256-cfb1" */ +655, /* "aes-256-cfb8" */ +426, /* "aes-256-ecb" */ +428, /* "aes-256-ofb" */ +376, /* "algorithm" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +882, /* "authorityRevocationList" */ +91, /* "bf-cbc" */ +93, /* "bf-cfb" */ +92, /* "bf-ecb" */ +94, /* "bf-ofb" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +751, /* "camellia-128-cbc" */ +757, /* "camellia-128-cfb" */ +760, /* "camellia-128-cfb1" */ +763, /* "camellia-128-cfb8" */ +754, /* "camellia-128-ecb" */ +766, /* "camellia-128-ofb" */ +752, /* "camellia-192-cbc" */ +758, /* "camellia-192-cfb" */ +761, /* "camellia-192-cfb1" */ +764, /* "camellia-192-cfb8" */ +755, /* "camellia-192-ecb" */ +767, /* "camellia-192-ofb" */ +753, /* "camellia-256-cbc" */ +759, /* "camellia-256-cfb" */ +762, /* "camellia-256-cfb1" */ +765, /* "camellia-256-cfb8" */ +756, /* "camellia-256-ecb" */ +768, /* "camellia-256-ofb" */ +443, /* "caseIgnoreIA5StringSyntax" */ +108, /* "cast5-cbc" */ +110, /* "cast5-cfb" */ +109, /* "cast5-ecb" */ +111, /* "cast5-ofb" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +517, /* "certificate extensions" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +633, /* "cleartext track 2" */ +13, /* "commonName" */ +513, /* "content types" */ +50, /* "contentType" */ +53, /* "countersignature" */ +14, /* "countryName" */ +153, /* "crlBag" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcObject" */ +891, /* "deltaRevocationList" */ +31, /* "des-cbc" */ +643, /* "des-cdmf" */ +30, /* "des-cfb" */ +656, /* "des-cfb1" */ +657, /* "des-cfb8" */ +29, /* "des-ecb" */ +32, /* "des-ede" */ +43, /* "des-ede-cbc" */ +60, /* "des-ede-cfb" */ +62, /* "des-ede-ofb" */ +33, /* "des-ede3" */ +44, /* "des-ede3-cbc" */ +61, /* "des-ede3-cfb" */ +658, /* "des-ede3-cfb1" */ +659, /* "des-ede3-cfb8" */ +63, /* "des-ede3-ofb" */ +45, /* "des-ofb" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +80, /* "desx-cbc" */ +28, /* "dhKeyAgreement" */ +11, /* "directory services (X.500)" */ +378, /* "directory services - algorithms" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +380, /* "dod" */ +391, /* "domainComponent" */ +452, /* "domainRelatedObject" */ +116, /* "dsaEncryption" */ +67, /* "dsaEncryption-old" */ +66, /* "dsaWithSHA" */ +113, /* "dsaWithSHA1" */ +70, /* "dsaWithSHA1-old" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +297, /* "dvcs" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +632, /* "encrypted track 2" */ +885, /* "enhancedSearchGuide" */ +56, /* "extendedCertificateAttributes" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +631, /* "generate cryptogram" */ +509, /* "generationQualifier" */ +601, /* "generic cryptogram" */ +99, /* "givenName" */ +814, /* "gost89-cnt" */ +855, /* "hmac" */ +780, /* "hmac-md5" */ +781, /* "hmac-sha1" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +381, /* "iana" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +788, /* "id-aes128-wrap" */ +789, /* "id-aes192-wrap" */ +790, /* "id-aes256-wrap" */ +262, /* "id-alg" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +787, /* "id-ct-asciiTextWithCRLF" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +34, /* "idea-cbc" */ +35, /* "idea-cfb" */ +36, /* "idea-ecb" */ +46, /* "idea-ofb" */ +676, /* "identified-organization" */ +461, /* "info" */ +101, /* "initials" */ +869, /* "internationaliSDNNumber" */ +749, /* "ipsec3" */ +750, /* "ipsec4" */ +181, /* "iso" */ +623, /* "issuer capabilities" */ +645, /* "itu-t" */ +492, /* "janetMailbox" */ +646, /* "joint-iso-itu-t" */ +150, /* "keyBag" */ +773, /* "kisa" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +15, /* "localityName" */ +480, /* "mXRecord" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ + 3, /* "md2" */ + 7, /* "md2WithRSAEncryption" */ +257, /* "md4" */ +396, /* "md4WithRSAEncryption" */ + 4, /* "md5" */ +114, /* "md5-sha1" */ +104, /* "md5WithRSA" */ + 8, /* "md5WithRSAEncryption" */ +95, /* "mdc2" */ +96, /* "mdc2WithRSA" */ +875, /* "member" */ +602, /* "merchant initiated auth" */ +514, /* "message extensions" */ +51, /* "messageDigest" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +481, /* "nSRecord" */ +173, /* "name" */ +681, /* "onBasis" */ +379, /* "org" */ +17, /* "organizationName" */ +491, /* "organizationalStatus" */ +18, /* "organizationalUnitName" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +489, /* "pagerTelephoneNumber" */ +782, /* "password based MAC" */ +374, /* "path" */ +621, /* "payment gateway capabilities" */ + 9, /* "pbeWithMD2AndDES-CBC" */ +168, /* "pbeWithMD2AndRC2-CBC" */ +112, /* "pbeWithMD5AndCast5CBC" */ +10, /* "pbeWithMD5AndDES-CBC" */ +169, /* "pbeWithMD5AndRC2-CBC" */ +148, /* "pbeWithSHA1And128BitRC2-CBC" */ +144, /* "pbeWithSHA1And128BitRC4" */ +147, /* "pbeWithSHA1And2-KeyTripleDES-CBC" */ +146, /* "pbeWithSHA1And3-KeyTripleDES-CBC" */ +149, /* "pbeWithSHA1And40BitRC2-CBC" */ +145, /* "pbeWithSHA1And40BitRC4" */ +170, /* "pbeWithSHA1AndDES-CBC" */ +68, /* "pbeWithSHA1AndRC2-CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +886, /* "protocolInformation" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +98, /* "rc2-40-cbc" */ +166, /* "rc2-64-cbc" */ +37, /* "rc2-cbc" */ +39, /* "rc2-cfb" */ +38, /* "rc2-ecb" */ +40, /* "rc2-ofb" */ + 5, /* "rc4" */ +97, /* "rc4-40" */ +120, /* "rc5-cbc" */ +122, /* "rc5-cfb" */ +121, /* "rc5-ecb" */ +123, /* "rc5-ofb" */ +870, /* "registeredAddress" */ +460, /* "rfc822Mailbox" */ +117, /* "ripemd160" */ +119, /* "ripemd160WithRSA" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ +19, /* "rsa" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ +124, /* "run length compression" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +290, /* "sbgp-ipAddrBlock" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +635, /* "secure device signature" */ +878, /* "seeAlso" */ +777, /* "seed-cbc" */ +779, /* "seed-cfb" */ +776, /* "seed-ecb" */ +778, /* "seed-ofb" */ +105, /* "serialNumber" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +41, /* "sha" */ +64, /* "sha1" */ +115, /* "sha1WithRSA" */ +65, /* "sha1WithRSAEncryption" */ +675, /* "sha224" */ +671, /* "sha224WithRSAEncryption" */ +672, /* "sha256" */ +668, /* "sha256WithRSAEncryption" */ +673, /* "sha384" */ +669, /* "sha384WithRSAEncryption" */ +674, /* "sha512" */ +670, /* "sha512WithRSAEncryption" */ +42, /* "shaWithRSAEncryption" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +16, /* "stateOrProvinceName" */ +660, /* "streetAddress" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +100, /* "surname" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +106, /* "title" */ +682, /* "tpBasis" */ +436, /* "ucl" */ + 0, /* "undefined" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +458, /* "userId" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +125, /* "zlib compression" */ }; -static ASN1_OBJECT *obj_objs[NUM_OBJ]={ -&(nid_objs[ 0]),/* OBJ_undef 0 */ -&(nid_objs[393]),/* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ -&(nid_objs[404]),/* OBJ_ccitt OBJ_itu_t */ -&(nid_objs[645]),/* OBJ_itu_t 0 */ -&(nid_objs[434]),/* OBJ_data 0 9 */ -&(nid_objs[181]),/* OBJ_iso 1 */ -&(nid_objs[182]),/* OBJ_member_body 1 2 */ -&(nid_objs[379]),/* OBJ_org 1 3 */ -&(nid_objs[676]),/* OBJ_identified_organization 1 3 */ -&(nid_objs[646]),/* OBJ_joint_iso_itu_t 2 */ -&(nid_objs[11]),/* OBJ_X500 2 5 */ -&(nid_objs[647]),/* OBJ_international_organizations 2 23 */ -&(nid_objs[380]),/* OBJ_dod 1 3 6 */ -&(nid_objs[12]),/* OBJ_X509 2 5 4 */ -&(nid_objs[378]),/* OBJ_X500algorithms 2 5 8 */ -&(nid_objs[81]),/* OBJ_id_ce 2 5 29 */ -&(nid_objs[512]),/* OBJ_id_set 2 23 42 */ -&(nid_objs[678]),/* OBJ_wap 2 23 43 */ -&(nid_objs[435]),/* OBJ_pss 0 9 2342 */ -&(nid_objs[183]),/* OBJ_ISO_US 1 2 840 */ -&(nid_objs[381]),/* OBJ_iana 1 3 6 1 */ -&(nid_objs[677]),/* OBJ_certicom_arc 1 3 132 */ -&(nid_objs[394]),/* OBJ_selected_attribute_types 2 5 1 5 */ -&(nid_objs[13]),/* OBJ_commonName 2 5 4 3 */ -&(nid_objs[100]),/* OBJ_surname 2 5 4 4 */ -&(nid_objs[105]),/* OBJ_serialNumber 2 5 4 5 */ -&(nid_objs[14]),/* OBJ_countryName 2 5 4 6 */ -&(nid_objs[15]),/* OBJ_localityName 2 5 4 7 */ -&(nid_objs[16]),/* OBJ_stateOrProvinceName 2 5 4 8 */ -&(nid_objs[660]),/* OBJ_streetAddress 2 5 4 9 */ -&(nid_objs[17]),/* OBJ_organizationName 2 5 4 10 */ -&(nid_objs[18]),/* OBJ_organizationalUnitName 2 5 4 11 */ -&(nid_objs[106]),/* OBJ_title 2 5 4 12 */ -&(nid_objs[107]),/* OBJ_description 2 5 4 13 */ -&(nid_objs[859]),/* OBJ_searchGuide 2 5 4 14 */ -&(nid_objs[860]),/* OBJ_businessCategory 2 5 4 15 */ -&(nid_objs[861]),/* OBJ_postalAddress 2 5 4 16 */ -&(nid_objs[661]),/* OBJ_postalCode 2 5 4 17 */ -&(nid_objs[862]),/* OBJ_postOfficeBox 2 5 4 18 */ -&(nid_objs[863]),/* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ -&(nid_objs[864]),/* OBJ_telephoneNumber 2 5 4 20 */ -&(nid_objs[865]),/* OBJ_telexNumber 2 5 4 21 */ -&(nid_objs[866]),/* OBJ_teletexTerminalIdentifier 2 5 4 22 */ -&(nid_objs[867]),/* OBJ_facsimileTelephoneNumber 2 5 4 23 */ -&(nid_objs[868]),/* OBJ_x121Address 2 5 4 24 */ -&(nid_objs[869]),/* OBJ_internationaliSDNNumber 2 5 4 25 */ -&(nid_objs[870]),/* OBJ_registeredAddress 2 5 4 26 */ -&(nid_objs[871]),/* OBJ_destinationIndicator 2 5 4 27 */ -&(nid_objs[872]),/* OBJ_preferredDeliveryMethod 2 5 4 28 */ -&(nid_objs[873]),/* OBJ_presentationAddress 2 5 4 29 */ -&(nid_objs[874]),/* OBJ_supportedApplicationContext 2 5 4 30 */ -&(nid_objs[875]),/* OBJ_member 2 5 4 31 */ -&(nid_objs[876]),/* OBJ_owner 2 5 4 32 */ -&(nid_objs[877]),/* OBJ_roleOccupant 2 5 4 33 */ -&(nid_objs[878]),/* OBJ_seeAlso 2 5 4 34 */ -&(nid_objs[879]),/* OBJ_userPassword 2 5 4 35 */ -&(nid_objs[880]),/* OBJ_userCertificate 2 5 4 36 */ -&(nid_objs[881]),/* OBJ_cACertificate 2 5 4 37 */ -&(nid_objs[882]),/* OBJ_authorityRevocationList 2 5 4 38 */ -&(nid_objs[883]),/* OBJ_certificateRevocationList 2 5 4 39 */ -&(nid_objs[884]),/* OBJ_crossCertificatePair 2 5 4 40 */ -&(nid_objs[173]),/* OBJ_name 2 5 4 41 */ -&(nid_objs[99]),/* OBJ_givenName 2 5 4 42 */ -&(nid_objs[101]),/* OBJ_initials 2 5 4 43 */ -&(nid_objs[509]),/* OBJ_generationQualifier 2 5 4 44 */ -&(nid_objs[503]),/* OBJ_x500UniqueIdentifier 2 5 4 45 */ -&(nid_objs[174]),/* OBJ_dnQualifier 2 5 4 46 */ -&(nid_objs[885]),/* OBJ_enhancedSearchGuide 2 5 4 47 */ -&(nid_objs[886]),/* OBJ_protocolInformation 2 5 4 48 */ -&(nid_objs[887]),/* OBJ_distinguishedName 2 5 4 49 */ -&(nid_objs[888]),/* OBJ_uniqueMember 2 5 4 50 */ -&(nid_objs[889]),/* OBJ_houseIdentifier 2 5 4 51 */ -&(nid_objs[890]),/* OBJ_supportedAlgorithms 2 5 4 52 */ -&(nid_objs[891]),/* OBJ_deltaRevocationList 2 5 4 53 */ -&(nid_objs[892]),/* OBJ_dmdName 2 5 4 54 */ -&(nid_objs[510]),/* OBJ_pseudonym 2 5 4 65 */ -&(nid_objs[400]),/* OBJ_role 2 5 4 72 */ -&(nid_objs[769]),/* OBJ_subject_directory_attributes 2 5 29 9 */ -&(nid_objs[82]),/* OBJ_subject_key_identifier 2 5 29 14 */ -&(nid_objs[83]),/* OBJ_key_usage 2 5 29 15 */ -&(nid_objs[84]),/* OBJ_private_key_usage_period 2 5 29 16 */ -&(nid_objs[85]),/* OBJ_subject_alt_name 2 5 29 17 */ -&(nid_objs[86]),/* OBJ_issuer_alt_name 2 5 29 18 */ -&(nid_objs[87]),/* OBJ_basic_constraints 2 5 29 19 */ -&(nid_objs[88]),/* OBJ_crl_number 2 5 29 20 */ -&(nid_objs[141]),/* OBJ_crl_reason 2 5 29 21 */ -&(nid_objs[430]),/* OBJ_hold_instruction_code 2 5 29 23 */ -&(nid_objs[142]),/* OBJ_invalidity_date 2 5 29 24 */ -&(nid_objs[140]),/* OBJ_delta_crl 2 5 29 27 */ -&(nid_objs[770]),/* OBJ_issuing_distribution_point 2 5 29 28 */ -&(nid_objs[771]),/* OBJ_certificate_issuer 2 5 29 29 */ -&(nid_objs[666]),/* OBJ_name_constraints 2 5 29 30 */ -&(nid_objs[103]),/* OBJ_crl_distribution_points 2 5 29 31 */ -&(nid_objs[89]),/* OBJ_certificate_policies 2 5 29 32 */ -&(nid_objs[747]),/* OBJ_policy_mappings 2 5 29 33 */ -&(nid_objs[90]),/* OBJ_authority_key_identifier 2 5 29 35 */ -&(nid_objs[401]),/* OBJ_policy_constraints 2 5 29 36 */ -&(nid_objs[126]),/* OBJ_ext_key_usage 2 5 29 37 */ -&(nid_objs[857]),/* OBJ_freshest_crl 2 5 29 46 */ -&(nid_objs[748]),/* OBJ_inhibit_any_policy 2 5 29 54 */ -&(nid_objs[402]),/* OBJ_target_information 2 5 29 55 */ -&(nid_objs[403]),/* OBJ_no_rev_avail 2 5 29 56 */ -&(nid_objs[513]),/* OBJ_set_ctype 2 23 42 0 */ -&(nid_objs[514]),/* OBJ_set_msgExt 2 23 42 1 */ -&(nid_objs[515]),/* OBJ_set_attr 2 23 42 3 */ -&(nid_objs[516]),/* OBJ_set_policy 2 23 42 5 */ -&(nid_objs[517]),/* OBJ_set_certExt 2 23 42 7 */ -&(nid_objs[518]),/* OBJ_set_brand 2 23 42 8 */ -&(nid_objs[679]),/* OBJ_wap_wsg 2 23 43 1 */ -&(nid_objs[382]),/* OBJ_Directory 1 3 6 1 1 */ -&(nid_objs[383]),/* OBJ_Management 1 3 6 1 2 */ -&(nid_objs[384]),/* OBJ_Experimental 1 3 6 1 3 */ -&(nid_objs[385]),/* OBJ_Private 1 3 6 1 4 */ -&(nid_objs[386]),/* OBJ_Security 1 3 6 1 5 */ -&(nid_objs[387]),/* OBJ_SNMPv2 1 3 6 1 6 */ -&(nid_objs[388]),/* OBJ_Mail 1 3 6 1 7 */ -&(nid_objs[376]),/* OBJ_algorithm 1 3 14 3 2 */ -&(nid_objs[395]),/* OBJ_clearance 2 5 1 5 55 */ -&(nid_objs[19]),/* OBJ_rsa 2 5 8 1 1 */ -&(nid_objs[96]),/* OBJ_mdc2WithRSA 2 5 8 3 100 */ -&(nid_objs[95]),/* OBJ_mdc2 2 5 8 3 101 */ -&(nid_objs[746]),/* OBJ_any_policy 2 5 29 32 0 */ -&(nid_objs[519]),/* OBJ_setct_PANData 2 23 42 0 0 */ -&(nid_objs[520]),/* OBJ_setct_PANToken 2 23 42 0 1 */ -&(nid_objs[521]),/* OBJ_setct_PANOnly 2 23 42 0 2 */ -&(nid_objs[522]),/* OBJ_setct_OIData 2 23 42 0 3 */ -&(nid_objs[523]),/* OBJ_setct_PI 2 23 42 0 4 */ -&(nid_objs[524]),/* OBJ_setct_PIData 2 23 42 0 5 */ -&(nid_objs[525]),/* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ -&(nid_objs[526]),/* OBJ_setct_HODInput 2 23 42 0 7 */ -&(nid_objs[527]),/* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ -&(nid_objs[528]),/* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ -&(nid_objs[529]),/* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ -&(nid_objs[530]),/* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ -&(nid_objs[531]),/* OBJ_setct_PInitResData 2 23 42 0 12 */ -&(nid_objs[532]),/* OBJ_setct_PI_TBS 2 23 42 0 13 */ -&(nid_objs[533]),/* OBJ_setct_PResData 2 23 42 0 14 */ -&(nid_objs[534]),/* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ -&(nid_objs[535]),/* OBJ_setct_AuthResTBS 2 23 42 0 17 */ -&(nid_objs[536]),/* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ -&(nid_objs[537]),/* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ -&(nid_objs[538]),/* OBJ_setct_CapTokenData 2 23 42 0 20 */ -&(nid_objs[539]),/* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ -&(nid_objs[540]),/* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ -&(nid_objs[541]),/* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ -&(nid_objs[542]),/* OBJ_setct_AuthRevResData 2 23 42 0 24 */ -&(nid_objs[543]),/* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ -&(nid_objs[544]),/* OBJ_setct_CapReqTBS 2 23 42 0 26 */ -&(nid_objs[545]),/* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ -&(nid_objs[546]),/* OBJ_setct_CapResData 2 23 42 0 28 */ -&(nid_objs[547]),/* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ -&(nid_objs[548]),/* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ -&(nid_objs[549]),/* OBJ_setct_CapRevResData 2 23 42 0 31 */ -&(nid_objs[550]),/* OBJ_setct_CredReqTBS 2 23 42 0 32 */ -&(nid_objs[551]),/* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ -&(nid_objs[552]),/* OBJ_setct_CredResData 2 23 42 0 34 */ -&(nid_objs[553]),/* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ -&(nid_objs[554]),/* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ -&(nid_objs[555]),/* OBJ_setct_CredRevResData 2 23 42 0 37 */ -&(nid_objs[556]),/* OBJ_setct_PCertReqData 2 23 42 0 38 */ -&(nid_objs[557]),/* OBJ_setct_PCertResTBS 2 23 42 0 39 */ -&(nid_objs[558]),/* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ -&(nid_objs[559]),/* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ -&(nid_objs[560]),/* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ -&(nid_objs[561]),/* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ -&(nid_objs[562]),/* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ -&(nid_objs[563]),/* OBJ_setct_CertReqData 2 23 42 0 45 */ -&(nid_objs[564]),/* OBJ_setct_CertReqTBS 2 23 42 0 46 */ -&(nid_objs[565]),/* OBJ_setct_CertResData 2 23 42 0 47 */ -&(nid_objs[566]),/* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ -&(nid_objs[567]),/* OBJ_setct_ErrorTBS 2 23 42 0 49 */ -&(nid_objs[568]),/* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ -&(nid_objs[569]),/* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ -&(nid_objs[570]),/* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ -&(nid_objs[571]),/* OBJ_setct_AuthResTBE 2 23 42 0 53 */ -&(nid_objs[572]),/* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ -&(nid_objs[573]),/* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ -&(nid_objs[574]),/* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ -&(nid_objs[575]),/* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ -&(nid_objs[576]),/* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ -&(nid_objs[577]),/* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ -&(nid_objs[578]),/* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ -&(nid_objs[579]),/* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ -&(nid_objs[580]),/* OBJ_setct_CapReqTBE 2 23 42 0 62 */ -&(nid_objs[581]),/* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ -&(nid_objs[582]),/* OBJ_setct_CapResTBE 2 23 42 0 64 */ -&(nid_objs[583]),/* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ -&(nid_objs[584]),/* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ -&(nid_objs[585]),/* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ -&(nid_objs[586]),/* OBJ_setct_CredReqTBE 2 23 42 0 68 */ -&(nid_objs[587]),/* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ -&(nid_objs[588]),/* OBJ_setct_CredResTBE 2 23 42 0 70 */ -&(nid_objs[589]),/* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ -&(nid_objs[590]),/* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ -&(nid_objs[591]),/* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ -&(nid_objs[592]),/* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ -&(nid_objs[593]),/* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ -&(nid_objs[594]),/* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ -&(nid_objs[595]),/* OBJ_setct_CertReqTBE 2 23 42 0 77 */ -&(nid_objs[596]),/* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ -&(nid_objs[597]),/* OBJ_setct_CertResTBE 2 23 42 0 79 */ -&(nid_objs[598]),/* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ -&(nid_objs[599]),/* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ -&(nid_objs[600]),/* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ -&(nid_objs[601]),/* OBJ_setext_genCrypt 2 23 42 1 1 */ -&(nid_objs[602]),/* OBJ_setext_miAuth 2 23 42 1 3 */ -&(nid_objs[603]),/* OBJ_setext_pinSecure 2 23 42 1 4 */ -&(nid_objs[604]),/* OBJ_setext_pinAny 2 23 42 1 5 */ -&(nid_objs[605]),/* OBJ_setext_track2 2 23 42 1 7 */ -&(nid_objs[606]),/* OBJ_setext_cv 2 23 42 1 8 */ -&(nid_objs[620]),/* OBJ_setAttr_Cert 2 23 42 3 0 */ -&(nid_objs[621]),/* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ -&(nid_objs[622]),/* OBJ_setAttr_TokenType 2 23 42 3 2 */ -&(nid_objs[623]),/* OBJ_setAttr_IssCap 2 23 42 3 3 */ -&(nid_objs[607]),/* OBJ_set_policy_root 2 23 42 5 0 */ -&(nid_objs[608]),/* OBJ_setCext_hashedRoot 2 23 42 7 0 */ -&(nid_objs[609]),/* OBJ_setCext_certType 2 23 42 7 1 */ -&(nid_objs[610]),/* OBJ_setCext_merchData 2 23 42 7 2 */ -&(nid_objs[611]),/* OBJ_setCext_cCertRequired 2 23 42 7 3 */ -&(nid_objs[612]),/* OBJ_setCext_tunneling 2 23 42 7 4 */ -&(nid_objs[613]),/* OBJ_setCext_setExt 2 23 42 7 5 */ -&(nid_objs[614]),/* OBJ_setCext_setQualf 2 23 42 7 6 */ -&(nid_objs[615]),/* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ -&(nid_objs[616]),/* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ -&(nid_objs[617]),/* OBJ_setCext_Track2Data 2 23 42 7 9 */ -&(nid_objs[618]),/* OBJ_setCext_TokenType 2 23 42 7 10 */ -&(nid_objs[619]),/* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ -&(nid_objs[636]),/* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ -&(nid_objs[640]),/* OBJ_set_brand_Visa 2 23 42 8 4 */ -&(nid_objs[641]),/* OBJ_set_brand_MasterCard 2 23 42 8 5 */ -&(nid_objs[637]),/* OBJ_set_brand_Diners 2 23 42 8 30 */ -&(nid_objs[638]),/* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ -&(nid_objs[639]),/* OBJ_set_brand_JCB 2 23 42 8 35 */ -&(nid_objs[805]),/* OBJ_cryptopro 1 2 643 2 2 */ -&(nid_objs[806]),/* OBJ_cryptocom 1 2 643 2 9 */ -&(nid_objs[184]),/* OBJ_X9_57 1 2 840 10040 */ -&(nid_objs[405]),/* OBJ_ansi_X9_62 1 2 840 10045 */ -&(nid_objs[389]),/* OBJ_Enterprises 1 3 6 1 4 1 */ -&(nid_objs[504]),/* OBJ_mime_mhs 1 3 6 1 7 1 */ -&(nid_objs[104]),/* OBJ_md5WithRSA 1 3 14 3 2 3 */ -&(nid_objs[29]),/* OBJ_des_ecb 1 3 14 3 2 6 */ -&(nid_objs[31]),/* OBJ_des_cbc 1 3 14 3 2 7 */ -&(nid_objs[45]),/* OBJ_des_ofb64 1 3 14 3 2 8 */ -&(nid_objs[30]),/* OBJ_des_cfb64 1 3 14 3 2 9 */ -&(nid_objs[377]),/* OBJ_rsaSignature 1 3 14 3 2 11 */ -&(nid_objs[67]),/* OBJ_dsa_2 1 3 14 3 2 12 */ -&(nid_objs[66]),/* OBJ_dsaWithSHA 1 3 14 3 2 13 */ -&(nid_objs[42]),/* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ -&(nid_objs[32]),/* OBJ_des_ede_ecb 1 3 14 3 2 17 */ -&(nid_objs[41]),/* OBJ_sha 1 3 14 3 2 18 */ -&(nid_objs[64]),/* OBJ_sha1 1 3 14 3 2 26 */ -&(nid_objs[70]),/* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ -&(nid_objs[115]),/* OBJ_sha1WithRSA 1 3 14 3 2 29 */ -&(nid_objs[117]),/* OBJ_ripemd160 1 3 36 3 2 1 */ -&(nid_objs[143]),/* OBJ_sxnet 1 3 101 1 4 1 */ -&(nid_objs[721]),/* OBJ_sect163k1 1 3 132 0 1 */ -&(nid_objs[722]),/* OBJ_sect163r1 1 3 132 0 2 */ -&(nid_objs[728]),/* OBJ_sect239k1 1 3 132 0 3 */ -&(nid_objs[717]),/* OBJ_sect113r1 1 3 132 0 4 */ -&(nid_objs[718]),/* OBJ_sect113r2 1 3 132 0 5 */ -&(nid_objs[704]),/* OBJ_secp112r1 1 3 132 0 6 */ -&(nid_objs[705]),/* OBJ_secp112r2 1 3 132 0 7 */ -&(nid_objs[709]),/* OBJ_secp160r1 1 3 132 0 8 */ -&(nid_objs[708]),/* OBJ_secp160k1 1 3 132 0 9 */ -&(nid_objs[714]),/* OBJ_secp256k1 1 3 132 0 10 */ -&(nid_objs[723]),/* OBJ_sect163r2 1 3 132 0 15 */ -&(nid_objs[729]),/* OBJ_sect283k1 1 3 132 0 16 */ -&(nid_objs[730]),/* OBJ_sect283r1 1 3 132 0 17 */ -&(nid_objs[719]),/* OBJ_sect131r1 1 3 132 0 22 */ -&(nid_objs[720]),/* OBJ_sect131r2 1 3 132 0 23 */ -&(nid_objs[724]),/* OBJ_sect193r1 1 3 132 0 24 */ -&(nid_objs[725]),/* OBJ_sect193r2 1 3 132 0 25 */ -&(nid_objs[726]),/* OBJ_sect233k1 1 3 132 0 26 */ -&(nid_objs[727]),/* OBJ_sect233r1 1 3 132 0 27 */ -&(nid_objs[706]),/* OBJ_secp128r1 1 3 132 0 28 */ -&(nid_objs[707]),/* OBJ_secp128r2 1 3 132 0 29 */ -&(nid_objs[710]),/* OBJ_secp160r2 1 3 132 0 30 */ -&(nid_objs[711]),/* OBJ_secp192k1 1 3 132 0 31 */ -&(nid_objs[712]),/* OBJ_secp224k1 1 3 132 0 32 */ -&(nid_objs[713]),/* OBJ_secp224r1 1 3 132 0 33 */ -&(nid_objs[715]),/* OBJ_secp384r1 1 3 132 0 34 */ -&(nid_objs[716]),/* OBJ_secp521r1 1 3 132 0 35 */ -&(nid_objs[731]),/* OBJ_sect409k1 1 3 132 0 36 */ -&(nid_objs[732]),/* OBJ_sect409r1 1 3 132 0 37 */ -&(nid_objs[733]),/* OBJ_sect571k1 1 3 132 0 38 */ -&(nid_objs[734]),/* OBJ_sect571r1 1 3 132 0 39 */ -&(nid_objs[624]),/* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ -&(nid_objs[625]),/* OBJ_set_addPolicy 2 23 42 3 0 1 */ -&(nid_objs[626]),/* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ -&(nid_objs[627]),/* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ -&(nid_objs[628]),/* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ -&(nid_objs[629]),/* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ -&(nid_objs[630]),/* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ -&(nid_objs[642]),/* OBJ_set_brand_Novus 2 23 42 8 6011 */ -&(nid_objs[735]),/* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ -&(nid_objs[736]),/* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ -&(nid_objs[737]),/* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ -&(nid_objs[738]),/* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ -&(nid_objs[739]),/* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ -&(nid_objs[740]),/* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ -&(nid_objs[741]),/* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ -&(nid_objs[742]),/* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ -&(nid_objs[743]),/* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ -&(nid_objs[744]),/* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ -&(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ -&(nid_objs[804]),/* OBJ_whirlpool 1 0 10118 3 0 55 */ -&(nid_objs[124]),/* OBJ_rle_compression 1 1 1 1 666 1 */ -&(nid_objs[773]),/* OBJ_kisa 1 2 410 200004 */ -&(nid_objs[807]),/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ -&(nid_objs[808]),/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ -&(nid_objs[809]),/* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ -&(nid_objs[810]),/* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ -&(nid_objs[811]),/* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ -&(nid_objs[812]),/* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ -&(nid_objs[813]),/* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ -&(nid_objs[815]),/* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ -&(nid_objs[816]),/* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ -&(nid_objs[817]),/* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ -&(nid_objs[818]),/* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ -&(nid_objs[ 1]),/* OBJ_rsadsi 1 2 840 113549 */ -&(nid_objs[185]),/* OBJ_X9cm 1 2 840 10040 4 */ -&(nid_objs[127]),/* OBJ_id_pkix 1 3 6 1 5 5 7 */ -&(nid_objs[505]),/* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ -&(nid_objs[506]),/* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ -&(nid_objs[119]),/* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ -&(nid_objs[631]),/* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ -&(nid_objs[632]),/* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ -&(nid_objs[633]),/* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ -&(nid_objs[634]),/* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ -&(nid_objs[635]),/* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ -&(nid_objs[436]),/* OBJ_ucl 0 9 2342 19200300 */ -&(nid_objs[820]),/* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ -&(nid_objs[819]),/* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ -&(nid_objs[845]),/* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ -&(nid_objs[846]),/* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ -&(nid_objs[847]),/* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ -&(nid_objs[848]),/* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ -&(nid_objs[821]),/* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ -&(nid_objs[822]),/* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ -&(nid_objs[823]),/* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ -&(nid_objs[824]),/* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ -&(nid_objs[825]),/* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ -&(nid_objs[826]),/* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ -&(nid_objs[827]),/* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ -&(nid_objs[828]),/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ -&(nid_objs[829]),/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ -&(nid_objs[830]),/* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ -&(nid_objs[831]),/* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ -&(nid_objs[832]),/* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ -&(nid_objs[833]),/* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ -&(nid_objs[834]),/* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ -&(nid_objs[835]),/* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ -&(nid_objs[836]),/* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ -&(nid_objs[837]),/* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ -&(nid_objs[838]),/* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ -&(nid_objs[839]),/* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ -&(nid_objs[840]),/* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ -&(nid_objs[841]),/* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ -&(nid_objs[842]),/* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ -&(nid_objs[843]),/* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ -&(nid_objs[844]),/* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ -&(nid_objs[ 2]),/* OBJ_pkcs 1 2 840 113549 1 */ -&(nid_objs[431]),/* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ -&(nid_objs[432]),/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ -&(nid_objs[433]),/* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ -&(nid_objs[116]),/* OBJ_dsa 1 2 840 10040 4 1 */ -&(nid_objs[113]),/* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ -&(nid_objs[406]),/* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ -&(nid_objs[407]),/* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ -&(nid_objs[408]),/* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ -&(nid_objs[416]),/* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ -&(nid_objs[791]),/* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ -&(nid_objs[792]),/* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ -&(nid_objs[258]),/* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ -&(nid_objs[175]),/* OBJ_id_pe 1 3 6 1 5 5 7 1 */ -&(nid_objs[259]),/* OBJ_id_qt 1 3 6 1 5 5 7 2 */ -&(nid_objs[128]),/* OBJ_id_kp 1 3 6 1 5 5 7 3 */ -&(nid_objs[260]),/* OBJ_id_it 1 3 6 1 5 5 7 4 */ -&(nid_objs[261]),/* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ -&(nid_objs[262]),/* OBJ_id_alg 1 3 6 1 5 5 7 6 */ -&(nid_objs[263]),/* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ -&(nid_objs[264]),/* OBJ_id_on 1 3 6 1 5 5 7 8 */ -&(nid_objs[265]),/* OBJ_id_pda 1 3 6 1 5 5 7 9 */ -&(nid_objs[266]),/* OBJ_id_aca 1 3 6 1 5 5 7 10 */ -&(nid_objs[267]),/* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ -&(nid_objs[268]),/* OBJ_id_cct 1 3 6 1 5 5 7 12 */ -&(nid_objs[662]),/* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ -&(nid_objs[176]),/* OBJ_id_ad 1 3 6 1 5 5 7 48 */ -&(nid_objs[507]),/* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ -&(nid_objs[508]),/* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ -&(nid_objs[57]),/* OBJ_netscape 2 16 840 1 113730 */ -&(nid_objs[754]),/* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ -&(nid_objs[766]),/* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ -&(nid_objs[757]),/* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ -&(nid_objs[755]),/* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ -&(nid_objs[767]),/* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ -&(nid_objs[758]),/* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ -&(nid_objs[756]),/* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ -&(nid_objs[768]),/* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ -&(nid_objs[759]),/* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ -&(nid_objs[437]),/* OBJ_pilot 0 9 2342 19200300 100 */ -&(nid_objs[776]),/* OBJ_seed_ecb 1 2 410 200004 1 3 */ -&(nid_objs[777]),/* OBJ_seed_cbc 1 2 410 200004 1 4 */ -&(nid_objs[779]),/* OBJ_seed_cfb128 1 2 410 200004 1 5 */ -&(nid_objs[778]),/* OBJ_seed_ofb128 1 2 410 200004 1 6 */ -&(nid_objs[852]),/* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ -&(nid_objs[853]),/* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ -&(nid_objs[850]),/* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ -&(nid_objs[851]),/* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ -&(nid_objs[849]),/* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ -&(nid_objs[854]),/* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ -&(nid_objs[186]),/* OBJ_pkcs1 1 2 840 113549 1 1 */ -&(nid_objs[27]),/* OBJ_pkcs3 1 2 840 113549 1 3 */ -&(nid_objs[187]),/* OBJ_pkcs5 1 2 840 113549 1 5 */ -&(nid_objs[20]),/* OBJ_pkcs7 1 2 840 113549 1 7 */ -&(nid_objs[47]),/* OBJ_pkcs9 1 2 840 113549 1 9 */ -&(nid_objs[ 3]),/* OBJ_md2 1 2 840 113549 2 2 */ -&(nid_objs[257]),/* OBJ_md4 1 2 840 113549 2 4 */ -&(nid_objs[ 4]),/* OBJ_md5 1 2 840 113549 2 5 */ -&(nid_objs[797]),/* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ -&(nid_objs[163]),/* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ -&(nid_objs[798]),/* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ -&(nid_objs[799]),/* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ -&(nid_objs[800]),/* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ -&(nid_objs[801]),/* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ -&(nid_objs[37]),/* OBJ_rc2_cbc 1 2 840 113549 3 2 */ -&(nid_objs[ 5]),/* OBJ_rc4 1 2 840 113549 3 4 */ -&(nid_objs[44]),/* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ -&(nid_objs[120]),/* OBJ_rc5_cbc 1 2 840 113549 3 8 */ -&(nid_objs[643]),/* OBJ_des_cdmf 1 2 840 113549 3 10 */ -&(nid_objs[680]),/* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ -&(nid_objs[684]),/* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ -&(nid_objs[685]),/* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ -&(nid_objs[686]),/* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ -&(nid_objs[687]),/* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ -&(nid_objs[688]),/* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ -&(nid_objs[689]),/* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ -&(nid_objs[690]),/* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ -&(nid_objs[691]),/* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ -&(nid_objs[692]),/* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ -&(nid_objs[693]),/* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ -&(nid_objs[694]),/* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ -&(nid_objs[695]),/* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ -&(nid_objs[696]),/* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ -&(nid_objs[697]),/* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ -&(nid_objs[698]),/* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ -&(nid_objs[699]),/* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ -&(nid_objs[700]),/* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ -&(nid_objs[701]),/* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ -&(nid_objs[702]),/* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ -&(nid_objs[703]),/* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ -&(nid_objs[409]),/* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ -&(nid_objs[410]),/* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ -&(nid_objs[411]),/* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ -&(nid_objs[412]),/* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ -&(nid_objs[413]),/* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ -&(nid_objs[414]),/* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ -&(nid_objs[415]),/* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ -&(nid_objs[793]),/* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ -&(nid_objs[794]),/* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ -&(nid_objs[795]),/* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ -&(nid_objs[796]),/* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ -&(nid_objs[269]),/* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ -&(nid_objs[270]),/* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ -&(nid_objs[271]),/* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ -&(nid_objs[272]),/* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ -&(nid_objs[273]),/* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ -&(nid_objs[274]),/* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ -&(nid_objs[275]),/* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ -&(nid_objs[276]),/* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ -&(nid_objs[277]),/* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ -&(nid_objs[278]),/* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ -&(nid_objs[279]),/* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ -&(nid_objs[280]),/* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ -&(nid_objs[281]),/* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ -&(nid_objs[282]),/* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ -&(nid_objs[283]),/* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ -&(nid_objs[284]),/* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ -&(nid_objs[177]),/* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ -&(nid_objs[285]),/* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ -&(nid_objs[286]),/* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ -&(nid_objs[287]),/* OBJ_ac_auditEntity 1 3 6 1 5 5 7 1 4 */ -&(nid_objs[288]),/* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ -&(nid_objs[289]),/* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ -&(nid_objs[290]),/* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ -&(nid_objs[291]),/* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ -&(nid_objs[292]),/* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ -&(nid_objs[397]),/* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ -&(nid_objs[398]),/* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ -&(nid_objs[663]),/* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ -&(nid_objs[164]),/* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ -&(nid_objs[165]),/* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ -&(nid_objs[293]),/* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ -&(nid_objs[129]),/* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ -&(nid_objs[130]),/* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ -&(nid_objs[131]),/* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ -&(nid_objs[132]),/* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ -&(nid_objs[294]),/* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ -&(nid_objs[295]),/* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ -&(nid_objs[296]),/* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ -&(nid_objs[133]),/* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ -&(nid_objs[180]),/* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ -&(nid_objs[297]),/* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ -&(nid_objs[298]),/* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ -&(nid_objs[299]),/* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ -&(nid_objs[300]),/* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ -&(nid_objs[301]),/* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ -&(nid_objs[302]),/* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ -&(nid_objs[303]),/* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ -&(nid_objs[304]),/* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ -&(nid_objs[305]),/* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ -&(nid_objs[306]),/* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ -&(nid_objs[307]),/* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ -&(nid_objs[308]),/* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ -&(nid_objs[309]),/* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ -&(nid_objs[310]),/* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ -&(nid_objs[311]),/* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ -&(nid_objs[312]),/* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ -&(nid_objs[784]),/* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ -&(nid_objs[313]),/* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ -&(nid_objs[314]),/* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ -&(nid_objs[323]),/* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ -&(nid_objs[324]),/* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ -&(nid_objs[325]),/* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ -&(nid_objs[326]),/* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ -&(nid_objs[327]),/* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ -&(nid_objs[328]),/* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ -&(nid_objs[329]),/* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ -&(nid_objs[330]),/* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ -&(nid_objs[331]),/* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ -&(nid_objs[332]),/* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ -&(nid_objs[333]),/* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ -&(nid_objs[334]),/* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ -&(nid_objs[335]),/* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ -&(nid_objs[336]),/* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ -&(nid_objs[337]),/* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ -&(nid_objs[338]),/* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ -&(nid_objs[339]),/* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ -&(nid_objs[340]),/* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ -&(nid_objs[341]),/* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ -&(nid_objs[342]),/* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ -&(nid_objs[343]),/* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ -&(nid_objs[344]),/* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ -&(nid_objs[345]),/* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ -&(nid_objs[346]),/* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ -&(nid_objs[347]),/* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ -&(nid_objs[858]),/* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ -&(nid_objs[348]),/* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ -&(nid_objs[349]),/* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ -&(nid_objs[351]),/* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ -&(nid_objs[352]),/* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ -&(nid_objs[353]),/* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ -&(nid_objs[354]),/* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ -&(nid_objs[355]),/* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ -&(nid_objs[356]),/* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ -&(nid_objs[357]),/* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ -&(nid_objs[358]),/* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ -&(nid_objs[399]),/* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ -&(nid_objs[359]),/* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ -&(nid_objs[360]),/* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ -&(nid_objs[361]),/* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ -&(nid_objs[362]),/* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ -&(nid_objs[664]),/* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ -&(nid_objs[665]),/* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ -&(nid_objs[667]),/* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ -&(nid_objs[178]),/* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ -&(nid_objs[179]),/* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ -&(nid_objs[363]),/* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ -&(nid_objs[364]),/* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ -&(nid_objs[785]),/* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ -&(nid_objs[780]),/* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ -&(nid_objs[781]),/* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ -&(nid_objs[58]),/* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ -&(nid_objs[59]),/* OBJ_netscape_data_type 2 16 840 1 113730 2 */ -&(nid_objs[438]),/* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ -&(nid_objs[439]),/* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ -&(nid_objs[440]),/* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ -&(nid_objs[441]),/* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ -&(nid_objs[108]),/* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ -&(nid_objs[112]),/* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ -&(nid_objs[782]),/* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ -&(nid_objs[783]),/* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ -&(nid_objs[ 6]),/* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ -&(nid_objs[ 7]),/* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ -&(nid_objs[396]),/* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ -&(nid_objs[ 8]),/* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ -&(nid_objs[65]),/* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ -&(nid_objs[644]),/* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ -&(nid_objs[668]),/* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ -&(nid_objs[669]),/* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ -&(nid_objs[670]),/* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ -&(nid_objs[671]),/* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ -&(nid_objs[28]),/* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ -&(nid_objs[ 9]),/* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ -&(nid_objs[10]),/* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ -&(nid_objs[168]),/* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ -&(nid_objs[169]),/* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ -&(nid_objs[170]),/* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ -&(nid_objs[68]),/* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ -&(nid_objs[69]),/* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ -&(nid_objs[161]),/* OBJ_pbes2 1 2 840 113549 1 5 13 */ -&(nid_objs[162]),/* OBJ_pbmac1 1 2 840 113549 1 5 14 */ -&(nid_objs[21]),/* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ -&(nid_objs[22]),/* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ -&(nid_objs[23]),/* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ -&(nid_objs[24]),/* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ -&(nid_objs[25]),/* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ -&(nid_objs[26]),/* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ -&(nid_objs[48]),/* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ -&(nid_objs[49]),/* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ -&(nid_objs[50]),/* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ -&(nid_objs[51]),/* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ -&(nid_objs[52]),/* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ -&(nid_objs[53]),/* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ -&(nid_objs[54]),/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ -&(nid_objs[55]),/* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ -&(nid_objs[56]),/* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ -&(nid_objs[172]),/* OBJ_ext_req 1 2 840 113549 1 9 14 */ -&(nid_objs[167]),/* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ -&(nid_objs[188]),/* OBJ_SMIME 1 2 840 113549 1 9 16 */ -&(nid_objs[156]),/* OBJ_friendlyName 1 2 840 113549 1 9 20 */ -&(nid_objs[157]),/* OBJ_localKeyID 1 2 840 113549 1 9 21 */ -&(nid_objs[681]),/* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ -&(nid_objs[682]),/* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ -&(nid_objs[683]),/* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ -&(nid_objs[417]),/* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ -&(nid_objs[856]),/* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ -&(nid_objs[390]),/* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ -&(nid_objs[91]),/* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ -&(nid_objs[315]),/* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ -&(nid_objs[316]),/* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ -&(nid_objs[317]),/* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ -&(nid_objs[318]),/* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ -&(nid_objs[319]),/* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ -&(nid_objs[320]),/* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ -&(nid_objs[321]),/* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ -&(nid_objs[322]),/* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ -&(nid_objs[365]),/* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ -&(nid_objs[366]),/* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ -&(nid_objs[367]),/* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ -&(nid_objs[368]),/* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ -&(nid_objs[369]),/* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ -&(nid_objs[370]),/* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ -&(nid_objs[371]),/* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ -&(nid_objs[372]),/* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ -&(nid_objs[373]),/* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ -&(nid_objs[374]),/* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ -&(nid_objs[375]),/* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ -&(nid_objs[418]),/* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ -&(nid_objs[419]),/* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ -&(nid_objs[420]),/* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ -&(nid_objs[421]),/* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ -&(nid_objs[788]),/* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ -&(nid_objs[422]),/* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ -&(nid_objs[423]),/* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ -&(nid_objs[424]),/* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ -&(nid_objs[425]),/* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ -&(nid_objs[789]),/* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ -&(nid_objs[426]),/* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ -&(nid_objs[427]),/* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ -&(nid_objs[428]),/* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ -&(nid_objs[429]),/* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ -&(nid_objs[790]),/* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ -&(nid_objs[672]),/* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ -&(nid_objs[673]),/* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ -&(nid_objs[674]),/* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ -&(nid_objs[675]),/* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ -&(nid_objs[802]),/* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ -&(nid_objs[803]),/* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ -&(nid_objs[71]),/* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ -&(nid_objs[72]),/* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ -&(nid_objs[73]),/* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ -&(nid_objs[74]),/* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ -&(nid_objs[75]),/* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ -&(nid_objs[76]),/* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ -&(nid_objs[77]),/* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ -&(nid_objs[78]),/* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ -&(nid_objs[79]),/* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ -&(nid_objs[139]),/* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ -&(nid_objs[458]),/* OBJ_userId 0 9 2342 19200300 100 1 1 */ -&(nid_objs[459]),/* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ -&(nid_objs[460]),/* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ -&(nid_objs[461]),/* OBJ_info 0 9 2342 19200300 100 1 4 */ -&(nid_objs[462]),/* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ -&(nid_objs[463]),/* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ -&(nid_objs[464]),/* OBJ_photo 0 9 2342 19200300 100 1 7 */ -&(nid_objs[465]),/* OBJ_userClass 0 9 2342 19200300 100 1 8 */ -&(nid_objs[466]),/* OBJ_host 0 9 2342 19200300 100 1 9 */ -&(nid_objs[467]),/* OBJ_manager 0 9 2342 19200300 100 1 10 */ -&(nid_objs[468]),/* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ -&(nid_objs[469]),/* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ -&(nid_objs[470]),/* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ -&(nid_objs[471]),/* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ -&(nid_objs[472]),/* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ -&(nid_objs[473]),/* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ -&(nid_objs[474]),/* OBJ_secretary 0 9 2342 19200300 100 1 21 */ -&(nid_objs[475]),/* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ -&(nid_objs[476]),/* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ -&(nid_objs[477]),/* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ -&(nid_objs[391]),/* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ -&(nid_objs[478]),/* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ -&(nid_objs[479]),/* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ -&(nid_objs[480]),/* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ -&(nid_objs[481]),/* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ -&(nid_objs[482]),/* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ -&(nid_objs[483]),/* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ -&(nid_objs[484]),/* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ -&(nid_objs[485]),/* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ -&(nid_objs[486]),/* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ -&(nid_objs[487]),/* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ -&(nid_objs[488]),/* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ -&(nid_objs[489]),/* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ -&(nid_objs[490]),/* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ -&(nid_objs[491]),/* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ -&(nid_objs[492]),/* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ -&(nid_objs[493]),/* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ -&(nid_objs[494]),/* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ -&(nid_objs[495]),/* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ -&(nid_objs[496]),/* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ -&(nid_objs[497]),/* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ -&(nid_objs[498]),/* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ -&(nid_objs[499]),/* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ -&(nid_objs[500]),/* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ -&(nid_objs[501]),/* OBJ_audio 0 9 2342 19200300 100 1 55 */ -&(nid_objs[502]),/* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ -&(nid_objs[442]),/* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ -&(nid_objs[443]),/* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ -&(nid_objs[444]),/* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ -&(nid_objs[445]),/* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ -&(nid_objs[446]),/* OBJ_account 0 9 2342 19200300 100 4 5 */ -&(nid_objs[447]),/* OBJ_document 0 9 2342 19200300 100 4 6 */ -&(nid_objs[448]),/* OBJ_room 0 9 2342 19200300 100 4 7 */ -&(nid_objs[449]),/* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ -&(nid_objs[392]),/* OBJ_Domain 0 9 2342 19200300 100 4 13 */ -&(nid_objs[450]),/* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ -&(nid_objs[451]),/* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ -&(nid_objs[452]),/* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ -&(nid_objs[453]),/* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ -&(nid_objs[454]),/* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ -&(nid_objs[455]),/* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ -&(nid_objs[456]),/* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ -&(nid_objs[457]),/* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ -&(nid_objs[189]),/* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ -&(nid_objs[190]),/* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ -&(nid_objs[191]),/* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ -&(nid_objs[192]),/* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ -&(nid_objs[193]),/* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ -&(nid_objs[194]),/* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ -&(nid_objs[195]),/* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ -&(nid_objs[158]),/* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ -&(nid_objs[159]),/* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ -&(nid_objs[160]),/* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ -&(nid_objs[144]),/* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ -&(nid_objs[145]),/* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ -&(nid_objs[146]),/* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ -&(nid_objs[147]),/* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ -&(nid_objs[148]),/* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ -&(nid_objs[149]),/* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ -&(nid_objs[171]),/* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ -&(nid_objs[134]),/* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ -&(nid_objs[135]),/* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ -&(nid_objs[136]),/* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ -&(nid_objs[137]),/* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ -&(nid_objs[138]),/* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ -&(nid_objs[648]),/* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ -&(nid_objs[649]),/* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ -&(nid_objs[751]),/* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ -&(nid_objs[752]),/* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ -&(nid_objs[753]),/* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ -&(nid_objs[196]),/* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ -&(nid_objs[197]),/* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ -&(nid_objs[198]),/* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ -&(nid_objs[199]),/* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ -&(nid_objs[200]),/* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ -&(nid_objs[201]),/* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ -&(nid_objs[202]),/* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ -&(nid_objs[203]),/* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ -&(nid_objs[204]),/* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ -&(nid_objs[205]),/* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ -&(nid_objs[206]),/* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ -&(nid_objs[207]),/* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ -&(nid_objs[208]),/* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ -&(nid_objs[209]),/* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ -&(nid_objs[210]),/* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ -&(nid_objs[211]),/* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ -&(nid_objs[786]),/* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ -&(nid_objs[787]),/* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ -&(nid_objs[212]),/* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ -&(nid_objs[213]),/* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ -&(nid_objs[214]),/* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ -&(nid_objs[215]),/* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ -&(nid_objs[216]),/* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ -&(nid_objs[217]),/* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ -&(nid_objs[218]),/* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ -&(nid_objs[219]),/* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ -&(nid_objs[220]),/* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ -&(nid_objs[221]),/* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ -&(nid_objs[222]),/* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ -&(nid_objs[223]),/* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ -&(nid_objs[224]),/* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ -&(nid_objs[225]),/* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ -&(nid_objs[226]),/* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ -&(nid_objs[227]),/* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ -&(nid_objs[228]),/* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ -&(nid_objs[229]),/* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ -&(nid_objs[230]),/* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ -&(nid_objs[231]),/* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ -&(nid_objs[232]),/* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ -&(nid_objs[233]),/* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ -&(nid_objs[234]),/* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ -&(nid_objs[235]),/* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ -&(nid_objs[236]),/* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ -&(nid_objs[237]),/* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ -&(nid_objs[238]),/* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ -&(nid_objs[239]),/* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ -&(nid_objs[240]),/* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ -&(nid_objs[241]),/* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ -&(nid_objs[242]),/* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ -&(nid_objs[243]),/* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ -&(nid_objs[244]),/* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ -&(nid_objs[245]),/* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ -&(nid_objs[246]),/* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ -&(nid_objs[247]),/* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ -&(nid_objs[125]),/* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ -&(nid_objs[248]),/* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ -&(nid_objs[249]),/* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ -&(nid_objs[250]),/* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ -&(nid_objs[251]),/* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ -&(nid_objs[252]),/* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ -&(nid_objs[253]),/* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ -&(nid_objs[254]),/* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ -&(nid_objs[255]),/* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ -&(nid_objs[256]),/* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ -&(nid_objs[150]),/* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ -&(nid_objs[151]),/* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ -&(nid_objs[152]),/* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ -&(nid_objs[153]),/* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ -&(nid_objs[154]),/* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ -&(nid_objs[155]),/* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ -&(nid_objs[34]),/* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ +static const unsigned int obj_objs[NUM_OBJ]={ + 0, /* OBJ_undef 0 */ +393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ +404, /* OBJ_ccitt OBJ_itu_t */ +645, /* OBJ_itu_t 0 */ +434, /* OBJ_data 0 9 */ +181, /* OBJ_iso 1 */ +182, /* OBJ_member_body 1 2 */ +379, /* OBJ_org 1 3 */ +676, /* OBJ_identified_organization 1 3 */ +646, /* OBJ_joint_iso_itu_t 2 */ +11, /* OBJ_X500 2 5 */ +647, /* OBJ_international_organizations 2 23 */ +380, /* OBJ_dod 1 3 6 */ +12, /* OBJ_X509 2 5 4 */ +378, /* OBJ_X500algorithms 2 5 8 */ +81, /* OBJ_id_ce 2 5 29 */ +512, /* OBJ_id_set 2 23 42 */ +678, /* OBJ_wap 2 23 43 */ +435, /* OBJ_pss 0 9 2342 */ +183, /* OBJ_ISO_US 1 2 840 */ +381, /* OBJ_iana 1 3 6 1 */ +677, /* OBJ_certicom_arc 1 3 132 */ +394, /* OBJ_selected_attribute_types 2 5 1 5 */ +13, /* OBJ_commonName 2 5 4 3 */ +100, /* OBJ_surname 2 5 4 4 */ +105, /* OBJ_serialNumber 2 5 4 5 */ +14, /* OBJ_countryName 2 5 4 6 */ +15, /* OBJ_localityName 2 5 4 7 */ +16, /* OBJ_stateOrProvinceName 2 5 4 8 */ +660, /* OBJ_streetAddress 2 5 4 9 */ +17, /* OBJ_organizationName 2 5 4 10 */ +18, /* OBJ_organizationalUnitName 2 5 4 11 */ +106, /* OBJ_title 2 5 4 12 */ +107, /* OBJ_description 2 5 4 13 */ +859, /* OBJ_searchGuide 2 5 4 14 */ +860, /* OBJ_businessCategory 2 5 4 15 */ +861, /* OBJ_postalAddress 2 5 4 16 */ +661, /* OBJ_postalCode 2 5 4 17 */ +862, /* OBJ_postOfficeBox 2 5 4 18 */ +863, /* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ +864, /* OBJ_telephoneNumber 2 5 4 20 */ +865, /* OBJ_telexNumber 2 5 4 21 */ +866, /* OBJ_teletexTerminalIdentifier 2 5 4 22 */ +867, /* OBJ_facsimileTelephoneNumber 2 5 4 23 */ +868, /* OBJ_x121Address 2 5 4 24 */ +869, /* OBJ_internationaliSDNNumber 2 5 4 25 */ +870, /* OBJ_registeredAddress 2 5 4 26 */ +871, /* OBJ_destinationIndicator 2 5 4 27 */ +872, /* OBJ_preferredDeliveryMethod 2 5 4 28 */ +873, /* OBJ_presentationAddress 2 5 4 29 */ +874, /* OBJ_supportedApplicationContext 2 5 4 30 */ +875, /* OBJ_member 2 5 4 31 */ +876, /* OBJ_owner 2 5 4 32 */ +877, /* OBJ_roleOccupant 2 5 4 33 */ +878, /* OBJ_seeAlso 2 5 4 34 */ +879, /* OBJ_userPassword 2 5 4 35 */ +880, /* OBJ_userCertificate 2 5 4 36 */ +881, /* OBJ_cACertificate 2 5 4 37 */ +882, /* OBJ_authorityRevocationList 2 5 4 38 */ +883, /* OBJ_certificateRevocationList 2 5 4 39 */ +884, /* OBJ_crossCertificatePair 2 5 4 40 */ +173, /* OBJ_name 2 5 4 41 */ +99, /* OBJ_givenName 2 5 4 42 */ +101, /* OBJ_initials 2 5 4 43 */ +509, /* OBJ_generationQualifier 2 5 4 44 */ +503, /* OBJ_x500UniqueIdentifier 2 5 4 45 */ +174, /* OBJ_dnQualifier 2 5 4 46 */ +885, /* OBJ_enhancedSearchGuide 2 5 4 47 */ +886, /* OBJ_protocolInformation 2 5 4 48 */ +887, /* OBJ_distinguishedName 2 5 4 49 */ +888, /* OBJ_uniqueMember 2 5 4 50 */ +889, /* OBJ_houseIdentifier 2 5 4 51 */ +890, /* OBJ_supportedAlgorithms 2 5 4 52 */ +891, /* OBJ_deltaRevocationList 2 5 4 53 */ +892, /* OBJ_dmdName 2 5 4 54 */ +510, /* OBJ_pseudonym 2 5 4 65 */ +400, /* OBJ_role 2 5 4 72 */ +769, /* OBJ_subject_directory_attributes 2 5 29 9 */ +82, /* OBJ_subject_key_identifier 2 5 29 14 */ +83, /* OBJ_key_usage 2 5 29 15 */ +84, /* OBJ_private_key_usage_period 2 5 29 16 */ +85, /* OBJ_subject_alt_name 2 5 29 17 */ +86, /* OBJ_issuer_alt_name 2 5 29 18 */ +87, /* OBJ_basic_constraints 2 5 29 19 */ +88, /* OBJ_crl_number 2 5 29 20 */ +141, /* OBJ_crl_reason 2 5 29 21 */ +430, /* OBJ_hold_instruction_code 2 5 29 23 */ +142, /* OBJ_invalidity_date 2 5 29 24 */ +140, /* OBJ_delta_crl 2 5 29 27 */ +770, /* OBJ_issuing_distribution_point 2 5 29 28 */ +771, /* OBJ_certificate_issuer 2 5 29 29 */ +666, /* OBJ_name_constraints 2 5 29 30 */ +103, /* OBJ_crl_distribution_points 2 5 29 31 */ +89, /* OBJ_certificate_policies 2 5 29 32 */ +747, /* OBJ_policy_mappings 2 5 29 33 */ +90, /* OBJ_authority_key_identifier 2 5 29 35 */ +401, /* OBJ_policy_constraints 2 5 29 36 */ +126, /* OBJ_ext_key_usage 2 5 29 37 */ +857, /* OBJ_freshest_crl 2 5 29 46 */ +748, /* OBJ_inhibit_any_policy 2 5 29 54 */ +402, /* OBJ_target_information 2 5 29 55 */ +403, /* OBJ_no_rev_avail 2 5 29 56 */ +513, /* OBJ_set_ctype 2 23 42 0 */ +514, /* OBJ_set_msgExt 2 23 42 1 */ +515, /* OBJ_set_attr 2 23 42 3 */ +516, /* OBJ_set_policy 2 23 42 5 */ +517, /* OBJ_set_certExt 2 23 42 7 */ +518, /* OBJ_set_brand 2 23 42 8 */ +679, /* OBJ_wap_wsg 2 23 43 1 */ +382, /* OBJ_Directory 1 3 6 1 1 */ +383, /* OBJ_Management 1 3 6 1 2 */ +384, /* OBJ_Experimental 1 3 6 1 3 */ +385, /* OBJ_Private 1 3 6 1 4 */ +386, /* OBJ_Security 1 3 6 1 5 */ +387, /* OBJ_SNMPv2 1 3 6 1 6 */ +388, /* OBJ_Mail 1 3 6 1 7 */ +376, /* OBJ_algorithm 1 3 14 3 2 */ +395, /* OBJ_clearance 2 5 1 5 55 */ +19, /* OBJ_rsa 2 5 8 1 1 */ +96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */ +95, /* OBJ_mdc2 2 5 8 3 101 */ +746, /* OBJ_any_policy 2 5 29 32 0 */ +519, /* OBJ_setct_PANData 2 23 42 0 0 */ +520, /* OBJ_setct_PANToken 2 23 42 0 1 */ +521, /* OBJ_setct_PANOnly 2 23 42 0 2 */ +522, /* OBJ_setct_OIData 2 23 42 0 3 */ +523, /* OBJ_setct_PI 2 23 42 0 4 */ +524, /* OBJ_setct_PIData 2 23 42 0 5 */ +525, /* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ +526, /* OBJ_setct_HODInput 2 23 42 0 7 */ +527, /* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ +528, /* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ +529, /* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ +530, /* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ +531, /* OBJ_setct_PInitResData 2 23 42 0 12 */ +532, /* OBJ_setct_PI_TBS 2 23 42 0 13 */ +533, /* OBJ_setct_PResData 2 23 42 0 14 */ +534, /* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ +535, /* OBJ_setct_AuthResTBS 2 23 42 0 17 */ +536, /* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ +537, /* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ +538, /* OBJ_setct_CapTokenData 2 23 42 0 20 */ +539, /* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ +540, /* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ +541, /* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ +542, /* OBJ_setct_AuthRevResData 2 23 42 0 24 */ +543, /* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ +544, /* OBJ_setct_CapReqTBS 2 23 42 0 26 */ +545, /* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ +546, /* OBJ_setct_CapResData 2 23 42 0 28 */ +547, /* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ +548, /* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ +549, /* OBJ_setct_CapRevResData 2 23 42 0 31 */ +550, /* OBJ_setct_CredReqTBS 2 23 42 0 32 */ +551, /* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ +552, /* OBJ_setct_CredResData 2 23 42 0 34 */ +553, /* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ +554, /* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ +555, /* OBJ_setct_CredRevResData 2 23 42 0 37 */ +556, /* OBJ_setct_PCertReqData 2 23 42 0 38 */ +557, /* OBJ_setct_PCertResTBS 2 23 42 0 39 */ +558, /* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ +559, /* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ +560, /* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ +561, /* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ +562, /* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ +563, /* OBJ_setct_CertReqData 2 23 42 0 45 */ +564, /* OBJ_setct_CertReqTBS 2 23 42 0 46 */ +565, /* OBJ_setct_CertResData 2 23 42 0 47 */ +566, /* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ +567, /* OBJ_setct_ErrorTBS 2 23 42 0 49 */ +568, /* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ +569, /* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ +570, /* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ +571, /* OBJ_setct_AuthResTBE 2 23 42 0 53 */ +572, /* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ +573, /* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ +574, /* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ +575, /* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ +576, /* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ +577, /* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ +578, /* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ +579, /* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ +580, /* OBJ_setct_CapReqTBE 2 23 42 0 62 */ +581, /* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ +582, /* OBJ_setct_CapResTBE 2 23 42 0 64 */ +583, /* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ +584, /* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ +585, /* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ +586, /* OBJ_setct_CredReqTBE 2 23 42 0 68 */ +587, /* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ +588, /* OBJ_setct_CredResTBE 2 23 42 0 70 */ +589, /* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ +590, /* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ +591, /* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ +592, /* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ +593, /* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ +594, /* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ +595, /* OBJ_setct_CertReqTBE 2 23 42 0 77 */ +596, /* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ +597, /* OBJ_setct_CertResTBE 2 23 42 0 79 */ +598, /* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ +599, /* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ +600, /* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ +601, /* OBJ_setext_genCrypt 2 23 42 1 1 */ +602, /* OBJ_setext_miAuth 2 23 42 1 3 */ +603, /* OBJ_setext_pinSecure 2 23 42 1 4 */ +604, /* OBJ_setext_pinAny 2 23 42 1 5 */ +605, /* OBJ_setext_track2 2 23 42 1 7 */ +606, /* OBJ_setext_cv 2 23 42 1 8 */ +620, /* OBJ_setAttr_Cert 2 23 42 3 0 */ +621, /* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ +622, /* OBJ_setAttr_TokenType 2 23 42 3 2 */ +623, /* OBJ_setAttr_IssCap 2 23 42 3 3 */ +607, /* OBJ_set_policy_root 2 23 42 5 0 */ +608, /* OBJ_setCext_hashedRoot 2 23 42 7 0 */ +609, /* OBJ_setCext_certType 2 23 42 7 1 */ +610, /* OBJ_setCext_merchData 2 23 42 7 2 */ +611, /* OBJ_setCext_cCertRequired 2 23 42 7 3 */ +612, /* OBJ_setCext_tunneling 2 23 42 7 4 */ +613, /* OBJ_setCext_setExt 2 23 42 7 5 */ +614, /* OBJ_setCext_setQualf 2 23 42 7 6 */ +615, /* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ +616, /* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ +617, /* OBJ_setCext_Track2Data 2 23 42 7 9 */ +618, /* OBJ_setCext_TokenType 2 23 42 7 10 */ +619, /* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ +636, /* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ +640, /* OBJ_set_brand_Visa 2 23 42 8 4 */ +641, /* OBJ_set_brand_MasterCard 2 23 42 8 5 */ +637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ +638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ +639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ +805, /* OBJ_cryptopro 1 2 643 2 2 */ +806, /* OBJ_cryptocom 1 2 643 2 9 */ +184, /* OBJ_X9_57 1 2 840 10040 */ +405, /* OBJ_ansi_X9_62 1 2 840 10045 */ +389, /* OBJ_Enterprises 1 3 6 1 4 1 */ +504, /* OBJ_mime_mhs 1 3 6 1 7 1 */ +104, /* OBJ_md5WithRSA 1 3 14 3 2 3 */ +29, /* OBJ_des_ecb 1 3 14 3 2 6 */ +31, /* OBJ_des_cbc 1 3 14 3 2 7 */ +45, /* OBJ_des_ofb64 1 3 14 3 2 8 */ +30, /* OBJ_des_cfb64 1 3 14 3 2 9 */ +377, /* OBJ_rsaSignature 1 3 14 3 2 11 */ +67, /* OBJ_dsa_2 1 3 14 3 2 12 */ +66, /* OBJ_dsaWithSHA 1 3 14 3 2 13 */ +42, /* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ +32, /* OBJ_des_ede_ecb 1 3 14 3 2 17 */ +41, /* OBJ_sha 1 3 14 3 2 18 */ +64, /* OBJ_sha1 1 3 14 3 2 26 */ +70, /* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ +115, /* OBJ_sha1WithRSA 1 3 14 3 2 29 */ +117, /* OBJ_ripemd160 1 3 36 3 2 1 */ +143, /* OBJ_sxnet 1 3 101 1 4 1 */ +721, /* OBJ_sect163k1 1 3 132 0 1 */ +722, /* OBJ_sect163r1 1 3 132 0 2 */ +728, /* OBJ_sect239k1 1 3 132 0 3 */ +717, /* OBJ_sect113r1 1 3 132 0 4 */ +718, /* OBJ_sect113r2 1 3 132 0 5 */ +704, /* OBJ_secp112r1 1 3 132 0 6 */ +705, /* OBJ_secp112r2 1 3 132 0 7 */ +709, /* OBJ_secp160r1 1 3 132 0 8 */ +708, /* OBJ_secp160k1 1 3 132 0 9 */ +714, /* OBJ_secp256k1 1 3 132 0 10 */ +723, /* OBJ_sect163r2 1 3 132 0 15 */ +729, /* OBJ_sect283k1 1 3 132 0 16 */ +730, /* OBJ_sect283r1 1 3 132 0 17 */ +719, /* OBJ_sect131r1 1 3 132 0 22 */ +720, /* OBJ_sect131r2 1 3 132 0 23 */ +724, /* OBJ_sect193r1 1 3 132 0 24 */ +725, /* OBJ_sect193r2 1 3 132 0 25 */ +726, /* OBJ_sect233k1 1 3 132 0 26 */ +727, /* OBJ_sect233r1 1 3 132 0 27 */ +706, /* OBJ_secp128r1 1 3 132 0 28 */ +707, /* OBJ_secp128r2 1 3 132 0 29 */ +710, /* OBJ_secp160r2 1 3 132 0 30 */ +711, /* OBJ_secp192k1 1 3 132 0 31 */ +712, /* OBJ_secp224k1 1 3 132 0 32 */ +713, /* OBJ_secp224r1 1 3 132 0 33 */ +715, /* OBJ_secp384r1 1 3 132 0 34 */ +716, /* OBJ_secp521r1 1 3 132 0 35 */ +731, /* OBJ_sect409k1 1 3 132 0 36 */ +732, /* OBJ_sect409r1 1 3 132 0 37 */ +733, /* OBJ_sect571k1 1 3 132 0 38 */ +734, /* OBJ_sect571r1 1 3 132 0 39 */ +624, /* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ +625, /* OBJ_set_addPolicy 2 23 42 3 0 1 */ +626, /* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ +627, /* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ +628, /* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ +629, /* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ +630, /* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ +642, /* OBJ_set_brand_Novus 2 23 42 8 6011 */ +735, /* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ +736, /* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ +737, /* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ +738, /* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ +739, /* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ +740, /* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ +741, /* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ +742, /* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ +743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ +744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ +745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ +804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ +124, /* OBJ_rle_compression 1 1 1 1 666 1 */ +773, /* OBJ_kisa 1 2 410 200004 */ +807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ +808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ +809, /* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ +810, /* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ +811, /* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ +812, /* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ +813, /* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ +815, /* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ +816, /* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ +817, /* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ +818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ + 1, /* OBJ_rsadsi 1 2 840 113549 */ +185, /* OBJ_X9cm 1 2 840 10040 4 */ +127, /* OBJ_id_pkix 1 3 6 1 5 5 7 */ +505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ +506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ +119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ +631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ +632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ +633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ +634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ +635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ +436, /* OBJ_ucl 0 9 2342 19200300 */ +820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ +819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ +845, /* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ +846, /* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ +847, /* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ +848, /* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ +821, /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ +822, /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ +823, /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ +824, /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ +825, /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ +826, /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ +827, /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ +828, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ +829, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ +830, /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ +831, /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ +832, /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ +833, /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ +834, /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ +835, /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ +836, /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ +837, /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ +838, /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ +839, /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ +840, /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ +841, /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ +842, /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ +843, /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ +844, /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ + 2, /* OBJ_pkcs 1 2 840 113549 1 */ +431, /* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ +432, /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ +433, /* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ +116, /* OBJ_dsa 1 2 840 10040 4 1 */ +113, /* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ +406, /* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ +407, /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ +408, /* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ +416, /* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ +791, /* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ +792, /* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ +258, /* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ +175, /* OBJ_id_pe 1 3 6 1 5 5 7 1 */ +259, /* OBJ_id_qt 1 3 6 1 5 5 7 2 */ +128, /* OBJ_id_kp 1 3 6 1 5 5 7 3 */ +260, /* OBJ_id_it 1 3 6 1 5 5 7 4 */ +261, /* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ +262, /* OBJ_id_alg 1 3 6 1 5 5 7 6 */ +263, /* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ +264, /* OBJ_id_on 1 3 6 1 5 5 7 8 */ +265, /* OBJ_id_pda 1 3 6 1 5 5 7 9 */ +266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ +267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ +268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ +662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ +176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ +507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ +508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ +57, /* OBJ_netscape 2 16 840 1 113730 */ +754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ +766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ +757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ +755, /* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ +767, /* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ +758, /* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ +756, /* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ +768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ +759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ +437, /* OBJ_pilot 0 9 2342 19200300 100 */ +776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ +777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ +779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ +778, /* OBJ_seed_ofb128 1 2 410 200004 1 6 */ +852, /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ +853, /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ +850, /* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ +851, /* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ +849, /* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ +854, /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ +186, /* OBJ_pkcs1 1 2 840 113549 1 1 */ +27, /* OBJ_pkcs3 1 2 840 113549 1 3 */ +187, /* OBJ_pkcs5 1 2 840 113549 1 5 */ +20, /* OBJ_pkcs7 1 2 840 113549 1 7 */ +47, /* OBJ_pkcs9 1 2 840 113549 1 9 */ + 3, /* OBJ_md2 1 2 840 113549 2 2 */ +257, /* OBJ_md4 1 2 840 113549 2 4 */ + 4, /* OBJ_md5 1 2 840 113549 2 5 */ +797, /* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ +163, /* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ +798, /* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ +799, /* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ +800, /* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ +801, /* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ +37, /* OBJ_rc2_cbc 1 2 840 113549 3 2 */ + 5, /* OBJ_rc4 1 2 840 113549 3 4 */ +44, /* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ +120, /* OBJ_rc5_cbc 1 2 840 113549 3 8 */ +643, /* OBJ_des_cdmf 1 2 840 113549 3 10 */ +680, /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ +684, /* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ +685, /* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ +686, /* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ +687, /* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ +688, /* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ +689, /* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ +690, /* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ +691, /* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ +692, /* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ +693, /* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ +694, /* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ +695, /* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ +696, /* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ +697, /* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ +698, /* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ +699, /* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ +700, /* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ +701, /* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ +702, /* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ +703, /* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ +409, /* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ +410, /* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ +411, /* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ +412, /* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ +413, /* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ +414, /* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ +415, /* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ +793, /* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ +794, /* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ +795, /* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ +796, /* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ +269, /* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ +270, /* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ +271, /* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ +272, /* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ +273, /* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ +274, /* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ +275, /* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ +276, /* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ +277, /* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ +278, /* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ +279, /* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ +280, /* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ +281, /* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ +282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ +283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ +284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ +177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ +285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ +286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ +287, /* OBJ_ac_auditEntity 1 3 6 1 5 5 7 1 4 */ +288, /* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ +289, /* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ +290, /* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ +291, /* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ +292, /* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ +397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ +398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ +663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ +164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ +165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ +293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ +129, /* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ +130, /* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ +131, /* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ +132, /* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ +294, /* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ +295, /* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ +296, /* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ +133, /* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ +180, /* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ +297, /* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ +298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ +299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ +300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ +301, /* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ +302, /* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ +303, /* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ +304, /* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ +305, /* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ +306, /* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ +307, /* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ +308, /* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ +309, /* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ +310, /* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ +311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ +312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ +784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ +313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ +314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ +323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ +324, /* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ +325, /* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ +326, /* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ +327, /* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ +328, /* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ +329, /* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ +330, /* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ +331, /* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ +332, /* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ +333, /* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ +334, /* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ +335, /* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ +336, /* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ +337, /* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ +338, /* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ +339, /* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ +340, /* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ +341, /* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ +342, /* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ +343, /* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ +344, /* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ +345, /* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ +346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ +347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ +858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ +348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ +349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ +351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ +352, /* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ +353, /* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ +354, /* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ +355, /* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ +356, /* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ +357, /* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ +358, /* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ +399, /* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ +359, /* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ +360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ +361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ +362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ +664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ +665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ +667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ +178, /* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ +179, /* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ +363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ +364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ +785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ +780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ +781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ +58, /* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ +59, /* OBJ_netscape_data_type 2 16 840 1 113730 2 */ +438, /* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ +439, /* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ +440, /* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ +441, /* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ +108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ +112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ +782, /* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ +783, /* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ + 6, /* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ + 7, /* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ +396, /* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ + 8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ +65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ +644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ +668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ +669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ +670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ +671, /* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ +28, /* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ + 9, /* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ +10, /* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ +168, /* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ +169, /* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ +170, /* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ +68, /* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ +69, /* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ +161, /* OBJ_pbes2 1 2 840 113549 1 5 13 */ +162, /* OBJ_pbmac1 1 2 840 113549 1 5 14 */ +21, /* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ +22, /* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ +23, /* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ +24, /* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ +25, /* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ +26, /* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ +48, /* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ +49, /* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ +50, /* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ +51, /* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ +52, /* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ +53, /* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ +54, /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ +55, /* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ +56, /* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ +172, /* OBJ_ext_req 1 2 840 113549 1 9 14 */ +167, /* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ +188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ +156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ +157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ +681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ +682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ +683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ +417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ +856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ +390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ +91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ +315, /* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ +316, /* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ +317, /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ +318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ +319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ +320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ +321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ +322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ +365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ +366, /* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ +367, /* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ +368, /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ +369, /* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ +370, /* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ +371, /* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ +372, /* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ +373, /* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ +374, /* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ +375, /* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ +418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ +419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ +420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ +421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ +788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ +422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ +423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ +424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ +425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ +789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ +426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ +427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ +428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ +429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ +790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ +672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ +673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ +674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ +675, /* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ +802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ +803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ +71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ +72, /* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ +73, /* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ +74, /* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ +75, /* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ +76, /* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ +77, /* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ +78, /* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ +79, /* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ +139, /* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ +458, /* OBJ_userId 0 9 2342 19200300 100 1 1 */ +459, /* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ +460, /* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ +461, /* OBJ_info 0 9 2342 19200300 100 1 4 */ +462, /* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ +463, /* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ +464, /* OBJ_photo 0 9 2342 19200300 100 1 7 */ +465, /* OBJ_userClass 0 9 2342 19200300 100 1 8 */ +466, /* OBJ_host 0 9 2342 19200300 100 1 9 */ +467, /* OBJ_manager 0 9 2342 19200300 100 1 10 */ +468, /* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ +469, /* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ +470, /* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ +471, /* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ +472, /* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ +473, /* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ +474, /* OBJ_secretary 0 9 2342 19200300 100 1 21 */ +475, /* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ +476, /* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ +477, /* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ +391, /* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ +478, /* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ +479, /* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ +480, /* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ +481, /* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ +482, /* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ +483, /* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ +484, /* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ +485, /* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ +486, /* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ +487, /* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ +488, /* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ +489, /* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ +490, /* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ +491, /* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ +492, /* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ +493, /* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ +494, /* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ +495, /* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ +496, /* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ +497, /* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ +498, /* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ +499, /* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ +500, /* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ +501, /* OBJ_audio 0 9 2342 19200300 100 1 55 */ +502, /* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ +442, /* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ +443, /* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ +444, /* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ +445, /* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ +446, /* OBJ_account 0 9 2342 19200300 100 4 5 */ +447, /* OBJ_document 0 9 2342 19200300 100 4 6 */ +448, /* OBJ_room 0 9 2342 19200300 100 4 7 */ +449, /* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ +392, /* OBJ_Domain 0 9 2342 19200300 100 4 13 */ +450, /* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ +451, /* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ +452, /* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ +453, /* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ +454, /* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ +455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ +456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ +457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ +189, /* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ +190, /* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ +191, /* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ +192, /* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ +193, /* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ +194, /* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ +195, /* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ +158, /* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ +159, /* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ +160, /* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ +144, /* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ +145, /* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ +146, /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ +147, /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ +148, /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ +149, /* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ +171, /* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ +134, /* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ +135, /* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ +136, /* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ +137, /* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ +138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ +648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ +649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ +751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ +752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ +753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ +196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ +197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ +198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ +199, /* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ +200, /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ +201, /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ +202, /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ +203, /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ +204, /* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ +205, /* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ +206, /* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ +207, /* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ +208, /* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ +209, /* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ +210, /* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ +211, /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ +786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ +787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ +212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ +213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ +214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ +215, /* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ +216, /* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ +217, /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ +218, /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ +219, /* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ +220, /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ +221, /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ +222, /* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ +223, /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ +224, /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ +225, /* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ +226, /* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ +227, /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ +228, /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ +229, /* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ +230, /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ +231, /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ +232, /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ +233, /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ +234, /* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ +235, /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ +236, /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ +237, /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ +238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ +239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ +240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ +241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ +242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ +243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ +244, /* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ +245, /* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ +246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ +247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ +125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ +248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ +249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ +250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ +251, /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ +252, /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ +253, /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ +254, /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ +255, /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ +256, /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ +150, /* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ +151, /* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ +152, /* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ +153, /* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ +154, /* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ +155, /* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ +34, /* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ }; diff --git a/crypto/openssl/crypto/objects/obj_err.c b/crypto/openssl/crypto/objects/obj_err.c index 12b48850c6..2e7a034c3f 100644 --- a/crypto/openssl/crypto/objects/obj_err.c +++ b/crypto/openssl/crypto/objects/obj_err.c @@ -1,6 +1,6 @@ /* crypto/objects/obj_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/objects/obj_lib.c b/crypto/openssl/crypto/objects/obj_lib.c index 706fa0b0e7..23e9d48cdf 100644 --- a/crypto/openssl/crypto/objects/obj_lib.c +++ b/crypto/openssl/crypto/objects/obj_lib.c @@ -66,7 +66,8 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { ASN1_OBJECT *r; int i; - char *ln=NULL; + char *ln=NULL,*sn=NULL; + unsigned char *data=NULL; if (o == NULL) return(NULL); if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) @@ -79,42 +80,42 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB); return(NULL); } - r->data=OPENSSL_malloc(o->length); - if (r->data == NULL) + data=OPENSSL_malloc(o->length); + if (data == NULL) goto err; if (o->data != NULL) - memcpy(r->data,o->data,o->length); + memcpy(data,o->data,o->length); + /* once data attached to object it remains const */ + r->data = data; r->length=o->length; r->nid=o->nid; r->ln=r->sn=NULL; if (o->ln != NULL) { i=strlen(o->ln)+1; - r->ln=ln=OPENSSL_malloc(i); - if (r->ln == NULL) goto err; + ln=OPENSSL_malloc(i); + if (ln == NULL) goto err; memcpy(ln,o->ln,i); + r->ln=ln; } if (o->sn != NULL) { - char *s; - i=strlen(o->sn)+1; - r->sn=s=OPENSSL_malloc(i); - if (r->sn == NULL) goto err; - memcpy(s,o->sn,i); + sn=OPENSSL_malloc(i); + if (sn == NULL) goto err; + memcpy(sn,o->sn,i); + r->sn=sn; } r->flags=o->flags|(ASN1_OBJECT_FLAG_DYNAMIC| ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA); return(r); err: OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE); - if (r != NULL) - { - if (ln != NULL) OPENSSL_free(ln); - if (r->data != NULL) OPENSSL_free(r->data); - OPENSSL_free(r); - } + if (ln != NULL) OPENSSL_free(ln); + if (sn != NULL) OPENSSL_free(sn); + if (data != NULL) OPENSSL_free(data); + if (r != NULL) OPENSSL_free(r); return(NULL); } diff --git a/crypto/openssl/crypto/objects/obj_xref.c b/crypto/openssl/crypto/objects/obj_xref.c new file mode 100644 index 0000000000..152eca5c67 --- /dev/null +++ b/crypto/openssl/crypto/objects/obj_xref.c @@ -0,0 +1,231 @@ +/* crypto/objects/obj_xref.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "obj_xref.h" + +DECLARE_STACK_OF(nid_triple) +STACK_OF(nid_triple) *sig_app, *sigx_app; + +static int sig_cmp(const nid_triple *a, const nid_triple *b) + { + return a->sign_id - b->sign_id; + } + +DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); + +static int sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b) + { + return (*a)->sign_id - (*b)->sign_id; + } + +DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); + +static int sigx_cmp(const nid_triple * const *a, const nid_triple * const *b) + { + int ret; + ret = (*a)->hash_id - (*b)->hash_id; + if (ret) + return ret; + return (*a)->pkey_id - (*b)->pkey_id; + } + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid) + { + nid_triple tmp; + const nid_triple *rv = NULL; + tmp.sign_id = signid; + + if (sig_app) + { + int idx = sk_nid_triple_find(sig_app, &tmp); + if (idx >= 0) + rv = sk_nid_triple_value(sig_app, idx); + } + +#ifndef OBJ_XREF_TEST2 + if (rv == NULL) + { + rv = OBJ_bsearch_sig(&tmp, sigoid_srt, + sizeof(sigoid_srt) / sizeof(nid_triple)); + } +#endif + if (rv == NULL) + return 0; + *pdig_nid = rv->hash_id; + *ppkey_nid = rv->pkey_id; + return 1; + } + +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid) + { + nid_triple tmp; + const nid_triple *t=&tmp; + const nid_triple **rv = NULL; + + tmp.hash_id = dig_nid; + tmp.pkey_id = pkey_nid; + + if (sigx_app) + { + int idx = sk_nid_triple_find(sigx_app, &tmp); + if (idx >= 0) + { + t = sk_nid_triple_value(sigx_app, idx); + rv = &t; + } + } + +#ifndef OBJ_XREF_TEST2 + if (rv == NULL) + { + rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, + sizeof(sigoid_srt_xref) / sizeof(nid_triple *) + ); + } +#endif + if (rv == NULL) + return 0; + *psignid = (*rv)->sign_id; + return 1; + } + +int OBJ_add_sigid(int signid, int dig_id, int pkey_id) + { + nid_triple *ntr; + if (!sig_app) + sig_app = sk_nid_triple_new(sig_sk_cmp); + if (!sig_app) + return 0; + if (!sigx_app) + sigx_app = sk_nid_triple_new(sigx_cmp); + if (!sigx_app) + return 0; + ntr = OPENSSL_malloc(sizeof(int) * 3); + if (!ntr) + return 0; + ntr->sign_id = signid; + ntr->hash_id = dig_id; + ntr->pkey_id = pkey_id; + + if (!sk_nid_triple_push(sig_app, ntr)) + { + OPENSSL_free(ntr); + return 0; + } + + if (!sk_nid_triple_push(sigx_app, ntr)) + return 0; + + sk_nid_triple_sort(sig_app); + sk_nid_triple_sort(sigx_app); + + return 1; + } + +static void sid_free(nid_triple *tt) + { + OPENSSL_free(tt); + } + +void OBJ_sigid_free(void) + { + if (sig_app) + { + sk_nid_triple_pop_free(sig_app, sid_free); + sig_app = NULL; + } + if (sigx_app) + { + sk_nid_triple_free(sigx_app); + sigx_app = NULL; + } + } + +#ifdef OBJ_XREF_TEST + +main() + { + int n1, n2, n3; + + int i, rv; +#ifdef OBJ_XREF_TEST2 + for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) + { + OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], + sigoid_srt[i][2]); + } +#endif + + for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) + { + n1 = sigoid_srt[i][0]; + rv = OBJ_find_sigid_algs(n1, &n2, &n3); + printf("Forward: %d, %s %s %s\n", rv, + OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); + n1=0; + rv = OBJ_find_sigid_by_algs(&n1, n2, n3); + printf("Reverse: %d, %s %s %s\n", rv, + OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); + } + } + +#endif diff --git a/crypto/openssl/crypto/objects/obj_xref.h b/crypto/openssl/crypto/objects/obj_xref.h new file mode 100644 index 0000000000..d5b9b8e198 --- /dev/null +++ b/crypto/openssl/crypto/objects/obj_xref.h @@ -0,0 +1,75 @@ +/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */ + +typedef struct + { + int sign_id; + int hash_id; + int pkey_id; + } nid_triple; + +static const nid_triple sigoid_srt[] = + { + {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption}, + {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, + {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption}, + {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, + {NID_dsaWithSHA, NID_sha, NID_dsa}, + {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, + {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption}, + {NID_md5WithRSA, NID_md5, NID_rsa}, + {NID_dsaWithSHA1, NID_sha1, NID_dsa}, + {NID_sha1WithRSA, NID_sha1, NID_rsa}, + {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption}, + {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, + {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, + {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, + {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, + {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, + {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, + {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, + {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, + {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001}, + {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94}, + {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc}, + {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc}, + }; + +static const nid_triple * const sigoid_srt_xref[] = + { + &sigoid_srt[17], + &sigoid_srt[18], + &sigoid_srt[0], + &sigoid_srt[1], + &sigoid_srt[7], + &sigoid_srt[2], + &sigoid_srt[4], + &sigoid_srt[3], + &sigoid_srt[9], + &sigoid_srt[5], + &sigoid_srt[8], + &sigoid_srt[12], + &sigoid_srt[6], + &sigoid_srt[10], + &sigoid_srt[11], + &sigoid_srt[13], + &sigoid_srt[24], + &sigoid_srt[20], + &sigoid_srt[14], + &sigoid_srt[21], + &sigoid_srt[15], + &sigoid_srt[22], + &sigoid_srt[16], + &sigoid_srt[23], + &sigoid_srt[19], + &sigoid_srt[25], + &sigoid_srt[26], + &sigoid_srt[27], + &sigoid_srt[28], + }; + diff --git a/crypto/openssl/crypto/objects/objects.h b/crypto/openssl/crypto/objects/objects.h index 7242f76fb0..bd0ee52feb 100644 --- a/crypto/openssl/crypto/objects/objects.h +++ b/crypto/openssl/crypto/objects/objects.h @@ -1011,10 +1011,91 @@ int OBJ_txt2nid(const char *s); int OBJ_ln2nid(const char *s); int OBJ_sn2nid(const char *s); int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b); -const char * OBJ_bsearch(const char *key,const char *base,int num,int size, - int (*cmp)(const void *, const void *)); -const char * OBJ_bsearch_ex(const char *key,const char *base,int num, - int size, int (*cmp)(const void *, const void *), int flags); +const void * OBJ_bsearch_(const void *key,const void *base,int num,int size, + int (*cmp)(const void *, const void *)); +const void * OBJ_bsearch_ex_(const void *key,const void *base,int num, + int size, + int (*cmp)(const void *, const void *), + int flags); + +#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/* + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignement discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, delcare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +#define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) int OBJ_new_nid(int num); int OBJ_add_object(const ASN1_OBJECT *obj); @@ -1022,6 +1103,14 @@ int OBJ_create(const char *oid,const char *sn,const char *ln); void OBJ_cleanup(void ); int OBJ_create_objects(BIO *in); +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + +extern int obj_cleanup_defer; +void check_defer(int nid); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. diff --git a/crypto/openssl/crypto/ocsp/ocsp.h b/crypto/openssl/crypto/ocsp/ocsp.h index a0577a717e..31e45744ba 100644 --- a/crypto/openssl/crypto/ocsp/ocsp.h +++ b/crypto/openssl/crypto/ocsp/ocsp.h @@ -64,6 +64,7 @@ #ifndef HEADER_OCSP_H #define HEADER_OCSP_H +#include #include #include #include @@ -394,17 +395,20 @@ typedef struct ocsp_service_locator_st #define ASN1_BIT_STRING_digest(data,type,md,len) \ ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) -#define OCSP_CERTID_dup(cid) ASN1_dup_of(OCSP_CERTID,i2d_OCSP_CERTID,d2i_OCSP_CERTID,cid) - #define OCSP_CERTSTATUS_dup(cs)\ (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req); OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, int maxline); int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); @@ -474,11 +478,6 @@ int OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags); -ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, - void *data, STACK_OF(ASN1_OBJECT) *sk); -#define ASN1_STRING_encode_of(type,s,i2d,data,sk) \ - ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk) - X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); X509_EXTENSION *OCSP_accept_responses_new(char **oids); @@ -547,9 +546,9 @@ DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) -char *OCSP_response_status_str(long s); -char *OCSP_cert_status_str(long s); -char *OCSP_crl_reason_str(long s); +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags); int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags); @@ -582,7 +581,8 @@ void ERR_load_OCSP_strings(void); #define OCSP_F_OCSP_REQUEST_VERIFY 116 #define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 #define OCSP_F_OCSP_SENDREQ_BIO 112 -#define OCSP_F_PARSE_HTTP_LINE1 117 +#define OCSP_F_OCSP_SENDREQ_NBIO 117 +#define OCSP_F_PARSE_HTTP_LINE1 118 #define OCSP_F_REQUEST_VERIFY 113 /* Reason codes. */ diff --git a/crypto/openssl/crypto/ocsp/ocsp_cl.c b/crypto/openssl/crypto/ocsp/ocsp_cl.c index 17bab5fc59..9c14d9da27 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_cl.c +++ b/crypto/openssl/crypto/ocsp/ocsp_cl.c @@ -155,7 +155,6 @@ int OCSP_request_sign(OCSP_REQUEST *req, goto err; if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err; - if (!dgst) dgst = EVP_sha1(); if (key) { if (!X509_check_private_key(signer, key)) diff --git a/crypto/openssl/crypto/ocsp/ocsp_err.c b/crypto/openssl/crypto/ocsp/ocsp_err.c index d2f2e79f44..0cedcea682 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_err.c +++ b/crypto/openssl/crypto/ocsp/ocsp_err.c @@ -1,6 +1,6 @@ /* crypto/ocsp/ocsp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -86,6 +86,7 @@ static ERR_STRING_DATA OCSP_str_functs[]= {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"}, {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"}, {ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO), "OCSP_sendreq_bio"}, +{ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO), "OCSP_sendreq_nbio"}, {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "PARSE_HTTP_LINE1"}, {ERR_FUNC(OCSP_F_REQUEST_VERIFY), "REQUEST_VERIFY"}, {0,NULL} diff --git a/crypto/openssl/crypto/ocsp/ocsp_ext.c b/crypto/openssl/crypto/ocsp/ocsp_ext.c index 815cc29d58..ec884cb08f 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_ext.c +++ b/crypto/openssl/crypto/ocsp/ocsp_ext.c @@ -264,7 +264,7 @@ int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) } /* also CRL Entry Extensions */ - +#if 0 ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, void *data, STACK_OF(ASN1_OBJECT) *sk) { @@ -305,6 +305,7 @@ err: if (b) OPENSSL_free(b); return NULL; } +#endif /* Nonce handling functions */ @@ -442,17 +443,10 @@ X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) goto err; } - if (!(x = X509_EXTENSION_new())) goto err; - if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) goto err; - if (!(ASN1_STRING_encode_of(OCSP_CRLID,x->value,i2d_OCSP_CRLID,cid, - NULL))) - goto err; - OCSP_CRLID_free(cid); - return x; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); err: - if (x) X509_EXTENSION_free(x); if (cid) OCSP_CRLID_free(cid); - return NULL; + return x; } /* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ @@ -470,18 +464,10 @@ X509_EXTENSION *OCSP_accept_responses_new(char **oids) sk_ASN1_OBJECT_push(sk, o); oids++; } - if (!(x = X509_EXTENSION_new())) goto err; - if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses))) - goto err; - if (!(ASN1_STRING_encode_of(ASN1_OBJECT,x->value,i2d_ASN1_OBJECT,NULL, - sk))) - goto err; - sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); - return x; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); err: - if (x) X509_EXTENSION_free(x); if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); - return NULL; + return x; } /* ArchiveCutoff ::= GeneralizedTime */ @@ -492,16 +478,10 @@ X509_EXTENSION *OCSP_archive_cutoff_new(char* tim) if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err; if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err; - if (!(x = X509_EXTENSION_new())) goto err; - if (!(x->object=OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff)))goto err; - if (!(ASN1_STRING_encode_of(ASN1_GENERALIZEDTIME,x->value, - i2d_ASN1_GENERALIZEDTIME,gt,NULL))) goto err; - ASN1_GENERALIZEDTIME_free(gt); - return x; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); err: if (gt) ASN1_GENERALIZEDTIME_free(gt); - if (x) X509_EXTENSION_free(x); - return NULL; + return x; } /* per ACCESS_DESCRIPTION parameter are oids, of which there are currently @@ -530,16 +510,9 @@ X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls) if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err; urls++; } - if (!(x = X509_EXTENSION_new())) goto err; - if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator))) - goto err; - if (!(ASN1_STRING_encode_of(OCSP_SERVICELOC,x->value, - i2d_OCSP_SERVICELOC,sloc,NULL))) goto err; - OCSP_SERVICELOC_free(sloc); - return x; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); err: - if (x) X509_EXTENSION_free(x); if (sloc) OCSP_SERVICELOC_free(sloc); - return NULL; + return x; } diff --git a/crypto/openssl/crypto/ocsp/ocsp_ht.c b/crypto/openssl/crypto/ocsp/ocsp_ht.c index 6abb30b2c0..12bbfcffd1 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_ht.c +++ b/crypto/openssl/crypto/ocsp/ocsp_ht.c @@ -118,39 +118,65 @@ void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) OPENSSL_free(rctx); } -OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, - int maxline) +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) { - static char post_hdr[] = "POST %s HTTP/1.0\r\n" + static const char req_hdr[] = "Content-Type: application/ocsp-request\r\n" "Content-Length: %d\r\n\r\n"; + if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0) + return 0; + if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) + return 0; + rctx->state = OHS_ASN1_WRITE; + rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); + return 1; + } + +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value) + { + if (!name) + return 0; + if (BIO_puts(rctx->mem, name) <= 0) + return 0; + if (value) + { + if (BIO_write(rctx->mem, ": ", 2) != 2) + return 0; + if (BIO_puts(rctx->mem, value) <= 0) + return 0; + } + if (BIO_write(rctx->mem, "\r\n", 2) != 2) + return 0; + return 1; + } + +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, + int maxline) + { + static const char post_hdr[] = "POST %s HTTP/1.0\r\n"; OCSP_REQ_CTX *rctx; rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); - rctx->state = OHS_FIRSTLINE; + rctx->state = OHS_ERROR; rctx->mem = BIO_new(BIO_s_mem()); rctx->io = io; + rctx->asn1_len = 0; if (maxline > 0) rctx->iobuflen = maxline; else rctx->iobuflen = OCSP_MAX_LINE_LEN; rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); + if (!rctx->iobuf) + return 0; if (!path) path = "/"; - if (BIO_printf(rctx->mem, post_hdr, path, - i2d_OCSP_REQUEST(req, NULL)) <= 0) - { - rctx->state = OHS_ERROR; + if (BIO_printf(rctx->mem, post_hdr, path) <= 0) return 0; - } - if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) - { - rctx->state = OHS_ERROR; + + if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) return 0; - } - rctx->state = OHS_ASN1_WRITE; - rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); return rctx; } diff --git a/crypto/openssl/crypto/ocsp/ocsp_lib.c b/crypto/openssl/crypto/ocsp/ocsp_lib.c index 27450811d7..36905d76cd 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_lib.c +++ b/crypto/openssl/crypto/ocsp/ocsp_lib.c @@ -69,6 +69,7 @@ #include #include #include +#include /* Convert a certificate and its issuer to an OCSP_CERTID */ @@ -260,3 +261,5 @@ int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pss return 0; } + +IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) diff --git a/crypto/openssl/crypto/ocsp/ocsp_prn.c b/crypto/openssl/crypto/ocsp/ocsp_prn.c index 01f81e7a59..1695c9c4ad 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_prn.c +++ b/crypto/openssl/crypto/ocsp/ocsp_prn.c @@ -85,21 +85,21 @@ static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent) typedef struct { long t; - char *m; + const char *m; } OCSP_TBLSTR; -static char *table2string(long s, OCSP_TBLSTR *ts, int len) +static const char *table2string(long s, const OCSP_TBLSTR *ts, int len) { - OCSP_TBLSTR *p; + const OCSP_TBLSTR *p; for (p=ts; p < ts + len; p++) if (p->t == s) return p->m; return "(UNKNOWN)"; } -char *OCSP_response_status_str(long s) +const char *OCSP_response_status_str(long s) { - static OCSP_TBLSTR rstat_tbl[] = { + static const OCSP_TBLSTR rstat_tbl[] = { { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" }, { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" }, { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" }, @@ -109,18 +109,18 @@ char *OCSP_response_status_str(long s) return table2string(s, rstat_tbl, 6); } -char *OCSP_cert_status_str(long s) +const char *OCSP_cert_status_str(long s) { - static OCSP_TBLSTR cstat_tbl[] = { + static const OCSP_TBLSTR cstat_tbl[] = { { V_OCSP_CERTSTATUS_GOOD, "good" }, { V_OCSP_CERTSTATUS_REVOKED, "revoked" }, { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } }; return table2string(s, cstat_tbl, 3); } -char *OCSP_crl_reason_str(long s) +const char *OCSP_crl_reason_str(long s) { - OCSP_TBLSTR reason_tbl[] = { + static const OCSP_TBLSTR reason_tbl[] = { { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" }, { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" }, { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" }, @@ -275,6 +275,7 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags) } if (!X509V3_extensions_print(bp, "Response Extensions", rd->responseExtensions, flags, 4)) + goto err; if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) goto err; diff --git a/crypto/openssl/crypto/ocsp/ocsp_vfy.c b/crypto/openssl/crypto/ocsp/ocsp_vfy.c index 4a0c3870d8..415d67e61c 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_vfy.c +++ b/crypto/openssl/crypto/ocsp/ocsp_vfy.c @@ -308,6 +308,8 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, } mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; if ((cid->issuerNameHash->length != mdlen) || (cid->issuerKeyHash->length != mdlen)) return 0; @@ -316,7 +318,7 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, return -1; if (memcmp(md, cid->issuerNameHash->data, mdlen)) return 0; - X509_pubkey_digest(cert, EVP_sha1(), md, NULL); + X509_pubkey_digest(cert, dgst, md, NULL); if (memcmp(md, cid->issuerKeyHash->data, mdlen)) return 0; diff --git a/crypto/openssl/crypto/opensslv.h b/crypto/openssl/crypto/opensslv.h index 3d794d9dad..2fb110fa0e 100644 --- a/crypto/openssl/crypto/opensslv.h +++ b/crypto/openssl/crypto/opensslv.h @@ -12,7 +12,7 @@ * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) * 0.9.3 0x0090300f * 0.9.3a 0x0090301f - * 0.9.4 0x0090400f + * 0.9.4 0x0090400f * 1.2.3z 0x102031af * * For continuity reasons (because 0.9.5 is already out, and is coded @@ -25,11 +25,11 @@ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -#define OPENSSL_VERSION_NUMBER 0x009080dfL +#define OPENSSL_VERSION_NUMBER 0x1000001fL #ifdef OPENSSL_FIPS -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8m-fips 25 Feb 2010" +#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0a-fips 1 Jun 2010" #else -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8m 25 Feb 2010" +#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0a 1 Jun 2010" #endif #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT @@ -83,7 +83,7 @@ * should only keep the versions that are binary compatible with the current. */ #define SHLIB_VERSION_HISTORY "" -#define SHLIB_VERSION_NUMBER "0.9.8" +#define SHLIB_VERSION_NUMBER "1.0.0" #endif /* HEADER_OPENSSLV_H */ diff --git a/crypto/openssl/crypto/ossl_typ.h b/crypto/openssl/crypto/ossl_typ.h index 0e7a380880..12bd7014de 100644 --- a/crypto/openssl/crypto/ossl_typ.h +++ b/crypto/openssl/crypto/ossl_typ.h @@ -95,6 +95,8 @@ typedef int ASN1_BOOLEAN; typedef int ASN1_NULL; #endif +typedef struct asn1_pctx_st ASN1_PCTX; + #ifdef OPENSSL_SYS_WIN32 #undef X509_NAME #undef X509_EXTENSIONS @@ -122,6 +124,11 @@ typedef struct env_md_st EVP_MD; typedef struct env_md_ctx_st EVP_MD_CTX; typedef struct evp_pkey_st EVP_PKEY; +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + typedef struct dh_st DH; typedef struct dh_method DH_METHOD; @@ -139,11 +146,14 @@ typedef struct ecdsa_method ECDSA_METHOD; typedef struct x509_st X509; typedef struct X509_algor_st X509_ALGOR; typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; typedef struct x509_store_st X509_STORE; typedef struct x509_store_ctx_st X509_STORE_CTX; -typedef struct ssl_st SSL; -typedef struct ssl_ctx_st SSL_CTX; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; typedef struct v3_ext_ctx X509V3_CTX; typedef struct conf_st CONF; @@ -157,12 +167,19 @@ typedef struct ui_method_st UI_METHOD; typedef struct st_ERR_FNS ERR_FNS; typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; +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; + /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ #define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ #define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ diff --git a/crypto/openssl/crypto/pem/pem.h b/crypto/openssl/crypto/pem/pem.h index 6c193f1cbf..8a6ababe3a 100644 --- a/crypto/openssl/crypto/pem/pem.h +++ b/crypto/openssl/crypto/pem/pem.h @@ -134,6 +134,7 @@ extern "C" { #define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" #define PEM_STRING_ECPARAMETERS "EC PARAMETERS" #define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_PARAMETERS "PARAMETERS" #define PEM_STRING_CMS "CMS" /* Note that this structure is initialised by PEM_SealInit and cleaned up @@ -183,11 +184,8 @@ typedef struct pem_ctx_st int num_recipient; PEM_USER **recipient; -#ifndef OPENSSL_NO_STACK - STACK *x509_chain; /* certificate chain */ -#else - char *x509_chain; /* certificate chain */ -#endif + /* XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ EVP_MD *md; /* signature type */ int md_enc; /* is the md encrypted or not? */ @@ -224,28 +222,19 @@ typedef struct pem_ctx_st #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ { \ - return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \ - str, fp, \ - CHECKED_PPTR_OF(type, x), \ - cb, u); \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ } #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ int PEM_write_##name(FILE *fp, type *x) \ { \ - return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ - str, fp, \ - CHECKED_PTR_OF(type, x), \ - NULL, NULL, 0, NULL, NULL); \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ } #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ int PEM_write_##name(FILE *fp, const type *x) \ { \ - return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ - str, fp, \ - CHECKED_PTR_OF(const type, x), \ - NULL, NULL, 0, NULL, NULL); \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ } #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ @@ -253,10 +242,7 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, \ void *u) \ { \ - return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ - str, fp, \ - CHECKED_PTR_OF(type, x), \ - enc, kstr, klen, cb, u); \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ } #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ @@ -264,10 +250,7 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, \ void *u) \ { \ - return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ - str, fp, \ - CHECKED_PTR_OF(const type, x), \ - enc, kstr, klen, cb, u); \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ } #endif @@ -275,48 +258,33 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ { \ - return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \ - str, bp, \ - CHECKED_PPTR_OF(type, x), \ - cb, u); \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ } #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, type *x) \ { \ - return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ - str, bp, \ - CHECKED_PTR_OF(type, x), \ - NULL, NULL, 0, NULL, NULL); \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ } #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, const type *x) \ { \ - return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ - str, bp, \ - CHECKED_PTR_OF(const type, x), \ - NULL, NULL, 0, NULL, NULL); \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ } #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ { \ - return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ - str, bp, \ - CHECKED_PTR_OF(type, x), \ - enc, kstr, klen, cb, u); \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ } #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ { \ - return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ - str, bp, \ - CHECKED_PTR_OF(const type, x), \ - enc, kstr, klen, cb, u); \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ } #define IMPLEMENT_PEM_write(name, type, str, asn1) \ @@ -353,11 +321,10 @@ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ /* These are the same except they are for the declarations */ -#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_NO_FP_API) +#if defined(OPENSSL_NO_FP_API) #define DECLARE_PEM_read_fp(name, type) /**/ #define DECLARE_PEM_write_fp(name, type) /**/ -#define DECLARE_PEM_write_fp_const(name, type) /**/ #define DECLARE_PEM_write_cb_fp(name, type) /**/ #else @@ -428,138 +395,6 @@ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ DECLARE_PEM_read(name, type) \ DECLARE_PEM_write_cb(name, type) -#ifdef SSLEAY_MACROS - -#define PEM_write_SSL_SESSION(fp,x) \ - PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \ - PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_X509(fp,x) \ - PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \ - (char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_X509_REQ(fp,x) PEM_ASN1_write( \ - (int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,fp,(char *)x, \ - NULL,NULL,0,NULL,NULL) -#define PEM_write_X509_CRL(fp,x) \ - PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL, \ - fp,(char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \ - PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,\ - (char *)x,enc,kstr,klen,cb,u) -#define PEM_write_RSAPublicKey(fp,x) \ - PEM_ASN1_write((int (*)())i2d_RSAPublicKey,\ - PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL,NULL) -#define PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \ - PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,\ - (char *)x,enc,kstr,klen,cb,u) -#define PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb,u) \ - PEM_ASN1_write((int (*)())i2d_PrivateKey,\ - (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\ - bp,(char *)x,enc,kstr,klen,cb,u) -#define PEM_write_PKCS7(fp,x) \ - PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, \ - (char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_DHparams(fp,x) \ - PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,\ - (char *)x,NULL,NULL,0,NULL,NULL) - -#define PEM_write_NETSCAPE_CERT_SEQUENCE(fp,x) \ - PEM_ASN1_write((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \ - PEM_STRING_X509,fp, \ - (char *)x, NULL,NULL,0,NULL,NULL) - -#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \ - (char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u) -#define PEM_read_X509(fp,x,cb,u) (X509 *)PEM_ASN1_read( \ - (char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb,u) -#define PEM_read_X509_REQ(fp,x,cb,u) (X509_REQ *)PEM_ASN1_read( \ - (char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,fp,(char **)x,cb,u) -#define PEM_read_X509_CRL(fp,x,cb,u) (X509_CRL *)PEM_ASN1_read( \ - (char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,fp,(char **)x,cb,u) -#define PEM_read_RSAPrivateKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \ - (char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char **)x,cb,u) -#define PEM_read_RSAPublicKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \ - (char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char **)x,cb,u) -#define PEM_read_DSAPrivateKey(fp,x,cb,u) (DSA *)PEM_ASN1_read( \ - (char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,(char **)x,cb,u) -#define PEM_read_PrivateKey(fp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read( \ - (char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,fp,(char **)x,cb,u) -#define PEM_read_PKCS7(fp,x,cb,u) (PKCS7 *)PEM_ASN1_read( \ - (char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,(char **)x,cb,u) -#define PEM_read_DHparams(fp,x,cb,u) (DH *)PEM_ASN1_read( \ - (char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,(char **)x,cb,u) - -#define PEM_read_NETSCAPE_CERT_SEQUENCE(fp,x,cb,u) \ - (NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read( \ - (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,fp,\ - (char **)x,cb,u) - -#define PEM_write_bio_X509(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, \ - (char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( \ - (int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, \ - NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_X509_CRL(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,\ - bp,(char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \ - PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,\ - bp,(char *)x,enc,kstr,klen,cb,u) -#define PEM_write_bio_RSAPublicKey(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, \ - PEM_STRING_RSA_PUBLIC,\ - bp,(char *)x,NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \ - PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,\ - bp,(char *)x,enc,kstr,klen,cb,u) -#define PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb,u) \ - PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,\ - (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\ - bp,(char *)x,enc,kstr,klen,cb,u) -#define PEM_write_bio_PKCS7(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, \ - (char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_DHparams(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,\ - bp,(char *)x,NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_DSAparams(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_DSAparams, \ - PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL,NULL) - -#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp,x) \ - PEM_ASN1_write_bio((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \ - PEM_STRING_X509,bp, \ - (char *)x, NULL,NULL,0,NULL,NULL) - -#define PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u) -#define PEM_read_bio_X509_REQ(bp,x,cb,u) (X509_REQ *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,bp,(char **)x,cb,u) -#define PEM_read_bio_X509_CRL(bp,x,cb,u) (X509_CRL *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,bp,(char **)x,cb,u) -#define PEM_read_bio_RSAPrivateKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char **)x,cb,u) -#define PEM_read_bio_RSAPublicKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb,u) -#define PEM_read_bio_DSAPrivateKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,bp,(char **)x,cb,u) -#define PEM_read_bio_PrivateKey(bp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,bp,(char **)x,cb,u) - -#define PEM_read_bio_PKCS7(bp,x,cb,u) (PKCS7 *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,bp,(char **)x,cb,u) -#define PEM_read_bio_DHparams(bp,x,cb,u) (DH *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,bp,(char **)x,cb,u) -#define PEM_read_bio_DSAparams(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,bp,(char **)x,cb,u) - -#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp,x,cb,u) \ - (NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,bp,\ - (char **)x,cb,u) - -#endif - #if 1 /* "userdata": new with OpenSSL 0.9.4 */ typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); @@ -581,40 +416,25 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char pem_password_cb *cb, void *u); void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, pem_password_cb *cb, void *u); - -#define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \ - ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \ - name, bp, \ - CHECKED_PPTR_OF(type, x), \ - cb, u)) - -int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x, +int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x, const EVP_CIPHER *enc,unsigned char *kstr,int klen, pem_password_cb *cb, void *u); -#define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \ - (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \ - name, bp, \ - CHECKED_PTR_OF(type, x), \ - enc, kstr, klen, cb, u)) - STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); int PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cd, void *u); #endif -#ifndef OPENSSL_SYS_WIN16 int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,long *len); int PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len); void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, pem_password_cb *cb, void *u); int PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp, - char *x,const EVP_CIPHER *enc,unsigned char *kstr, + void *x,const EVP_CIPHER *enc,unsigned char *kstr, int klen,pem_password_cb *callback, void *u); STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); -#endif int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, unsigned char **ek, int *ekl, @@ -633,7 +453,6 @@ int PEM_def_callback(char *buf, int num, int w, void *key); void PEM_proc_type(char *buf, int type); void PEM_dek_info(char *buf, const char *type, int len, char *str); -#ifndef SSLEAY_MACROS #include @@ -719,7 +538,21 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, vo int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, char *kstr,int klen, pem_password_cb *cd, void *u); -#endif /* SSLEAY_MACROS */ +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +#ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +#endif /* BEGIN ERROR CODES */ @@ -731,10 +564,22 @@ void ERR_load_PEM_strings(void); /* Error codes for the PEM functions. */ /* Function codes. */ +#define PEM_F_B2I_DSS 127 +#define PEM_F_B2I_PVK_BIO 128 +#define PEM_F_B2I_RSA 129 +#define PEM_F_CHECK_BITLEN_DSA 130 +#define PEM_F_CHECK_BITLEN_RSA 131 #define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 #define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +#define PEM_F_DO_B2I 132 +#define PEM_F_DO_B2I_BIO 133 +#define PEM_F_DO_BLOB_HEADER 134 #define PEM_F_DO_PK8PKEY 126 #define PEM_F_DO_PK8PKEY_FP 125 +#define PEM_F_DO_PVK_BODY 135 +#define PEM_F_DO_PVK_HEADER 136 +#define PEM_F_I2B_PVK 137 +#define PEM_F_I2B_PVK_BIO 138 #define PEM_F_LOAD_IV 101 #define PEM_F_PEM_ASN1_READ 102 #define PEM_F_PEM_ASN1_READ_BIO 103 @@ -747,6 +592,7 @@ void ERR_load_PEM_strings(void); #define PEM_F_PEM_PK8PKEY 119 #define PEM_F_PEM_READ 108 #define PEM_F_PEM_READ_BIO 109 +#define PEM_F_PEM_READ_BIO_PARAMETERS 140 #define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 #define PEM_F_PEM_READ_PRIVATEKEY 124 #define PEM_F_PEM_SEALFINAL 110 @@ -754,6 +600,7 @@ void ERR_load_PEM_strings(void); #define PEM_F_PEM_SIGNFINAL 112 #define PEM_F_PEM_WRITE 113 #define PEM_F_PEM_WRITE_BIO 114 +#define PEM_F_PEM_WRITE_PRIVATEKEY 139 #define PEM_F_PEM_X509_INFO_READ 115 #define PEM_F_PEM_X509_INFO_READ_BIO 116 #define PEM_F_PEM_X509_INFO_WRITE_BIO 117 @@ -763,18 +610,30 @@ void ERR_load_PEM_strings(void); #define PEM_R_BAD_DECRYPT 101 #define PEM_R_BAD_END_LINE 102 #define PEM_R_BAD_IV_CHARS 103 +#define PEM_R_BAD_MAGIC_NUMBER 116 #define PEM_R_BAD_PASSWORD_READ 104 +#define PEM_R_BAD_VERSION_NUMBER 117 +#define PEM_R_BIO_WRITE_FAILURE 118 +#define PEM_R_CIPHER_IS_NULL 127 #define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +#define PEM_R_INCONSISTENT_HEADER 121 +#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +#define PEM_R_KEYBLOB_TOO_SHORT 123 #define PEM_R_NOT_DEK_INFO 105 #define PEM_R_NOT_ENCRYPTED 106 #define PEM_R_NOT_PROC_TYPE 107 #define PEM_R_NO_START_LINE 108 #define PEM_R_PROBLEMS_GETTING_PASSWORD 109 #define PEM_R_PUBLIC_KEY_NO_RSA 110 +#define PEM_R_PVK_DATA_TOO_SHORT 124 +#define PEM_R_PVK_TOO_SHORT 125 #define PEM_R_READ_KEY 111 #define PEM_R_SHORT_HEADER 112 #define PEM_R_UNSUPPORTED_CIPHER 113 #define PEM_R_UNSUPPORTED_ENCRYPTION 114 +#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/pem/pem_all.c b/crypto/openssl/crypto/pem/pem_all.c index 69dd19bf2e..3e7a6093ad 100644 --- a/crypto/openssl/crypto/pem/pem_all.c +++ b/crypto/openssl/crypto/pem/pem_all.c @@ -110,7 +110,6 @@ */ #include -#undef SSLEAY_MACROS #include "cryptlib.h" #include #include @@ -194,49 +193,7 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, #endif -#ifdef OPENSSL_FIPS - -int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_RSA(k, x); - - ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; -} - -#ifndef OPENSSL_NO_FP_API -int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - - EVP_PKEY_set1_RSA(k, x); - - ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; -} -#endif - -#else - IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) - -#endif - IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) @@ -263,50 +220,10 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, { EVP_PKEY *pktmp; pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_dsa(pktmp, dsa); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ } -#ifdef OPENSSL_FIPS - -int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_DSA(k, x); - - ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; -} - -#ifndef OPENSSL_NO_FP_API -int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_DSA(k, x); - ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; -} -#endif - -#else - IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) - -#endif - IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) #ifndef OPENSSL_NO_FP_API @@ -316,7 +233,7 @@ DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, { EVP_PKEY *pktmp; pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_dsa(pktmp, dsa); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ } #endif @@ -347,54 +264,13 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, { EVP_PKEY *pktmp; pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_eckey(pktmp, key); + return pkey_get_eckey(pktmp, key); /* will free pktmp */ } IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters) - - -#ifdef OPENSSL_FIPS - -int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_EC_KEY(k, x); - - ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; -} - -#ifndef OPENSSL_NO_FP_API -int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_EC_KEY(k, x); - ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; -} -#endif - -#else - IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey) -#endif - IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) #ifndef OPENSSL_NO_FP_API @@ -404,7 +280,7 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, { EVP_PKEY *pktmp; pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_eckey(pktmp, eckey); + return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ } #endif @@ -417,66 +293,4 @@ IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) #endif - -/* The PrivateKey case is not that straightforward. - * IMPLEMENT_PEM_rw_cb(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey) - * does not work, RSA and DSA keys have specific strings. - * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything - * appropriate.) - */ - -#ifdef OPENSSL_FIPS - -static const char *pkey_str(EVP_PKEY *x) - { - switch (x->type) - { - case EVP_PKEY_RSA: - return PEM_STRING_RSA; - - case EVP_PKEY_DSA: - return PEM_STRING_DSA; - - case EVP_PKEY_EC: - return PEM_STRING_ECPRIVATEKEY; - - default: - return NULL; - } - } - - -int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) - { - if (FIPS_mode()) - return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, - (char *)kstr, klen, cb, u); - else - return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, - pkey_str(x), bp,(char *)x,enc,kstr,klen,cb,u); - } - -#ifndef OPENSSL_NO_FP_API -int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) - { - if (FIPS_mode()) - return PEM_write_PKCS8PrivateKey(fp, x, enc, - (char *)kstr, klen, cb, u); - else - return PEM_ASN1_write((i2d_of_void *)i2d_PrivateKey, - pkey_str(x), fp,(char *)x,enc,kstr,klen,cb,u); - } -#endif - -#else -IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:\ - (x->type == EVP_PKEY_RSA)?PEM_STRING_RSA:PEM_STRING_ECPRIVATEKEY), PrivateKey) - -#endif - IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) - diff --git a/crypto/openssl/crypto/pem/pem_err.c b/crypto/openssl/crypto/pem/pem_err.c index 3133563d77..d644aeedd4 100644 --- a/crypto/openssl/crypto/pem/pem_err.c +++ b/crypto/openssl/crypto/pem/pem_err.c @@ -1,6 +1,6 @@ /* crypto/pem/pem_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -70,10 +70,22 @@ static ERR_STRING_DATA PEM_str_functs[]= { +{ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"}, +{ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"}, +{ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"}, +{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"}, +{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"}, {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"}, {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"}, +{ERR_FUNC(PEM_F_DO_B2I), "DO_B2I"}, +{ERR_FUNC(PEM_F_DO_B2I_BIO), "DO_B2I_BIO"}, +{ERR_FUNC(PEM_F_DO_BLOB_HEADER), "DO_BLOB_HEADER"}, {ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"}, {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"}, +{ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"}, +{ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"}, +{ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"}, +{ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"}, {ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"}, {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"}, {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"}, @@ -86,6 +98,7 @@ static ERR_STRING_DATA PEM_str_functs[]= {ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"}, {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"}, {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"}, +{ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"}, {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"}, {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"}, {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"}, @@ -93,6 +106,7 @@ static ERR_STRING_DATA PEM_str_functs[]= {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"}, {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"}, {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"}, +{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"}, {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"}, {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"}, {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"}, @@ -105,18 +119,30 @@ static ERR_STRING_DATA PEM_str_reasons[]= {ERR_REASON(PEM_R_BAD_DECRYPT) ,"bad decrypt"}, {ERR_REASON(PEM_R_BAD_END_LINE) ,"bad end line"}, {ERR_REASON(PEM_R_BAD_IV_CHARS) ,"bad iv chars"}, +{ERR_REASON(PEM_R_BAD_MAGIC_NUMBER) ,"bad magic number"}, {ERR_REASON(PEM_R_BAD_PASSWORD_READ) ,"bad password read"}, +{ERR_REASON(PEM_R_BAD_VERSION_NUMBER) ,"bad version number"}, +{ERR_REASON(PEM_R_BIO_WRITE_FAILURE) ,"bio write failure"}, +{ERR_REASON(PEM_R_CIPHER_IS_NULL) ,"cipher is null"}, {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),"error converting private key"}, +{ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),"expecting private key blob"}, +{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),"expecting public key blob"}, +{ERR_REASON(PEM_R_INCONSISTENT_HEADER) ,"inconsistent header"}, +{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),"keyblob header parse error"}, +{ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT) ,"keyblob too short"}, {ERR_REASON(PEM_R_NOT_DEK_INFO) ,"not dek info"}, {ERR_REASON(PEM_R_NOT_ENCRYPTED) ,"not encrypted"}, {ERR_REASON(PEM_R_NOT_PROC_TYPE) ,"not proc type"}, {ERR_REASON(PEM_R_NO_START_LINE) ,"no start line"}, {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),"problems getting password"}, {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA) ,"public key no rsa"}, +{ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT) ,"pvk data too short"}, +{ERR_REASON(PEM_R_PVK_TOO_SHORT) ,"pvk too short"}, {ERR_REASON(PEM_R_READ_KEY) ,"read key"}, {ERR_REASON(PEM_R_SHORT_HEADER) ,"short header"}, {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION),"unsupported encryption"}, +{ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),"unsupported key components"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/pem/pem_info.c b/crypto/openssl/crypto/pem/pem_info.c index 3a273f6f70..1b2be527ed 100644 --- a/crypto/openssl/crypto/pem/pem_info.c +++ b/crypto/openssl/crypto/pem/pem_info.c @@ -98,8 +98,8 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pe long len,error=0; int ok=0; STACK_OF(X509_INFO) *ret=NULL; - unsigned int i,raw; - d2i_of_void *d2i; + unsigned int i,raw,ptype; + d2i_of_void *d2i = 0; if (sk == NULL) { @@ -116,6 +116,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pe for (;;) { raw=0; + ptype = 0; i=PEM_read_bio(bp,&name,&header,&data,&len); if (i == 0) { @@ -166,7 +167,6 @@ start: #ifndef OPENSSL_NO_RSA if (strcmp(name,PEM_STRING_RSA) == 0) { - d2i=(D2I_OF(void))d2i_RSAPrivateKey; if (xi->x_pkey != NULL) { if (!sk_X509_INFO_push(ret,xi)) goto err; @@ -178,10 +178,8 @@ start: xi->enc_len=0; xi->x_pkey=X509_PKEY_new(); - if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) - goto err; - xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA; - pp=&(xi->x_pkey->dec_pkey->pkey.rsa); + ptype=EVP_PKEY_RSA; + pp=&xi->x_pkey->dec_pkey; if ((int)strlen(header) > 10) /* assume encrypted */ raw=1; } @@ -202,10 +200,8 @@ start: xi->enc_len=0; xi->x_pkey=X509_PKEY_new(); - if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) - goto err; - xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA; - pp=&xi->x_pkey->dec_pkey->pkey.dsa; + ptype = EVP_PKEY_DSA; + pp=&xi->x_pkey->dec_pkey; if ((int)strlen(header) > 10) /* assume encrypted */ raw=1; } @@ -226,10 +222,8 @@ start: xi->enc_len=0; xi->x_pkey=X509_PKEY_new(); - if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) - goto err; - xi->x_pkey->dec_pkey->type=EVP_PKEY_EC; - pp=&(xi->x_pkey->dec_pkey->pkey.ec); + ptype = EVP_PKEY_EC; + pp=&xi->x_pkey->dec_pkey; if ((int)strlen(header) > 10) /* assume encrypted */ raw=1; } @@ -251,7 +245,15 @@ start: if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err; p=data; - if (d2i(pp,&p,len) == NULL) + if (ptype) + { + if (!d2i_PrivateKey(ptype, pp, &p, len)) + { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB); + goto err; + } + } + else if (d2i(pp,&p,len) == NULL) { PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB); goto err; @@ -337,6 +339,12 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, { if ( (xi->enc_data!=NULL) && (xi->enc_len>0) ) { + if (enc == NULL) + { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_CIPHER_IS_NULL); + goto err; + } + /* copy from weirdo names into more normal things */ iv=xi->enc_cipher.iv; data=(unsigned char *)xi->enc_data; diff --git a/crypto/openssl/crypto/pem/pem_lib.c b/crypto/openssl/crypto/pem/pem_lib.c index cbafefe416..42e4861bc1 100644 --- a/crypto/openssl/crypto/pem/pem_lib.c +++ b/crypto/openssl/crypto/pem/pem_lib.c @@ -57,6 +57,7 @@ */ #include +#include #include "cryptlib.h" #include #include @@ -65,9 +66,13 @@ #include #include #include +#include "asn1_locl.h" #ifndef OPENSSL_NO_DES #include #endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT; @@ -75,6 +80,7 @@ const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT; static int load_iv(char **fromp,unsigned char *to, int num); static int check_pem(const char *nm, const char *name); +int pem_check_suffix(const char *pem_str, const char *suffix); int PEM_def_callback(char *buf, int num, int w, void *key) { @@ -99,7 +105,7 @@ int PEM_def_callback(char *buf, int num, int w, void *key) for (;;) { - i=EVP_read_pw_string(buf,num,prompt,w); + i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w); if (i != 0) { PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); @@ -183,20 +189,54 @@ static int check_pem(const char *nm, const char *name) /* Make PEM_STRING_EVP_PKEY match any private key */ - if(!strcmp(nm,PEM_STRING_PKCS8) && - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; - - if(!strcmp(nm,PEM_STRING_PKCS8INF) && - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; - - if(!strcmp(nm,PEM_STRING_RSA) && - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; + if(!strcmp(name,PEM_STRING_EVP_PKEY)) + { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + if(!strcmp(nm,PEM_STRING_PKCS8)) + return 1; + if(!strcmp(nm,PEM_STRING_PKCS8INF)) + return 1; + slen = pem_check_suffix(nm, "PRIVATE KEY"); + if (slen > 0) + { + /* NB: ENGINE implementations wont contain + * a deprecated old private key decode function + * so don't look for them. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (ameth && ameth->old_priv_decode) + return 1; + } + return 0; + } - if(!strcmp(nm,PEM_STRING_DSA) && - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; + if(!strcmp(name,PEM_STRING_PARAMETERS)) + { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + slen = pem_check_suffix(nm, "PARAMETERS"); + if (slen > 0) + { + ENGINE *e; + ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); + if (ameth) + { + int r; + if (ameth->param_decode) + r = 1; + else + r = 0; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return r; + } + } + return 0; + } - if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) && - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; /* Permit older strings */ if(!strcmp(nm,PEM_STRING_X509_OLD) && @@ -219,6 +259,14 @@ static int check_pem(const char *nm, const char *name) if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && !strcmp(name, PEM_STRING_PKCS7)) return 1; +#ifndef OPENSSL_NO_CMS + if(!strcmp(nm, PEM_STRING_X509) && + !strcmp(name, PEM_STRING_CMS)) return 1; + /* Allow CMS to be read from PKCS#7 headers */ + if(!strcmp(nm, PEM_STRING_PKCS7) && + !strcmp(name, PEM_STRING_CMS)) return 1; +#endif + return 0; } @@ -264,7 +312,7 @@ err: #ifndef OPENSSL_NO_FP_API int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - char *x, const EVP_CIPHER *enc, unsigned char *kstr, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { BIO *b; @@ -283,7 +331,7 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, #endif int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, - char *x, const EVP_CIPHER *enc, unsigned char *kstr, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX ctx; @@ -782,3 +830,25 @@ err: BUF_MEM_free(dataB); return(0); } + +/* Check pem string and return prefix length. + * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" + * the return value is 3 for the string "RSA". + */ + +int pem_check_suffix(const char *pem_str, const char *suffix) + { + int pem_len = strlen(pem_str); + int suffix_len = strlen(suffix); + const char *p; + if (suffix_len + 1 >= pem_len) + return 0; + p = pem_str + pem_len - suffix_len; + if (strcmp(p, suffix)) + return 0; + p--; + if (*p != ' ') + return 0; + return p - pem_str; + } + diff --git a/crypto/openssl/crypto/pem/pem_pkey.c b/crypto/openssl/crypto/pem/pem_pkey.c index 4da4c31ce5..8ecf24903b 100644 --- a/crypto/openssl/crypto/pem/pem_pkey.c +++ b/crypto/openssl/crypto/pem/pem_pkey.c @@ -65,7 +65,12 @@ #include #include #include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include "asn1_locl.h" +int pem_check_suffix(const char *pem_str, const char *suffix); EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { @@ -73,19 +78,14 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo const unsigned char *p=NULL; unsigned char *data=NULL; long len; + int slen; EVP_PKEY *ret=NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; - if (strcmp(nm,PEM_STRING_RSA) == 0) - ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); - else if (strcmp(nm,PEM_STRING_DSA) == 0) - ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); - else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0) - ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len); - else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { + if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if(!p8inf) goto p8err; @@ -119,7 +119,14 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); - } + } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) + { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (!ameth || !ameth->old_priv_decode) + goto p8err; + ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len); + } p8err: if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB); @@ -130,6 +137,74 @@ err: return(ret); } +int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) + { + char pem_str[80]; + if (!x->ameth || x->ameth->priv_encode) + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *)kstr, klen, + cb, u); + + BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_str,bp,x,enc,kstr,klen,cb,u); + } + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) + { + char *nm=NULL; + const unsigned char *p=NULL; + unsigned char *data=NULL; + long len; + int slen; + EVP_PKEY *ret=NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, + bp, 0, NULL)) + return NULL; + p = data; + + if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) + { + ret = EVP_PKEY_new(); + if (!ret) + goto err; + if (!EVP_PKEY_set_type_str(ret, nm, slen) + || !ret->ameth->param_decode + || !ret->ameth->param_decode(ret, &p, len)) + { + EVP_PKEY_free(ret); + ret = NULL; + goto err; + } + if(x) + { + if(*x) EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + } +err: + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS,ERR_R_ASN1_LIB); + OPENSSL_free(nm); + OPENSSL_free(data); + return(ret); + } + +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) + { + char pem_str[80]; + if (!x->ameth || !x->ameth->param_encode) + return 0; + + BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); + return PEM_ASN1_write_bio( + (i2d_of_void *)x->ameth->param_encode, + pem_str,bp,x,NULL,NULL,0,0,NULL); + } + #ifndef OPENSSL_NO_FP_API EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) { @@ -146,4 +221,22 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void BIO_free(b); return(ret); } + +int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) + { + BIO *b; + int ret; + + if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) + { + PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY,ERR_R_BUF_LIB); + return 0; + } + ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; + } + #endif diff --git a/crypto/openssl/crypto/pem/pem_x509.c b/crypto/openssl/crypto/pem/pem_x509.c index 3f709f13e6..b531057dc9 100644 --- a/crypto/openssl/crypto/pem/pem_x509.c +++ b/crypto/openssl/crypto/pem/pem_x509.c @@ -57,7 +57,6 @@ */ #include -#undef SSLEAY_MACROS #include "cryptlib.h" #include #include diff --git a/crypto/openssl/crypto/pem/pem_xaux.c b/crypto/openssl/crypto/pem/pem_xaux.c index 7cc7491009..328f796200 100644 --- a/crypto/openssl/crypto/pem/pem_xaux.c +++ b/crypto/openssl/crypto/pem/pem_xaux.c @@ -57,7 +57,6 @@ */ #include -#undef SSLEAY_MACROS #include "cryptlib.h" #include #include diff --git a/crypto/openssl/crypto/pem/pvkfmt.c b/crypto/openssl/crypto/pem/pvkfmt.c new file mode 100644 index 0000000000..d998a67fa5 --- /dev/null +++ b/crypto/openssl/crypto/pem/pvkfmt.c @@ -0,0 +1,942 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB + * and PRIVATEKEYBLOB). + */ + +#include "cryptlib.h" +#include +#include +#include +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) +#include +#include + +/* Utility function: read a DWORD (4 byte unsigned integer) in little endian + * format + */ + +static unsigned int read_ledword(const unsigned char **in) + { + const unsigned char *p = *in; + unsigned int ret; + ret = *p++; + ret |= (*p++ << 8); + ret |= (*p++ << 16); + ret |= (*p++ << 24); + *in = p; + return ret; + } + +/* Read a BIGNUM in little endian format. The docs say that this should take up + * bitlen/8 bytes. + */ + +static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) + { + const unsigned char *p; + unsigned char *tmpbuf, *q; + unsigned int i; + p = *in + nbyte - 1; + tmpbuf = OPENSSL_malloc(nbyte); + if (!tmpbuf) + return 0; + q = tmpbuf; + for (i = 0; i < nbyte; i++) + *q++ = *p--; + *r = BN_bin2bn(tmpbuf, nbyte, NULL); + OPENSSL_free(tmpbuf); + if (*r) + { + *in += nbyte; + return 1; + } + else + return 0; + } + + +/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ + +#define MS_PUBLICKEYBLOB 0x6 +#define MS_PRIVATEKEYBLOB 0x7 +#define MS_RSA1MAGIC 0x31415352L +#define MS_RSA2MAGIC 0x32415352L +#define MS_DSS1MAGIC 0x31535344L +#define MS_DSS2MAGIC 0x32535344L + +#define MS_KEYALG_RSA_KEYX 0xa400 +#define MS_KEYALG_DSS_SIGN 0x2200 + +#define MS_KEYTYPE_KEYX 0x1 +#define MS_KEYTYPE_SIGN 0x2 + +/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ +#define MS_PVKMAGIC 0xb0b5f11eL +/* Salt length for PVK files */ +#define PVK_SALTLEN 0x10 + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); + +static int do_blob_header(const unsigned char **in, unsigned int length, + unsigned int *pmagic, unsigned int *pbitlen, + int *pisdss, int *pispub) + { + const unsigned char *p = *in; + if (length < 16) + return 0; + /* bType */ + if (*p == MS_PUBLICKEYBLOB) + { + if (*pispub == 0) + { + PEMerr(PEM_F_DO_BLOB_HEADER, + PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + *pispub = 1; + } + else if (*p == MS_PRIVATEKEYBLOB) + { + if (*pispub == 1) + { + PEMerr(PEM_F_DO_BLOB_HEADER, + PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + *pispub = 0; + } + else + return 0; + p++; + /* Version */ + if (*p++ != 0x2) + { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER); + return 0; + } + /* Ignore reserved, aiKeyAlg */ + p+= 6; + *pmagic = read_ledword(&p); + *pbitlen = read_ledword(&p); + *pisdss = 0; + switch (*pmagic) + { + + case MS_DSS1MAGIC: + *pisdss = 1; + case MS_RSA1MAGIC: + if (*pispub == 0) + { + PEMerr(PEM_F_DO_BLOB_HEADER, + PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + break; + + case MS_DSS2MAGIC: + *pisdss = 1; + case MS_RSA2MAGIC: + if (*pispub == 1) + { + PEMerr(PEM_F_DO_BLOB_HEADER, + PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + break; + + default: + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER); + return -1; + } + *in = p; + return 1; + } + +static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) + { + unsigned int nbyte, hnbyte; + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + if (isdss) + { + + /* Expected length: 20 for q + 3 components bitlen each + 24 + * for seed structure. + */ + if (ispub) + return 44 + 3 * nbyte; + /* Expected length: 20 for q, priv, 2 bitlen components + 24 + * for seed structure. + */ + else + return 64 + 2 * nbyte; + } + else + { + /* Expected length: 4 for 'e' + 'n' */ + if (ispub) + return 4 + nbyte; + else + /* Expected length: 4 for 'e' and 7 other components. + * 2 components are bitlen size, 5 are bitlen/2 + */ + return 4 + 2*nbyte + 5*hnbyte; + } + + } + +static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, + int ispub) + { + const unsigned char *p = *in; + unsigned int bitlen, magic; + int isdss; + if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) + { + PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); + return NULL; + } + length -= 16; + if (length < blob_length(bitlen, isdss, ispub)) + { + PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + if (isdss) + return b2i_dss(&p, length, bitlen, ispub); + else + return b2i_rsa(&p, length, bitlen, ispub); + } + +static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) + { + const unsigned char *p; + unsigned char hdr_buf[16], *buf = NULL; + unsigned int bitlen, magic, length; + int isdss; + EVP_PKEY *ret = NULL; + if (BIO_read(in, hdr_buf, 16) != 16) + { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + p = hdr_buf; + if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) + return NULL; + + length = blob_length(bitlen, isdss, ispub); + buf = OPENSSL_malloc(length); + if (!buf) + { + PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (BIO_read(in, buf, length) != (int)length) + { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + goto err; + } + + if (isdss) + ret = b2i_dss(&p, length, bitlen, ispub); + else + ret = b2i_rsa(&p, length, bitlen, ispub); + + err: + if (buf) + OPENSSL_free(buf); + return ret; + } + +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub) + { + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + DSA *dsa = NULL; + BN_CTX *ctx = NULL; + unsigned int nbyte; + nbyte = (bitlen + 7) >> 3; + + dsa = DSA_new(); + ret = EVP_PKEY_new(); + if (!dsa || !ret) + goto memerr; + if (!read_lebn(&p, nbyte, &dsa->p)) + goto memerr; + if (!read_lebn(&p, 20, &dsa->q)) + goto memerr; + if (!read_lebn(&p, nbyte, &dsa->g)) + goto memerr; + if (ispub) + { + if (!read_lebn(&p, nbyte, &dsa->pub_key)) + goto memerr; + } + else + { + if (!read_lebn(&p, 20, &dsa->priv_key)) + goto memerr; + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) + goto memerr; + if (!(ctx = BN_CTX_new())) + goto memerr; + + if (!BN_mod_exp(dsa->pub_key, dsa->g, + dsa->priv_key, dsa->p, ctx)) + + goto memerr; + BN_CTX_free(ctx); + } + + EVP_PKEY_set1_DSA(ret, dsa); + DSA_free(dsa); + *in = p; + return ret; + + memerr: + PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE); + if (dsa) + DSA_free(dsa); + if (ret) + EVP_PKEY_free(ret); + if (ctx) + BN_CTX_free(ctx); + return NULL; + } + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub) + + { + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + RSA *rsa = NULL; + unsigned int nbyte, hnbyte; + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + rsa = RSA_new(); + ret = EVP_PKEY_new(); + if (!rsa || !ret) + goto memerr; + rsa->e = BN_new(); + if (!rsa->e) + goto memerr; + if (!BN_set_word(rsa->e, read_ledword(&p))) + goto memerr; + if (!read_lebn(&p, nbyte, &rsa->n)) + goto memerr; + if (!ispub) + { + if (!read_lebn(&p, hnbyte, &rsa->p)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->q)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->dmp1)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->dmq1)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->iqmp)) + goto memerr; + if (!read_lebn(&p, nbyte, &rsa->d)) + goto memerr; + } + + EVP_PKEY_set1_RSA(ret, rsa); + RSA_free(rsa); + *in = p; + return ret; + memerr: + PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); + if (rsa) + RSA_free(rsa); + if (ret) + EVP_PKEY_free(ret); + return NULL; + } + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) + { + return do_b2i(in, length, 0); + } + +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) + { + return do_b2i(in, length, 1); + } + + +EVP_PKEY *b2i_PrivateKey_bio(BIO *in) + { + return do_b2i_bio(in, 0); + } + +EVP_PKEY *b2i_PublicKey_bio(BIO *in) + { + return do_b2i_bio(in, 1); + } + +static void write_ledword(unsigned char **out, unsigned int dw) + { + unsigned char *p = *out; + *p++ = dw & 0xff; + *p++ = (dw>>8) & 0xff; + *p++ = (dw>>16) & 0xff; + *p++ = (dw>>24) & 0xff; + *out = p; + } + +static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) + { + int nb, i; + unsigned char *p = *out, *q, c; + nb = BN_num_bytes(bn); + BN_bn2bin(bn, p); + q = p + nb - 1; + /* In place byte order reversal */ + for (i = 0; i < nb/2; i++) + { + c = *p; + *p++ = *q; + *q-- = c; + } + *out += nb; + /* Pad with zeroes if we have to */ + if (len > 0) + { + len -= nb; + if (len > 0) + { + memset(*out, 0, len); + *out += len; + } + } + } + + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub); +static void write_dsa(unsigned char **out, DSA *dsa, int ispub); + +static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) + { + unsigned char *p; + unsigned int bitlen, magic = 0, keyalg; + int outlen, noinc = 0; + if (pk->type == EVP_PKEY_DSA) + { + bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic); + keyalg = MS_KEYALG_DSS_SIGN; + } + else if (pk->type == EVP_PKEY_RSA) + { + bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic); + keyalg = MS_KEYALG_RSA_KEYX; + } + else + return -1; + if (bitlen == 0) + return -1; + outlen = 16 + blob_length(bitlen, + keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); + if (out == NULL) + return outlen; + if (*out) + p = *out; + else + { + p = OPENSSL_malloc(outlen); + if (!p) + return -1; + *out = p; + noinc = 1; + } + if (ispub) + *p++ = MS_PUBLICKEYBLOB; + else + *p++ = MS_PRIVATEKEYBLOB; + *p++ = 0x2; + *p++ = 0; + *p++ = 0; + write_ledword(&p, keyalg); + write_ledword(&p, magic); + write_ledword(&p, bitlen); + if (keyalg == MS_KEYALG_DSS_SIGN) + write_dsa(&p, pk->pkey.dsa, ispub); + else + write_rsa(&p, pk->pkey.rsa, ispub); + if (!noinc) + *out += outlen; + return outlen; + } + +static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) + { + unsigned char *tmp = NULL; + int outlen, wrlen; + outlen = do_i2b(&tmp, pk, ispub); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + OPENSSL_free(tmp); + if (wrlen == outlen) + return outlen; + return -1; + } + +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) + { + int bitlen; + bitlen = BN_num_bits(dsa->p); + if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) + || (BN_num_bits(dsa->g) > bitlen)) + goto badkey; + if (ispub) + { + if (BN_num_bits(dsa->pub_key) > bitlen) + goto badkey; + *pmagic = MS_DSS1MAGIC; + } + else + { + if (BN_num_bits(dsa->priv_key) > 160) + goto badkey; + *pmagic = MS_DSS2MAGIC; + } + + return bitlen; + badkey: + PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; + } + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) + { + int nbyte, hnbyte, bitlen; + if (BN_num_bits(rsa->e) > 32) + goto badkey; + bitlen = BN_num_bits(rsa->n); + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + if (ispub) + { + *pmagic = MS_RSA1MAGIC; + return bitlen; + } + else + { + *pmagic = MS_RSA2MAGIC; + /* For private key each component must fit within nbyte or + * hnbyte. + */ + if (BN_num_bytes(rsa->d) > nbyte) + goto badkey; + if ((BN_num_bytes(rsa->iqmp) > hnbyte) + || (BN_num_bytes(rsa->p) > hnbyte) + || (BN_num_bytes(rsa->q) > hnbyte) + || (BN_num_bytes(rsa->dmp1) > hnbyte) + || (BN_num_bytes(rsa->dmq1) > hnbyte)) + goto badkey; + } + return bitlen; + badkey: + PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; + } + + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub) + { + int nbyte, hnbyte; + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + write_lebn(out, rsa->e, 4); + write_lebn(out, rsa->n, -1); + if (ispub) + return; + write_lebn(out, rsa->p, hnbyte); + write_lebn(out, rsa->q, hnbyte); + write_lebn(out, rsa->dmp1, hnbyte); + write_lebn(out, rsa->dmq1, hnbyte); + write_lebn(out, rsa->iqmp, hnbyte); + write_lebn(out, rsa->d, nbyte); + } + + +static void write_dsa(unsigned char **out, DSA *dsa, int ispub) + { + int nbyte; + nbyte = BN_num_bytes(dsa->p); + write_lebn(out, dsa->p, nbyte); + write_lebn(out, dsa->q, 20); + write_lebn(out, dsa->g, nbyte); + if (ispub) + write_lebn(out, dsa->pub_key, nbyte); + else + write_lebn(out, dsa->priv_key, 20); + /* Set "invalid" for seed structure values */ + memset(*out, 0xff, 24); + *out += 24; + return; + } + + +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) + { + return do_i2b_bio(out, pk, 0); + } + +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) + { + return do_i2b_bio(out, pk, 1); + } + +#ifndef OPENSSL_NO_RC4 + +static int do_PVK_header(const unsigned char **in, unsigned int length, + int skip_magic, + unsigned int *psaltlen, unsigned int *pkeylen) + + { + const unsigned char *p = *in; + unsigned int pvk_magic, keytype, is_encrypted; + if (skip_magic) + { + if (length < 20) + { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + return 0; + } + length -= 20; + } + else + { + if (length < 24) + { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + return 0; + } + length -= 24; + pvk_magic = read_ledword(&p); + if (pvk_magic != MS_PVKMAGIC) + { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER); + return 0; + } + } + /* Skip reserved */ + p += 4; + keytype = read_ledword(&p); + is_encrypted = read_ledword(&p); + *psaltlen = read_ledword(&p); + *pkeylen = read_ledword(&p); + + if (is_encrypted && !*psaltlen) + { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER); + return 0; + } + + *in = p; + return 1; + } + +static int derive_pvk_key(unsigned char *key, + const unsigned char *salt, unsigned int saltlen, + const unsigned char *pass, int passlen) + { + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL); + EVP_DigestUpdate(&mctx, salt, saltlen); + EVP_DigestUpdate(&mctx, pass, passlen); + EVP_DigestFinal_ex(&mctx, key, NULL); + EVP_MD_CTX_cleanup(&mctx); + return 1; + } + + +static EVP_PKEY *do_PVK_body(const unsigned char **in, + unsigned int saltlen, unsigned int keylen, + pem_password_cb *cb, void *u) + { + EVP_PKEY *ret = NULL; + const unsigned char *p = *in; + unsigned int magic; + unsigned char *enctmp = NULL, *q; + if (saltlen) + { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + EVP_CIPHER_CTX cctx; + int enctmplen, inlen; + if (cb) + inlen=cb(psbuf,PEM_BUFSIZE,0,u); + else + inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); + if (inlen <= 0) + { + PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ); + return NULL; + } + enctmp = OPENSSL_malloc(keylen + 8); + if (!enctmp) + { + PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!derive_pvk_key(keybuf, p, saltlen, + (unsigned char *)psbuf, inlen)) + return NULL; + p += saltlen; + /* Copy BLOBHEADER across, decrypt rest */ + memcpy(enctmp, p, 8); + p += 8; + inlen = keylen - 8; + q = enctmp + 8; + EVP_CIPHER_CTX_init(&cctx); + EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL); + EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen); + EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen); + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) + { + q = enctmp + 8; + memset(keybuf + 5, 0, 11); + EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, + NULL); + OPENSSL_cleanse(keybuf, 20); + EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen); + EVP_DecryptFinal_ex(&cctx, q + enctmplen, + &enctmplen); + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) + { + EVP_CIPHER_CTX_cleanup(&cctx); + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); + goto err; + } + } + else + OPENSSL_cleanse(keybuf, 20); + EVP_CIPHER_CTX_cleanup(&cctx); + p = enctmp; + } + + ret = b2i_PrivateKey(&p, keylen); + err: + if (enctmp && saltlen) + OPENSSL_free(enctmp); + return ret; + } + + +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) + { + unsigned char pvk_hdr[24], *buf = NULL; + const unsigned char *p; + int buflen; + EVP_PKEY *ret = NULL; + unsigned int saltlen, keylen; + if (BIO_read(in, pvk_hdr, 24) != 24) + { + PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + return NULL; + } + p = pvk_hdr; + + if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) + return 0; + buflen = (int) keylen + saltlen; + buf = OPENSSL_malloc(buflen); + if (!buf) + { + PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + p = buf; + if (BIO_read(in, buf, buflen) != buflen) + { + PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + goto err; + } + ret = do_PVK_body(&p, saltlen, keylen, cb, u); + + err: + if (buf) + { + OPENSSL_cleanse(buf, buflen); + OPENSSL_free(buf); + } + return ret; + } + + + +static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, + pem_password_cb *cb, void *u) + { + int outlen = 24, noinc, pklen; + unsigned char *p, *salt = NULL; + if (enclevel) + outlen += PVK_SALTLEN; + pklen = do_i2b(NULL, pk, 0); + if (pklen < 0) + return -1; + outlen += pklen; + if (!out) + return outlen; + if (*out) + { + p = *out; + noinc = 0; + } + else + { + p = OPENSSL_malloc(outlen); + if (!p) + { + PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE); + return -1; + } + *out = p; + noinc = 1; + } + + write_ledword(&p, MS_PVKMAGIC); + write_ledword(&p, 0); + if (pk->type == EVP_PKEY_DSA) + write_ledword(&p, MS_KEYTYPE_SIGN); + else + write_ledword(&p, MS_KEYTYPE_KEYX); + write_ledword(&p, enclevel ? 1 : 0); + write_ledword(&p, enclevel ? PVK_SALTLEN: 0); + write_ledword(&p, pklen); + if (enclevel) + { + if (RAND_bytes(p, PVK_SALTLEN) <= 0) + goto error; + salt = p; + p += PVK_SALTLEN; + } + do_i2b(&p, pk, 0); + if (enclevel == 0) + return outlen; + else + { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + EVP_CIPHER_CTX cctx; + int enctmplen, inlen; + if (cb) + inlen=cb(psbuf,PEM_BUFSIZE,1,u); + else + inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u); + if (inlen <= 0) + { + PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ); + goto error; + } + if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, + (unsigned char *)psbuf, inlen)) + goto error; + if (enclevel == 1) + memset(keybuf + 5, 0, 11); + p = salt + PVK_SALTLEN + 8; + EVP_CIPHER_CTX_init(&cctx); + EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL); + OPENSSL_cleanse(keybuf, 20); + EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8); + EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen); + EVP_CIPHER_CTX_cleanup(&cctx); + } + return outlen; + + error: + return -1; + } + +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u) + { + unsigned char *tmp = NULL; + int outlen, wrlen; + outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + OPENSSL_free(tmp); + if (wrlen == outlen) + { + PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE); + return outlen; + } + return -1; + } + +#endif + +#endif diff --git a/crypto/openssl/crypto/pkcs12/p12_add.c b/crypto/openssl/crypto/pkcs12/p12_add.c index 1f3e378f5c..27ac5facfa 100644 --- a/crypto/openssl/crypto/pkcs12/p12_add.c +++ b/crypto/openssl/crypto/pkcs12/p12_add.c @@ -106,6 +106,7 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, PKCS8_PRIV_KEY_INFO *p8) { PKCS12_SAFEBAG *bag; + const EVP_CIPHER *pbe_ciph; /* Set up the safe bag */ if (!(bag = PKCS12_SAFEBAG_new())) { @@ -114,8 +115,14 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, } bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe_nid = -1; + if (!(bag->value.shkeybag = - PKCS8_encrypt(pbe_nid, NULL, pass, passlen, salt, saltlen, iter, + PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, p8))) { PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); return NULL; @@ -164,6 +171,7 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, { PKCS7 *p7; X509_ALGOR *pbe; + const EVP_CIPHER *pbe_ciph; if (!(p7 = PKCS7_new())) { PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); return NULL; @@ -173,7 +181,15 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); return NULL; } - if (!(pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen))) { + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); + else + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + + if (!pbe) { PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/pkcs12/p12_attr.c b/crypto/openssl/crypto/pkcs12/p12_attr.c index 856933d978..e4d9c25647 100644 --- a/crypto/openssl/crypto/pkcs12/p12_attr.c +++ b/crypto/openssl/crypto/pkcs12/p12_attr.c @@ -60,12 +60,6 @@ #include "cryptlib.h" #include -#ifdef OPENSSL_SYS_NETWARE -/* Rename these functions to avoid name clashes on NetWare OS */ -#define uni2asc OPENSSL_uni2asc -#define asc2uni OPENSSL_asc2uni -#endif - /* Add a local keyid to a safebag */ int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, @@ -145,7 +139,7 @@ char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) ASN1_TYPE *atype; if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL; if (atype->type != V_ASN1_BMPSTRING) return NULL; - return uni2asc(atype->value.bmpstring->data, + return OPENSSL_uni2asc(atype->value.bmpstring->data, atype->value.bmpstring->length); } diff --git a/crypto/openssl/crypto/pkcs12/p12_crpt.c b/crypto/openssl/crypto/pkcs12/p12_crpt.c index f8b952e27e..b71d07b4d0 100644 --- a/crypto/openssl/crypto/pkcs12/p12_crpt.c +++ b/crypto/openssl/crypto/pkcs12/p12_crpt.c @@ -60,28 +60,10 @@ #include "cryptlib.h" #include -/* PKCS#12 specific PBE functions */ +/* PKCS#12 PBE algorithms now in static table */ void PKCS12_PBE_add(void) { -#ifndef OPENSSL_NO_RC4 -EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC4, EVP_rc4(), EVP_sha1(), - PKCS12_PBE_keyivgen); -EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC4, EVP_rc4_40(), EVP_sha1(), - PKCS12_PBE_keyivgen); -#endif -#ifndef OPENSSL_NO_DES -EVP_PBE_alg_add(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, - EVP_des_ede3_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen); -EVP_PBE_alg_add(NID_pbe_WithSHA1And2_Key_TripleDES_CBC, - EVP_des_ede_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen); -#endif -#ifndef OPENSSL_NO_RC2 -EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC2_CBC, EVP_rc2_cbc(), - EVP_sha1(), PKCS12_PBE_keyivgen); -EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(), - EVP_sha1(), PKCS12_PBE_keyivgen); -#endif } int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, diff --git a/crypto/openssl/crypto/pkcs12/p12_crt.c b/crypto/openssl/crypto/pkcs12/p12_crt.c index 9522342fa5..96b131defa 100644 --- a/crypto/openssl/crypto/pkcs12/p12_crt.c +++ b/crypto/openssl/crypto/pkcs12/p12_crt.c @@ -59,10 +59,6 @@ #include #include "cryptlib.h" #include -#ifdef OPENSSL_FIPS -#include -#endif - static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); @@ -94,14 +90,7 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, /* Set defaults */ if (!nid_cert) - { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - else -#endif nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; - } if (!nid_key) nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; if (!iter) diff --git a/crypto/openssl/crypto/pkcs12/p12_key.c b/crypto/openssl/crypto/pkcs12/p12_key.c index 5cfe7278df..a29794bbbc 100644 --- a/crypto/openssl/crypto/pkcs12/p12_key.c +++ b/crypto/openssl/crypto/pkcs12/p12_key.c @@ -69,12 +69,6 @@ extern BIO *bio_err; void h__dump (unsigned char *p, int len); #endif -#ifdef OPENSSL_SYS_NETWARE -/* Rename these functions to avoid name clashes on NetWare OS */ -#define uni2asc OPENSSL_uni2asc -#define asc2uni OPENSSL_asc2uni -#endif - /* PKCS12 compatible key/IV generation */ #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) @@ -87,15 +81,18 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, int ret; unsigned char *unipass; int uniplen; + if(!pass) { unipass = NULL; uniplen = 0; - } else if (!asc2uni(pass, passlen, &unipass, &uniplen)) { + } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE); return 0; } ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, id, iter, n, out, md_type); + if (ret <= 0) + return 0; if(unipass) { OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ OPENSSL_free(unipass); @@ -135,6 +132,8 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, #endif v = EVP_MD_block_size (md_type); u = EVP_MD_size (md_type); + if (u < 0) + return 0; D = OPENSSL_malloc (v); Ai = OPENSSL_malloc (u); B = OPENSSL_malloc (v + 1); diff --git a/crypto/openssl/crypto/pkcs12/p12_kiss.c b/crypto/openssl/crypto/pkcs12/p12_kiss.c index 5c4c6ec988..292cc3ed4a 100644 --- a/crypto/openssl/crypto/pkcs12/p12_kiss.c +++ b/crypto/openssl/crypto/pkcs12/p12_kiss.c @@ -63,16 +63,13 @@ /* Simplified PKCS#12 routines */ static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, - EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, X509 **cert, - STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid, - char *keymatch); + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, - ASN1_OCTET_STRING **keyid, char *keymatch); + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); /* Parse and decrypt a PKCS#12 structure returning user key, user cert * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, @@ -83,24 +80,20 @@ static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) { - + STACK_OF(X509) *ocerts = NULL; + X509 *x = NULL; /* Check for NULL PKCS12 structure */ - if(!p12) { + if(!p12) + { PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); return 0; - } - - /* Allocate stack for ca certificates if needed */ - if ((ca != NULL) && (*ca == NULL)) { - if (!(*ca = sk_X509_new_null())) { - PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); - return 0; } - } - if(pkey) *pkey = NULL; - if(cert) *cert = NULL; + if(pkey) + *pkey = NULL; + if(cert) + *cert = NULL; /* Check the mac */ @@ -122,19 +115,61 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, goto err; } - if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) + /* Allocate stack for other certificates */ + ocerts = sk_X509_new_null(); + + if (!ocerts) + { + PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) { PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); goto err; } + while ((x = sk_X509_pop(ocerts))) + { + if (pkey && *pkey && cert && !*cert) + { + if (X509_check_private_key(x, *pkey)) + { + *cert = x; + x = NULL; + } + } + + if (ca && x) + { + if (!*ca) + *ca = sk_X509_new_null(); + if (!*ca) + goto err; + if (!sk_X509_push(*ca, x)) + goto err; + x = NULL; + } + if (x) + X509_free(x); + } + + if (ocerts) + sk_X509_pop_free(ocerts, X509_free); + return 1; err: - if (pkey && *pkey) EVP_PKEY_free(*pkey); - if (cert && *cert) X509_free(*cert); - if (ca) sk_X509_pop_free(*ca, X509_free); + if (pkey && *pkey) + EVP_PKEY_free(*pkey); + if (cert && *cert) + X509_free(*cert); + if (x) + X509_free(*cert); + if (ocerts) + sk_X509_pop_free(ocerts, X509_free); return 0; } @@ -142,15 +177,13 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, /* Parse the outer PKCS#12 structure */ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, - EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { STACK_OF(PKCS7) *asafes; STACK_OF(PKCS12_SAFEBAG) *bags; int i, bagnid; PKCS7 *p7; - ASN1_OCTET_STRING *keyid = NULL; - char keymatch = 0; if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; for (i = 0; i < sk_PKCS7_num (asafes); i++) { p7 = sk_PKCS7_value (asafes, i); @@ -164,8 +197,7 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, sk_PKCS7_pop_free(asafes, PKCS7_free); return 0; } - if (!parse_bags(bags, pass, passlen, pkey, cert, ca, - &keyid, &keymatch)) { + if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); sk_PKCS7_pop_free(asafes, PKCS7_free); return 0; @@ -173,89 +205,65 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); } sk_PKCS7_pop_free(asafes, PKCS7_free); - if (keyid) M_ASN1_OCTET_STRING_free(keyid); return 1; } static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, X509 **cert, - STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid, - char *keymatch) + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), - pass, passlen, pkey, cert, ca, keyid, - keymatch)) return 0; + pass, passlen, pkey, ocerts)) + return 0; } return 1; } -#define MATCH_KEY 0x1 -#define MATCH_CERT 0x2 -#define MATCH_ALL 0x3 - static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, - ASN1_OCTET_STRING **keyid, - char *keymatch) + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { PKCS8_PRIV_KEY_INFO *p8; X509 *x509; - ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL; ASN1_TYPE *attrib; ASN1_BMPSTRING *fname = NULL; + ASN1_OCTET_STRING *lkid = NULL; if ((attrib = PKCS12_get_attr (bag, NID_friendlyName))) fname = attrib->value.bmpstring; - if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) { - lkey = attrib->value.octet_string; - ckid = lkey; - } + if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) + lkid = attrib->value.octet_string; - /* Check for any local key id matching (if needed) */ - if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { - if (*keyid) { - if (M_ASN1_OCTET_STRING_cmp(*keyid, lkey)) lkey = NULL; - } else { - if (!(*keyid = M_ASN1_OCTET_STRING_dup(lkey))) { - PKCS12err(PKCS12_F_PARSE_BAG,ERR_R_MALLOC_FAILURE); - return 0; - } - } - } - switch (M_PKCS12_bag_type(bag)) { case NID_keyBag: - if (!lkey || !pkey) return 1; - if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) return 0; - *keymatch |= MATCH_KEY; + if (!pkey || *pkey) + return 1; + if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) + return 0; break; case NID_pkcs8ShroudedKeyBag: - if (!lkey || !pkey) return 1; + if (!pkey || *pkey) + return 1; if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) return 0; *pkey = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (!(*pkey)) return 0; - *keymatch |= MATCH_KEY; break; case NID_certBag: if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) - return 1; - if (!(x509 = PKCS12_certbag2x509(bag))) return 0; - if(ckid) + return 1; + if (!(x509 = PKCS12_certbag2x509(bag))) + return 0; + if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { - if (!X509_keyid_set1(x509, ckid->data, ckid->length)) - { - X509_free(x509); - return 0; - } + X509_free(x509); + return 0; } if(fname) { int len, r; @@ -272,20 +280,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, } } + if(!sk_X509_push(ocerts, x509)) + { + X509_free(x509); + return 0; + } - if (lkey) { - *keymatch |= MATCH_CERT; - if (cert) *cert = x509; - else X509_free(x509); - } else { - if(ca) sk_X509_push (*ca, x509); - else X509_free(x509); - } break; case NID_safeContentsBag: return parse_bags(bag->value.safes, pass, passlen, - pkey, cert, ca, keyid, keymatch); + pkey, ocerts); break; default: diff --git a/crypto/openssl/crypto/pkcs12/p12_mutl.c b/crypto/openssl/crypto/pkcs12/p12_mutl.c index 70bfef6e5d..9ab740d51f 100644 --- a/crypto/openssl/crypto/pkcs12/p12_mutl.c +++ b/crypto/openssl/crypto/pkcs12/p12_mutl.c @@ -71,6 +71,7 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, HMAC_CTX hmac; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; + int md_size; if (!PKCS7_type_is_data(p12->authsafes)) { @@ -87,13 +88,16 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } + md_size = EVP_MD_size(md_type); + if (md_size < 0) + return 0; if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, - EVP_MD_size(md_type), key, md_type)) { + md_size, key, md_type)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR); return 0; } HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, key, EVP_MD_size(md_type), md_type, NULL); + HMAC_Init_ex(&hmac, key, md_size, md_type, NULL); HMAC_Update(&hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length); HMAC_Final(&hmac, mac, maclen); diff --git a/crypto/openssl/crypto/pkcs12/p12_npas.c b/crypto/openssl/crypto/pkcs12/p12_npas.c index 47e5e9c377..2f71355150 100644 --- a/crypto/openssl/crypto/pkcs12/p12_npas.c +++ b/crypto/openssl/crypto/pkcs12/p12_npas.c @@ -120,8 +120,13 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); - alg_get(p7->d.encrypted->enc_data->algorithm, - &pbe_nid, &pbe_iter, &pbe_saltlen); + if (!alg_get(p7->d.encrypted->enc_data->algorithm, + &pbe_nid, &pbe_iter, &pbe_saltlen)) + { + sk_PKCS12_SAFEBAG_pop_free(bags, + PKCS12_SAFEBAG_free); + bags = NULL; + } } else continue; if (!bags) { sk_PKCS7_pop_free(asafes, PKCS7_free); @@ -193,7 +198,9 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1; if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0; - alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen); + if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, + &p8_saltlen)) + return 0; if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, p8_iter, p8))) return 0; X509_SIG_free(bag->value.shkeybag); @@ -208,9 +215,11 @@ static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) p = alg->parameter->value.sequence->data; pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); + if (!pbe) + return 0; *pnid = OBJ_obj2nid(alg->algorithm); *piter = ASN1_INTEGER_get(pbe->iter); *psaltlen = pbe->salt->length; PBEPARAM_free(pbe); - return 0; + return 1; } diff --git a/crypto/openssl/crypto/pkcs12/p12_utl.c b/crypto/openssl/crypto/pkcs12/p12_utl.c index 2edbf905c5..59c6f453f6 100644 --- a/crypto/openssl/crypto/pkcs12/p12_utl.c +++ b/crypto/openssl/crypto/pkcs12/p12_utl.c @@ -60,15 +60,9 @@ #include "cryptlib.h" #include -#ifdef OPENSSL_SYS_NETWARE -/* Rename these functions to avoid name clashes on NetWare OS */ -#define uni2asc OPENSSL_uni2asc -#define asc2uni OPENSSL_asc2uni -#endif - /* Cheap and nasty Unicode stuff */ -unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen) +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen) { int ulen, i; unsigned char *unitmp; @@ -87,7 +81,7 @@ unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *un return unitmp; } -char *uni2asc(unsigned char *uni, int unilen) +char *OPENSSL_uni2asc(unsigned char *uni, int unilen) { int asclen, i; char *asctmp; diff --git a/crypto/openssl/crypto/pkcs12/pk12err.c b/crypto/openssl/crypto/pkcs12/pk12err.c index 07a1fb6907..f6ddf2df12 100644 --- a/crypto/openssl/crypto/pkcs12/pk12err.c +++ b/crypto/openssl/crypto/pkcs12/pk12err.c @@ -1,6 +1,6 @@ /* crypto/pkcs12/pk12err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/pkcs12/pkcs12.h b/crypto/openssl/crypto/pkcs12/pkcs12.h index 78317fb1fa..b17eb9f42b 100644 --- a/crypto/openssl/crypto/pkcs12/pkcs12.h +++ b/crypto/openssl/crypto/pkcs12/pkcs12.h @@ -108,8 +108,6 @@ PKCS12_MAC_DATA *mac; PKCS7 *authsafes; } PKCS12; -PREDECLARE_STACK_OF(PKCS12_SAFEBAG) - typedef struct { ASN1_OBJECT *type; union { @@ -232,14 +230,9 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, const EVP_MD *md_type); int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, const EVP_MD *md_type); -#if defined(NETWARE) || defined(OPENSSL_SYS_NETWARE) -/* Rename these functions to avoid name clashes on NetWare OS */ unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen); char *OPENSSL_uni2asc(unsigned char *uni, int unilen); -#else -unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen); -char *uni2asc(unsigned char *uni, int unilen); -#endif + DECLARE_ASN1_FUNCTIONS(PKCS12) DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) diff --git a/crypto/openssl/crypto/rc4/rc4_fblk.c b/crypto/openssl/crypto/pkcs7/bio_pk7.c similarity index 84% rename from crypto/openssl/crypto/rc4/rc4_fblk.c rename to crypto/openssl/crypto/pkcs7/bio_pk7.c index 1b2a42979b..c8d06d6cdc 100644 --- a/crypto/openssl/crypto/rc4/rc4_fblk.c +++ b/crypto/openssl/crypto/pkcs7/bio_pk7.c @@ -1,4 +1,4 @@ -/* crypto/rc4/rc4_fblk.c */ +/* bio_pk7.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ @@ -49,27 +49,21 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== + * */ +#include +#include +#include -#include -#include "rc4_locl.h" -#include -#include -#ifdef OPENSSL_FIPS -#include +#ifndef OPENSSL_SYSNAME_NETWARE +#include #endif +#include -/* FIPS mode blocking for RC4 has to be done separately since RC4_set_key - * may be implemented in an assembly language file. - */ +/* Streaming encode support for PKCS#7 */ -#ifdef OPENSSL_FIPS -void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) { - if (FIPS_mode()) - FIPS_BAD_ABORT(RC4) - private_RC4_set_key(key, len, data); + return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); } -#endif - diff --git a/crypto/openssl/crypto/pkcs7/pk7_asn1.c b/crypto/openssl/crypto/pkcs7/pk7_asn1.c index 1f70d31386..b7ec2883cb 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_asn1.c +++ b/crypto/openssl/crypto/pkcs7/pk7_asn1.c @@ -77,10 +77,39 @@ ASN1_ADB(PKCS7) = { ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) } ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); -ASN1_NDEF_SEQUENCE(PKCS7) = { +/* PKCS#7 streaming support */ +static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + PKCS7 **pp7 = (PKCS7 **)pval; + + switch(operation) + { + + case ASN1_OP_STREAM_PRE: + if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) + return 0; + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) + return 0; + break; + + } + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), ASN1_ADB_OBJECT(PKCS7) -}ASN1_NDEF_SEQUENCE_END(PKCS7) +}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7) IMPLEMENT_ASN1_FUNCTIONS(PKCS7) IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) @@ -98,7 +127,8 @@ ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = { IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) /* Minor tweak to operation: free up EVP_PKEY */ -static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_FREE_POST) { PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; @@ -140,7 +170,8 @@ ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = { IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) /* Minor tweak to operation: free up X509 */ -static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_FREE_POST) { PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; @@ -161,7 +192,7 @@ IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), - ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0) + ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0) } ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) @@ -212,3 +243,5 @@ ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) + +IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7) diff --git a/crypto/openssl/crypto/pkcs7/pk7_attr.c b/crypto/openssl/crypto/pkcs7/pk7_attr.c index d549717169..a97db51210 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_attr.c +++ b/crypto/openssl/crypto/pkcs7/pk7_attr.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -68,27 +69,12 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap) { ASN1_STRING *seq; - unsigned char *p, *pp; - int len; - len=i2d_ASN1_SET_OF_X509_ALGOR(cap,NULL,i2d_X509_ALGOR, - V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, - IS_SEQUENCE); - if(!(pp=(unsigned char *)OPENSSL_malloc(len))) { - PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); - return 0; - } - p=pp; - i2d_ASN1_SET_OF_X509_ALGOR(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, IS_SEQUENCE); if(!(seq = ASN1_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); return 0; } - if(!ASN1_STRING_set (seq, pp, len)) { - PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); - return 0; - } - OPENSSL_free (pp); + seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data, + ASN1_ITEM_rptr(X509_ALGORS)); return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, V_ASN1_SEQUENCE, seq); } @@ -102,10 +88,9 @@ STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) if (!cap || (cap->type != V_ASN1_SEQUENCE)) return NULL; p = cap->value.sequence->data; - return d2i_ASN1_SET_OF_X509_ALGOR(NULL, &p, - cap->value.sequence->length, - d2i_X509_ALGOR, X509_ALGOR_free, - V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + return (STACK_OF(X509_ALGOR) *) + ASN1_item_d2i(NULL, &p, cap->value.sequence->length, + ASN1_ITEM_rptr(X509_ALGORS)); } /* Basic smime-capabilities OID and optional integer arg */ @@ -139,3 +124,42 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) sk_X509_ALGOR_push (sk, alg); return 1; } + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) + { + if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType)) + return 0; + if (!coid) + coid = OBJ_nid2obj(NID_pkcs7_data); + return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, coid); + } + +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) + { + if (!t && !(t=X509_gmtime_adj(NULL,0))) + { + PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, + ERR_R_MALLOC_FAILURE); + return 0; + } + return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, + V_ASN1_UTCTIME, t); + } + +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen) + { + ASN1_OCTET_STRING *os; + os = ASN1_OCTET_STRING_new(); + if (!os) + return 0; + if (!ASN1_STRING_set(os, md, mdlen) + || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, os)) + { + ASN1_OCTET_STRING_free(os); + return 0; + } + return 1; + } diff --git a/crypto/openssl/crypto/pkcs7/pk7_doit.c b/crypto/openssl/crypto/pkcs7/pk7_doit.c index a03d7ebedf..451de84489 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_doit.c +++ b/crypto/openssl/crypto/pkcs7/pk7_doit.c @@ -138,6 +138,121 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) } +static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, + unsigned char *key, int keylen) + { + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkey = NULL; + unsigned char *ek = NULL; + int ret = 0; + size_t eklen; + + pkey = X509_get_pubkey(ri->cert); + + if (!pkey) + return 0; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) + { + PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) + { + PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) + goto err; + + ASN1_STRING_set0(ri->enc_key, ek, eklen); + ek = NULL; + + ret = 1; + + err: + if (pkey) + EVP_PKEY_free(pkey); + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (ek) + OPENSSL_free(ek); + return ret; + + } + + +static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, + PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) + { + EVP_PKEY_CTX *pctx = NULL; + unsigned char *ek = NULL; + size_t eklen; + + int ret = 0; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) + { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, NULL, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) + { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, ek, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) + { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + + *pek = ek; + *peklen = eklen; + + err: + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (!ret && ek) + OPENSSL_free(ek); + + return ret; + } + BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; @@ -148,7 +263,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; - EVP_PKEY *pkey; ASN1_OCTET_STRING *os=NULL; i=OBJ_obj2nid(p7->type); @@ -187,6 +301,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; + case NID_pkcs7_data: + break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; @@ -204,8 +320,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen,ivlen; - int jj,max; - unsigned char *tmp; EVP_CIPHER_CTX *ctx; if ((btmp=BIO_new(BIO_f_cipher())) == NULL) @@ -234,52 +348,16 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) goto err; } if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) - goto err; + goto err; } /* Lets do the pub key stuff :-) */ - max=0; for (i=0; icert == NULL) - { - PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); - goto err; - } - if ((pkey=X509_get_pubkey(ri->cert)) == NULL) - goto err; - jj=EVP_PKEY_size(pkey); - EVP_PKEY_free(pkey); - if (max < jj) max=jj; - } - if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) - { - PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); - goto err; - } - for (i=0; icert)) == NULL) - goto err; - jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); - EVP_PKEY_free(pkey); - if (jj <= 0) - { - PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); - OPENSSL_free(tmp); + if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) goto err; - } - if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) - { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, - ERR_R_MALLOC_FAILURE); - OPENSSL_free(tmp); - goto err; - } } - OPENSSL_free(tmp); OPENSSL_cleanse(key, keylen); if (out == NULL) @@ -303,7 +381,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) BIO_set_mem_eof_return(bio,0); } } - BIO_push(out,bio); + if (out) + BIO_push(out,bio); + else + out = bio; bio=NULL; if (0) { @@ -333,7 +414,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i,j; BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; - unsigned char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=NULL; const EVP_MD *evp_md; @@ -423,7 +503,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) int max; X509_OBJECT ret; #endif - int jj; + unsigned char *ek = NULL; + int eklen; if ((etmp=BIO_new(BIO_f_cipher())) == NULL) { @@ -438,26 +519,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) * (if any) */ - if (pcert) { - for (i=0; ienc_key), - M_ASN1_STRING_length(ri->enc_key), - pkey); - if (jj > 0) + if (pkcs7_decrypt_rinfo(&ek, &eklen, + ri, pkey) > 0) break; ERR_clear_error(); ri = NULL; @@ -485,15 +558,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } else { - jj=EVP_PKEY_decrypt(tmp, - M_ASN1_STRING_data(ri->enc_key), - M_ASN1_STRING_length(ri->enc_key), pkey); - if (jj <= 0) - { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - ERR_R_EVP_LIB); + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0) goto err; - } } evp_ctx=NULL; @@ -503,22 +569,26 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) goto err; - if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { + if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ - if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) + if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto err; } } - if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) + if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) goto err; - OPENSSL_cleanse(tmp,jj); + if (ek) + { + OPENSSL_cleanse(ek,eklen); + OPENSSL_free(ek); + } if (out == NULL) out=etmp; @@ -566,8 +636,6 @@ err: if (bio != NULL) BIO_free_all(bio); out=NULL; } - if (tmp != NULL) - OPENSSL_free(tmp); return(out); } @@ -594,13 +662,43 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) return NULL; } +static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) + { + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + + /* Add signing time if not already present */ + if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) + { + if (!PKCS7_add0_attrib_signing_time(si, NULL)) + { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, + ERR_R_MALLOC_FAILURE); + return 0; + } + } + + /* Add digest */ + EVP_DigestFinal_ex(mctx, md_data,&md_len); + if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) + { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Now sign the attributes */ + if (!PKCS7_SIGNER_INFO_sign(si)) + return 0; + + return 1; + } + + int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) { int ret=0; int i,j; BIO *btmp; - BUF_MEM *buf_mem=NULL; - BUF_MEM *buf=NULL; PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc,ctx_tmp; STACK_OF(X509_ATTRIBUTE) *sk; @@ -613,24 +711,37 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) switch (i) { + case NID_pkcs7_data: + os = p7->d.data; + break; case NID_pkcs7_signedAndEnveloped: /* XXXXXXXXXXXXXXXX */ si_sk=p7->d.signed_and_enveloped->signer_info; - if (!(os=M_ASN1_OCTET_STRING_new())) + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (!os) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); - goto err; + os=M_ASN1_OCTET_STRING_new(); + if (!os) + { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.signed_and_enveloped->enc_data->enc_data=os; } - p7->d.signed_and_enveloped->enc_data->enc_data=os; break; case NID_pkcs7_enveloped: /* XXXXXXXXXXXXXXXX */ - if (!(os=M_ASN1_OCTET_STRING_new())) + os = p7->d.enveloped->enc_data->enc_data; + if (!os) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); - goto err; + os=M_ASN1_OCTET_STRING_new(); + if (!os) + { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.enveloped->enc_data->enc_data=os; } - p7->d.enveloped->enc_data->enc_data=os; break; case NID_pkcs7_signed: si_sk=p7->d.sign->signer_info; @@ -652,21 +763,20 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) } break; + default: + PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; } if (si_sk != NULL) { - if ((buf=BUF_MEM_new()) == NULL) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); - goto err; - } for (i=0; ipkey == NULL) continue; + if (si->pkey == NULL) + continue; - j=OBJ_obj2nid(si->digest_alg->algorithm); + j = OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; @@ -678,97 +788,33 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) /* We now have the EVP_MD_CTX, lets do the * signing. */ EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); - if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); - goto err; - } sk=si->auth_attr; /* If there are attributes, we add the digest * attribute and only sign the attributes */ - if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) + if (sk_X509_ATTRIBUTE_num(sk) > 0) { - unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; - unsigned int md_len, alen; - ASN1_OCTET_STRING *digest; - ASN1_UTCTIME *sign_time; - const EVP_MD *md_tmp; - - /* Add signing time if not already present */ - if (!PKCS7_get_signed_attribute(si, - NID_pkcs9_signingTime)) - { - if (!(sign_time=X509_gmtime_adj(NULL,0))) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (!PKCS7_add_signed_attribute(si, - NID_pkcs9_signingTime, - V_ASN1_UTCTIME,sign_time)) - { - M_ASN1_UTCTIME_free(sign_time); - goto err; - } - } - - /* Add digest */ - md_tmp=EVP_MD_CTX_md(&ctx_tmp); - EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); - if (!(digest=M_ASN1_OCTET_STRING_new())) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, - ERR_R_MALLOC_FAILURE); + if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) goto err; - } - if (!M_ASN1_OCTET_STRING_set(digest,md_data, - md_len)) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, - ERR_R_MALLOC_FAILURE); - M_ASN1_OCTET_STRING_free(digest); + } + else + { + unsigned char *abuf = NULL; + unsigned int abuflen; + abuflen = EVP_PKEY_size(si->pkey); + abuf = OPENSSL_malloc(abuflen); + if (!abuf) goto err; - } - if (!PKCS7_add_signed_attribute(si, - NID_pkcs9_messageDigest, - V_ASN1_OCTET_STRING,digest)) + + if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, + si->pkey)) { - M_ASN1_OCTET_STRING_free(digest); + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, + ERR_R_EVP_LIB); goto err; } - - /* Now sign the attributes */ - EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); - alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, - ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); - if(!abuf) goto err; - EVP_SignUpdate(&ctx_tmp,abuf,alen); - OPENSSL_free(abuf); - } - -#ifndef OPENSSL_NO_DSA - if (si->pkey->type == EVP_PKEY_DSA) - ctx_tmp.digest=EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (si->pkey->type == EVP_PKEY_EC) - ctx_tmp.digest=EVP_ecdsa(); -#endif - - if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, - (unsigned int *)&buf->length,si->pkey)) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); - goto err; - } - if (!ASN1_STRING_set(si->enc_digest, - (unsigned char *)buf->data,buf->length)) - { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); - goto err; + ASN1_STRING_set0(si->enc_digest, abuf, abuflen); } } } @@ -783,34 +829,90 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); } - if (!PKCS7_is_detached(p7)) + if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) { + char *cont; + long contlen; btmp=BIO_find_type(bio,BIO_TYPE_MEM); if (btmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } - BIO_get_mem_ptr(btmp,&buf_mem); + contlen = BIO_get_mem_data(btmp, &cont); /* Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); - os->data = (unsigned char *)buf_mem->data; - os->length = buf_mem->length; -#if 0 - M_ASN1_OCTET_STRING_set(os, - (unsigned char *)buf_mem->data,buf_mem->length); -#endif + ASN1_STRING_set0(os, (unsigned char *)cont, contlen); } ret=1; err: EVP_MD_CTX_cleanup(&ctx_tmp); - if (buf != NULL) BUF_MEM_free(buf); return(ret); } +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) + { + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; + size_t siglen; + const EVP_MD *md = NULL; + + md = EVP_get_digestbyobj(si->digest_alg->algorithm); + if (md == NULL) + return 0; + + EVP_MD_CTX_init(&mctx); + if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) + { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + goto err; + } + + alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf, + ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); + if(!abuf) + goto err; + if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0) + goto err; + OPENSSL_free(abuf); + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + abuf = OPENSSL_malloc(siglen); + if(!abuf) + goto err; + if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) + { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + goto err; + } + + EVP_MD_CTX_cleanup(&mctx); + + ASN1_STRING_set0(si->enc_digest, abuf, siglen); + + return 1; + + err: + if (abuf) + OPENSSL_free(abuf); + EVP_MD_CTX_cleanup(&mctx); + return 0; + + } + int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si) { @@ -922,7 +1024,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; - unsigned int md_len, alen; + unsigned int md_len; + int alen; ASN1_OCTET_STRING *message_digest; EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); @@ -954,6 +1057,12 @@ for (ii=0; iitype == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); -#endif i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); EVP_PKEY_free(pkey); @@ -1107,8 +1210,9 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, if (*sk == NULL) { - if (!(*sk = sk_X509_ATTRIBUTE_new_null())) - return 0; + *sk = sk_X509_ATTRIBUTE_new_null(); + if (*sk == NULL) + return 0; new_attrib: if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) return 0; diff --git a/crypto/openssl/crypto/pkcs7/pk7_lib.c b/crypto/openssl/crypto/pkcs7/pk7_lib.c index f2490941a3..3ca0952792 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_lib.c +++ b/crypto/openssl/crypto/pkcs7/pk7_lib.c @@ -60,6 +60,7 @@ #include "cryptlib.h" #include #include +#include "asn1_locl.h" long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) { @@ -314,7 +315,7 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) *sk=sk_X509_new_null(); if (*sk == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE); + PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); return 0; } CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); @@ -365,13 +366,8 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) { - int nid; - char is_dsa; + int ret; - if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC) - is_dsa = 1; - else - is_dsa = 0; /* We now need to add another PKCS7_SIGNER_INFO entry */ if (!ASN1_INTEGER_set(p7i->version,1)) goto err; @@ -391,65 +387,55 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, p7i->pkey=pkey; /* Set the algorithms */ - if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1); - else - p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst)); - if (p7i->digest_alg->parameter != NULL) - ASN1_TYPE_free(p7i->digest_alg->parameter); - if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL) - goto err; - p7i->digest_alg->parameter->type=V_ASN1_NULL; + X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), + V_ASN1_NULL, NULL); - if (p7i->digest_enc_alg->parameter != NULL) - ASN1_TYPE_free(p7i->digest_enc_alg->parameter); - nid = EVP_PKEY_type(pkey->type); - if (nid == EVP_PKEY_RSA) + if (pkey->ameth && pkey->ameth->pkey_ctrl) { - p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption); - if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) - goto err; - p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; - } - else if (nid == EVP_PKEY_DSA) - { -#if 1 - /* use 'dsaEncryption' OID for compatibility with other software - * (PKCS #7 v1.5 does specify how to handle DSA) ... */ - p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa); -#else - /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS) - * would make more sense. */ - p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1); -#endif - p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */ - } - else if (nid == EVP_PKEY_EC) - { - p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1); - if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) - goto err; - p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, + 0, p7i); + if (ret > 0) + return 1; + if (ret != -2) + { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_CTRL_FAILURE); + return 0; + } } - else - return(0); - - return(1); + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); err: - return(0); + return 0; } PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) { - PKCS7_SIGNER_INFO *si; + PKCS7_SIGNER_INFO *si = NULL; + + if (dgst == NULL) + { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) + goto err; + dgst = EVP_get_digestbynid(def_nid); + if (dgst == NULL) + { + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, + PKCS7_R_NO_DEFAULT_DIGEST); + goto err; + } + } if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err; if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err; if (!PKCS7_add_signer(p7,si)) goto err; return(si); err: - PKCS7_SIGNER_INFO_free(si); + if (si) + PKCS7_SIGNER_INFO_free(si); return(NULL); } @@ -485,6 +471,23 @@ STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) return(NULL); } +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig) + { + if (pk) + *pk = si->pkey; + if (pdig) + *pdig = si->digest_alg; + if (psig) + *psig = si->digest_enc_alg; + } + +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) + { + if (penc) + *penc = ri->key_enc_algor; + } + PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) { PKCS7_RECIP_INFO *ri; @@ -492,10 +495,11 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err; if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err; if (!PKCS7_add_recipient_info(p7,ri)) goto err; - return(ri); + return ri; err: - PKCS7_RECIP_INFO_free(ri); - return(NULL); + if (ri) + PKCS7_RECIP_INFO_free(ri); + return NULL; } int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) @@ -524,6 +528,8 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) { + int ret; + EVP_PKEY *pkey = NULL; if (!ASN1_INTEGER_set(p7i->version,0)) return 0; if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, @@ -535,14 +541,41 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) return 0; - X509_ALGOR_free(p7i->key_enc_algor); - if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor))) - return 0; + pkey = X509_get_pubkey(x509); + + if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) + { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, + 0, p7i); + if (ret == -2) + { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + if (ret <= 0) + { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_CTRL_FAILURE); + goto err; + } + + EVP_PKEY_free(pkey); CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); p7i->cert=x509; - return(1); + return 1; + + err: + if (pkey) + EVP_PKEY_free(pkey); + return 0; } X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) @@ -587,3 +620,48 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) return 1; } +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) + { + ASN1_OCTET_STRING *os = NULL; + + switch (OBJ_obj2nid(p7->type)) + { + case NID_pkcs7_data: + os = p7->d.data; + break; + + case NID_pkcs7_signedAndEnveloped: + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (os == NULL) + { + os=M_ASN1_OCTET_STRING_new(); + p7->d.signed_and_enveloped->enc_data->enc_data=os; + } + break; + + case NID_pkcs7_enveloped: + os = p7->d.enveloped->enc_data->enc_data; + if (os == NULL) + { + os=M_ASN1_OCTET_STRING_new(); + p7->d.enveloped->enc_data->enc_data=os; + } + break; + + case NID_pkcs7_signed: + os=p7->d.sign->contents->d.data; + break; + + default: + os = NULL; + break; + } + + if (os == NULL) + return 0; + + os->flags |= ASN1_STRING_FLAG_NDEF; + *boundary = &os->data; + + return 1; + } diff --git a/crypto/openssl/crypto/pkcs7/pk7_mime.c b/crypto/openssl/crypto/pkcs7/pk7_mime.c index 7762d647ca..938f79a646 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_mime.c +++ b/crypto/openssl/crypto/pkcs7/pk7_mime.c @@ -59,57 +59,19 @@ #include #include -/* PKCS#7 wrappers round generalised MIME routines */ +/* PKCS#7 wrappers round generalised stream and MIME routines */ -PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) { - return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags, + ASN1_ITEM_rptr(PKCS7)); } -/* Callback for int_smime_write_ASN1 */ - -static int pk7_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, - const ASN1_ITEM *it) +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) { - PKCS7 *p7 = (PKCS7 *)val; - BIO *tmpbio, *p7bio; - int r = 0; - - if (!(flags & SMIME_DETACHED)) - { - SMIME_crlf_copy(data, out, flags); - return 1; - } - - /* Let PKCS7 code prepend any needed BIOs */ - - p7bio = PKCS7_dataInit(p7, out); - - if (!p7bio) - return 0; - - /* Copy data across, passing through filter BIOs for processing */ - SMIME_crlf_copy(data, p7bio, flags); - - /* Finalize structure */ - if (PKCS7_dataFinal(p7, p7bio) <= 0) - goto err; - - r = 1; - - err: - - /* Now remove any digests prepended to the BIO */ - - while (p7bio != out) - { - tmpbio = BIO_pop(p7bio); - BIO_free(p7bio); - p7bio = tmpbio; - } - - return 1; - + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags, + "PKCS7", + ASN1_ITEM_rptr(PKCS7)); } int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) @@ -121,8 +83,15 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) else mdalgs = NULL; - return int_smime_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, + flags ^= SMIME_OLDMIME; + + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, ctype_nid, NID_undef, mdalgs, - pk7_output_data, ASN1_ITEM_rptr(PKCS7)); } + +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) + { + return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); + } diff --git a/crypto/openssl/crypto/pkcs7/pk7_smime.c b/crypto/openssl/crypto/pkcs7/pk7_smime.c index fd18ec3d95..86742d0dcd 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_smime.c +++ b/crypto/openssl/crypto/pkcs7/pk7_smime.c @@ -63,24 +63,19 @@ #include #include +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); + PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags) { - PKCS7 *p7 = NULL; - PKCS7_SIGNER_INFO *si; - BIO *p7bio = NULL; - STACK_OF(X509_ALGOR) *smcap = NULL; + PKCS7 *p7; int i; - if(!X509_check_private_key(signcert, pkey)) { - PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - return NULL; - } - - if(!(p7 = PKCS7_new())) { + if(!(p7 = PKCS7_new())) + { PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); return NULL; - } + } if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err; @@ -88,82 +83,185 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, if (!PKCS7_content_new(p7, NID_pkcs7_data)) goto err; - if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { - PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); + if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) + { + PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR); goto err; - } + } - if(!(flags & PKCS7_NOCERTS)) { - if (!PKCS7_add_certificate(p7, signcert)) - goto err; - if(certs) for(i = 0; i < sk_X509_num(certs); i++) + if(!(flags & PKCS7_NOCERTS)) + { + for(i = 0; i < sk_X509_num(certs); i++) + { if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) goto err; - } + } + } - if(!(flags & PKCS7_NOATTR)) { - if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, - V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) - goto err; - /* Add SMIMECapabilities */ - if(!(flags & PKCS7_NOSMIMECAP)) + if(flags & PKCS7_DETACHED) + PKCS7_set_detached(p7, 1); + + if (flags & (PKCS7_STREAM|PKCS7_PARTIAL)) + return p7; + + if (PKCS7_final(p7, data, flags)) + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags) + { + BIO *p7bio; + int ret = 0; + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { - if(!(smcap = sk_X509_ALGOR_new_null())) { - PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); - goto err; - } -#ifndef OPENSSL_NO_DES - if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1)) - goto err; -#endif -#ifndef OPENSSL_NO_RC2 - if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128)) - goto err; - if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64)) - goto err; -#endif -#ifndef OPENSSL_NO_DES - if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1)) - goto err; -#endif -#ifndef OPENSSL_NO_RC2 - if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40)) - goto err; -#endif - if (!PKCS7_add_attrib_smimecap (si, smcap)) - goto err; - sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); - smcap = NULL; + PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE); + return 0; } - } - if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); + SMIME_crlf_copy(data, p7bio, flags); - if (flags & PKCS7_STREAM) - return p7; + (void)BIO_flush(p7bio); - if (!(p7bio = PKCS7_dataInit(p7, NULL))) { - PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); + if (!PKCS7_dataFinal(p7,p7bio)) + { + PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN); goto err; + } + + ret = 1; + + err: + BIO_free_all(p7bio); + + return ret; + } - SMIME_crlf_copy(data, p7bio, flags); +/* Check to see if a cipher exists and if so add S/MIME capabilities */ +static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) + { + if (EVP_get_cipherbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; + } - if (!PKCS7_dataFinal(p7,p7bio)) { - PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN); - goto err; +static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) + { + if (EVP_get_digestbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; } - BIO_free_all(p7bio); - return p7; -err: - sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); - BIO_free_all(p7bio); - PKCS7_free(p7); +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, + EVP_PKEY *pkey, const EVP_MD *md, + int flags) + { + PKCS7_SIGNER_INFO *si = NULL; + STACK_OF(X509_ALGOR) *smcap = NULL; + if(!X509_check_private_key(signcert, pkey)) + { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + + if (!(si = PKCS7_add_signature(p7,signcert,pkey, md))) + { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); + return NULL; + } + + if(!(flags & PKCS7_NOCERTS)) + { + if (!PKCS7_add_certificate(p7, signcert)) + goto err; + } + + if(!(flags & PKCS7_NOATTR)) + { + if (!PKCS7_add_attrib_content_type(si, NULL)) + goto err; + /* Add SMIMECapabilities */ + if(!(flags & PKCS7_NOSMIMECAP)) + { + if(!(smcap = sk_X509_ALGOR_new_null())) + { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) + || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) + || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) + || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) + || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) + || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) + || !add_cipher_smcap(smcap, NID_des_cbc, -1) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) + || !PKCS7_add_attrib_smimecap (si, smcap)) + goto err; + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + smcap = NULL; + } + if (flags & PKCS7_REUSE_DIGEST) + { + if (!pkcs7_copy_existing_digest(p7, si)) + goto err; + if (!(flags & PKCS7_PARTIAL) && + !PKCS7_SIGNER_INFO_sign(si)) + goto err; + } + } + return si; + err: + if (smcap) + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); return NULL; -} + } + +/* Search for a digest matching SignerInfo digest type and if found + * copy across. + */ + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) + { + int i; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *sitmp; + ASN1_OCTET_STRING *osdig = NULL; + sinfos = PKCS7_get_signer_info(p7); + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) + { + sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + if (si == sitmp) + break; + if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) + continue; + if (!OBJ_cmp(si->digest_alg->algorithm, + sitmp->digest_alg->algorithm)) + { + osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); + break; + } + + } + + if (osdig) + return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); + + PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, + PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); + return 0; + } int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags) @@ -354,7 +452,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); - return NULL; + return 0; } if(!(signers = sk_X509_new_null())) { @@ -377,12 +475,12 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) if (!signer) { PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); sk_X509_free(signers); - return NULL; + return 0; } if (!sk_X509_push(signers, signer)) { - sk_X509_free(signers); - return NULL; + sk_X509_free(signers); + return NULL; } } return signers; @@ -405,7 +503,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) goto err; - if(!PKCS7_set_cipher(p7, cipher)) { + if (!PKCS7_set_cipher(p7, cipher)) { PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); goto err; } @@ -419,22 +517,11 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, } } - if(!(p7bio = PKCS7_dataInit(p7, NULL))) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); - goto err; - } - - SMIME_crlf_copy(in, p7bio, flags); - - (void)BIO_flush(p7bio); - - if (!PKCS7_dataFinal(p7,p7bio)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR); - goto err; - } - BIO_free_all(p7bio); + if (flags & PKCS7_STREAM) + return p7; - return p7; + if (PKCS7_final(p7, in, flags)) + return p7; err: diff --git a/crypto/openssl/crypto/pkcs7/pkcs7.h b/crypto/openssl/crypto/pkcs7/pkcs7.h index cc092d262d..e4d443193c 100644 --- a/crypto/openssl/crypto/pkcs7/pkcs7.h +++ b/crypto/openssl/crypto/pkcs7/pkcs7.h @@ -232,6 +232,9 @@ DECLARE_PKCS12_STACK_OF(PKCS7) #define PKCS7_type_is_signedAndEnveloped(a) \ (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) #define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) +#define PKCS7_type_is_encrypted(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) #define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) @@ -242,14 +245,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7) #define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) -#ifdef SSLEAY_MACROS -#ifndef PKCS7_ISSUER_AND_SERIAL_digest -#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \ - ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\ - (char *)data,md,len) -#endif -#endif - /* S/MIME related flags */ #define PKCS7_TEXT 0x1 @@ -266,6 +261,8 @@ DECLARE_PKCS12_STACK_OF(PKCS7) #define PKCS7_CRLFEOL 0x800 #define PKCS7_STREAM 0x1000 #define PKCS7_NOCRL 0x2000 +#define PKCS7_PARTIAL 0x4000 +#define PKCS7_REUSE_DIGEST 0x8000 /* Flags: for compatibility with older code */ @@ -281,7 +278,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7) DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) -#ifndef SSLEAY_MACROS int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type, unsigned char *md,unsigned int *len); #ifndef OPENSSL_NO_FP_API @@ -291,7 +287,8 @@ int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7); PKCS7 *PKCS7_dup(PKCS7 *p7); PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7); int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7); -#endif +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) @@ -307,6 +304,7 @@ DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); @@ -315,6 +313,7 @@ int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); @@ -336,9 +335,13 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); @@ -355,6 +358,12 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk); PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, + int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); @@ -367,10 +376,16 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); -int SMIME_crlf_copy(BIO *in, BIO *out, int flags); -int SMIME_text(BIO *in, BIO *out); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -383,12 +398,17 @@ void ERR_load_PKCS7_strings(void); /* Function codes. */ #define PKCS7_F_B64_READ_PKCS7 120 #define PKCS7_F_B64_WRITE_PKCS7 121 +#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 #define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 #define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 #define PKCS7_F_PKCS7_ADD_CRL 101 #define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +#define PKCS7_F_PKCS7_ADD_SIGNATURE 131 #define PKCS7_F_PKCS7_ADD_SIGNER 103 #define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 #define PKCS7_F_PKCS7_CTRL 104 #define PKCS7_F_PKCS7_DATADECODE 112 #define PKCS7_F_PKCS7_DATAFINAL 128 @@ -396,15 +416,22 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_F_PKCS7_DATASIGN 106 #define PKCS7_F_PKCS7_DATAVERIFY 107 #define PKCS7_F_PKCS7_DECRYPT 114 +#define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +#define PKCS7_F_PKCS7_ENCODE_RINFO 132 #define PKCS7_F_PKCS7_ENCRYPT 115 +#define PKCS7_F_PKCS7_FINAL 134 #define PKCS7_F_PKCS7_FIND_DIGEST 127 #define PKCS7_F_PKCS7_GET0_SIGNERS 124 +#define PKCS7_F_PKCS7_RECIP_INFO_SET 130 #define PKCS7_F_PKCS7_SET_CIPHER 108 #define PKCS7_F_PKCS7_SET_CONTENT 109 #define PKCS7_F_PKCS7_SET_DIGEST 126 #define PKCS7_F_PKCS7_SET_TYPE 110 #define PKCS7_F_PKCS7_SIGN 116 #define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 #define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 #define PKCS7_F_PKCS7_VERIFY 117 #define PKCS7_F_SMIME_READ_PKCS7 122 @@ -415,10 +442,13 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 #define PKCS7_R_CIPHER_NOT_INITIALIZED 116 #define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +#define PKCS7_R_CTRL_ERROR 152 #define PKCS7_R_DECODE_ERROR 130 #define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 #define PKCS7_R_DECRYPT_ERROR 119 #define PKCS7_R_DIGEST_FAILURE 101 +#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 #define PKCS7_R_ERROR_ADDING_RECIPIENT 120 #define PKCS7_R_ERROR_SETTING_CIPHER 121 #define PKCS7_R_INVALID_MIME_TYPE 131 @@ -429,6 +459,8 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_R_MISSING_CERIPEND_INFO 103 #define PKCS7_R_NO_CONTENT 122 #define PKCS7_R_NO_CONTENT_TYPE 135 +#define PKCS7_R_NO_DEFAULT_DIGEST 151 +#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 #define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 #define PKCS7_R_NO_MULTIPART_BOUNDARY 137 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 @@ -438,6 +470,7 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_R_NO_SIG_CONTENT_TYPE 138 #define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 #define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 #define PKCS7_R_PKCS7_DATAFINAL 126 #define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 #define PKCS7_R_PKCS7_DATASIGN 145 @@ -446,6 +479,8 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 #define PKCS7_R_SIGNATURE_FAILURE 105 #define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +#define PKCS7_R_SIGNING_CTRL_FAILURE 147 +#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 #define PKCS7_R_SIG_INVALID_MIME_TYPE 141 #define PKCS7_R_SMIME_TEXT_ERROR 129 #define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 diff --git a/crypto/openssl/crypto/pkcs7/pkcs7err.c b/crypto/openssl/crypto/pkcs7/pkcs7err.c index c0e3d4cd33..d0af32a265 100644 --- a/crypto/openssl/crypto/pkcs7/pkcs7err.c +++ b/crypto/openssl/crypto/pkcs7/pkcs7err.c @@ -1,6 +1,6 @@ /* crypto/pkcs7/pkcs7err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -72,12 +72,17 @@ static ERR_STRING_DATA PKCS7_str_functs[]= { {ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"}, {ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"}, +{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "DO_PKCS7_SIGNED_ATTRIB"}, +{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM), "i2d_PKCS7_bio_stream"}, +{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME), "PKCS7_add0_attrib_signing_time"}, {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), "PKCS7_add_attrib_smimecap"}, {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"}, {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"}, {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"}, +{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"}, {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, +{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), "PKCS7_COPY_EXISTING_DIGEST"}, {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"}, {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, @@ -85,15 +90,22 @@ static ERR_STRING_DATA PKCS7_str_functs[]= {ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, +{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"}, +{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"}, {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, +{ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"}, {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"}, +{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"}, {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"}, {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"}, {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"}, {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"}, {ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"}, {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"}, +{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"}, +{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"}, +{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"}, {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"}, {ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"}, {ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"}, @@ -107,10 +119,13 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"}, {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"}, {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"}, +{ERR_REASON(PKCS7_R_CTRL_ERROR) ,"ctrl error"}, {ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"}, {ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"}, {ERR_REASON(PKCS7_R_DIGEST_FAILURE) ,"digest failure"}, +{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE),"encryption ctrl failure"}, +{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"encryption not supported for this key type"}, {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"}, {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"}, {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"}, @@ -121,6 +136,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"}, {ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"}, {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"}, +{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST) ,"no default digest"}, +{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"}, {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"}, @@ -130,6 +147,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"}, {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"}, {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"}, +{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR),"pkcs7 add signer error"}, {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) ,"pkcs7 datafinal"}, {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"}, {ERR_REASON(PKCS7_R_PKCS7_DATASIGN) ,"pkcs7 datasign"}, @@ -138,6 +156,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"}, {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"}, {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"}, +{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"}, +{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"}, {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"}, {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"}, {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"}, diff --git a/crypto/openssl/crypto/pqueue/pq_compat.h b/crypto/openssl/crypto/pqueue/pq_compat.h deleted file mode 100644 index 7b2c32725c..0000000000 --- a/crypto/openssl/crypto/pqueue/pq_compat.h +++ /dev/null @@ -1,152 +0,0 @@ -/* crypto/pqueue/pqueue_compat.h */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-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). - * - */ - -#ifndef HEADER_PQ_COMPAT_H -#define HEADER_PQ_COMPAT_H - -#include -#include - -/* - * The purpose of this header file is for supporting 64-bit integer - * manipulation on 32-bit (and lower) machines. Currently the only - * such environment is VMS, Utrix and those with smaller default integer - * sizes than 32 bits. For all such environment, we fall back to using - * BIGNUM. We may need to fine tune the conditions for systems that - * are incorrectly configured. - * - * The only clients of this code are (1) pqueue for priority, and - * (2) DTLS, for sequence number manipulation. - */ - -#if (defined(THIRTY_TWO_BIT) && !defined(BN_LLONG)) || defined(SIXTEEN_BIT) || defined(EIGHT_BIT) - -#define PQ_64BIT_IS_INTEGER 0 -#define PQ_64BIT_IS_BIGNUM 1 - -#define PQ_64BIT BIGNUM -#define PQ_64BIT_CTX BN_CTX - -#define pq_64bit_init(x) BN_init(x) -#define pq_64bit_free(x) BN_free(x) - -#define pq_64bit_ctx_new(ctx) BN_CTX_new() -#define pq_64bit_ctx_free(x) BN_CTX_free(x) - -#define pq_64bit_assign(x, y) BN_copy(x, y) -#define pq_64bit_assign_word(x, y) BN_set_word(x, y) -#define pq_64bit_gt(x, y) BN_ucmp(x, y) >= 1 ? 1 : 0 -#define pq_64bit_eq(x, y) BN_ucmp(x, y) == 0 ? 1 : 0 -#define pq_64bit_add_word(x, w) BN_add_word(x, w) -#define pq_64bit_sub(r, x, y) BN_sub(r, x, y) -#define pq_64bit_sub_word(x, w) BN_sub_word(x, w) -#define pq_64bit_mod(r, x, n, ctx) BN_mod(r, x, n, ctx) - -#define pq_64bit_bin2num(bn, bytes, len) BN_bin2bn(bytes, len, bn) -#define pq_64bit_num2bin(bn, bytes) BN_bn2bin(bn, bytes) -#define pq_64bit_get_word(x) BN_get_word(x) -#define pq_64bit_is_bit_set(x, offset) BN_is_bit_set(x, offset) -#define pq_64bit_lshift(r, x, shift) BN_lshift(r, x, shift) -#define pq_64bit_set_bit(x, num) BN_set_bit(x, num) -#define pq_64bit_get_length(x) BN_num_bits((x)) - -#else - -#define PQ_64BIT_IS_INTEGER 1 -#define PQ_64BIT_IS_BIGNUM 0 - -#if defined(SIXTY_FOUR_BIT) -#define PQ_64BIT BN_ULONG -#define PQ_64BIT_PRINT "%lld" -#elif defined(SIXTY_FOUR_BIT_LONG) -#define PQ_64BIT BN_ULONG -#define PQ_64BIT_PRINT "%ld" -#elif defined(THIRTY_TWO_BIT) -#define PQ_64BIT BN_ULLONG -#define PQ_64BIT_PRINT "%lld" -#endif - -#define PQ_64BIT_CTX void - -#define pq_64bit_init(x) -#define pq_64bit_free(x) -#define pq_64bit_ctx_new(ctx) (ctx) -#define pq_64bit_ctx_free(x) - -#define pq_64bit_assign(x, y) (*(x) = *(y)) -#define pq_64bit_assign_word(x, y) (*(x) = y) -#define pq_64bit_gt(x, y) (*(x) > *(y)) -#define pq_64bit_eq(x, y) (*(x) == *(y)) -#define pq_64bit_add_word(x, w) (*(x) = (*(x) + (w))) -#define pq_64bit_sub(r, x, y) (*(r) = (*(x) - *(y))) -#define pq_64bit_sub_word(x, w) (*(x) = (*(x) - (w))) -#define pq_64bit_mod(r, x, n, ctx) - -#define pq_64bit_bin2num(num, bytes, len) bytes_to_long_long(bytes, num) -#define pq_64bit_num2bin(num, bytes) long_long_to_bytes(num, bytes) -#define pq_64bit_get_word(x) *(x) -#define pq_64bit_lshift(r, x, shift) (*(r) = (*(x) << (shift))) -#define pq_64bit_set_bit(x, num) do { \ - PQ_64BIT mask = 1; \ - mask = mask << (num); \ - *(x) |= mask; \ - } while(0) -#endif /* OPENSSL_SYS_VMS */ - -#endif diff --git a/crypto/openssl/crypto/pqueue/pqueue.c b/crypto/openssl/crypto/pqueue/pqueue.c index 6c89f06fb1..99a6fb874d 100644 --- a/crypto/openssl/crypto/pqueue/pqueue.c +++ b/crypto/openssl/crypto/pqueue/pqueue.c @@ -68,13 +68,12 @@ typedef struct _pqueue } pqueue_s; pitem * -pitem_new(PQ_64BIT priority, void *data) +pitem_new(unsigned char *prio64be, void *data) { pitem *item = (pitem *) OPENSSL_malloc(sizeof(pitem)); if (item == NULL) return NULL; - pq_64bit_init(&(item->priority)); - pq_64bit_assign(&item->priority, &priority); + memcpy(item->priority,prio64be,sizeof(item->priority)); item->data = data; item->next = NULL; @@ -87,7 +86,6 @@ pitem_free(pitem *item) { if (item == NULL) return; - pq_64bit_free(&(item->priority)); OPENSSL_free(item); } @@ -124,7 +122,10 @@ pqueue_insert(pqueue_s *pq, pitem *item) next != NULL; curr = next, next = next->next) { - if (pq_64bit_gt(&(next->priority), &(item->priority))) + /* we can compare 64-bit value in big-endian encoding + * with memcmp:-) */ + int cmp = memcmp(next->priority, item->priority,8); + if (cmp > 0) /* next > item */ { item->next = next; @@ -135,8 +136,8 @@ pqueue_insert(pqueue_s *pq, pitem *item) return item; } - /* duplicates not allowed */ - if (pq_64bit_eq(&(item->priority), &(next->priority))) + + else if (cmp == 0) /* duplicates not allowed */ return NULL; } @@ -164,7 +165,7 @@ pqueue_pop(pqueue_s *pq) } pitem * -pqueue_find(pqueue_s *pq, PQ_64BIT priority) +pqueue_find(pqueue_s *pq, unsigned char *prio64be) { pitem *next, *prev = NULL; pitem *found = NULL; @@ -175,7 +176,7 @@ pqueue_find(pqueue_s *pq, PQ_64BIT priority) for ( next = pq->items; next->next != NULL; prev = next, next = next->next) { - if ( pq_64bit_eq(&(next->priority), &priority)) + if ( memcmp(next->priority, prio64be,8) == 0) { found = next; break; @@ -183,7 +184,7 @@ pqueue_find(pqueue_s *pq, PQ_64BIT priority) } /* check the one last node */ - if ( pq_64bit_eq(&(next->priority), &priority)) + if ( memcmp(next->priority, prio64be,8) ==0) found = next; if ( ! found) @@ -199,7 +200,6 @@ pqueue_find(pqueue_s *pq, PQ_64BIT priority) return found; } -#if PQ_64BIT_IS_INTEGER void pqueue_print(pqueue_s *pq) { @@ -207,11 +207,14 @@ pqueue_print(pqueue_s *pq) while(item != NULL) { - printf("item\t" PQ_64BIT_PRINT "\n", item->priority); + printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n", + item->priority[0],item->priority[1], + item->priority[2],item->priority[3], + item->priority[4],item->priority[5], + item->priority[6],item->priority[7]); item = item->next; } } -#endif pitem * pqueue_iterator(pqueue_s *pq) diff --git a/crypto/openssl/crypto/pqueue/pqueue.h b/crypto/openssl/crypto/pqueue/pqueue.h index 16c4072681..87fc9037c8 100644 --- a/crypto/openssl/crypto/pqueue/pqueue.h +++ b/crypto/openssl/crypto/pqueue/pqueue.h @@ -64,20 +64,18 @@ #include #include -#include - typedef struct _pqueue *pqueue; typedef struct _pitem { - PQ_64BIT priority; + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ void *data; struct _pitem *next; } pitem; typedef struct _pitem *piterator; -pitem *pitem_new(PQ_64BIT priority, void *data); +pitem *pitem_new(unsigned char *prio64be, void *data); void pitem_free(pitem *item); pqueue pqueue_new(void); @@ -86,7 +84,7 @@ void pqueue_free(pqueue pq); pitem *pqueue_insert(pqueue pq, pitem *item); pitem *pqueue_peek(pqueue pq); pitem *pqueue_pop(pqueue pq); -pitem *pqueue_find(pqueue pq, PQ_64BIT priority); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); pitem *pqueue_iterator(pqueue pq); pitem *pqueue_next(piterator *iter); diff --git a/crypto/openssl/crypto/rand/md_rand.c b/crypto/openssl/crypto/rand/md_rand.c index 0f8dd3e00f..88088ce73c 100644 --- a/crypto/openssl/crypto/rand/md_rand.c +++ b/crypto/openssl/crypto/rand/md_rand.c @@ -126,10 +126,6 @@ #include #include -#ifdef OPENSSL_FIPS -#include -#endif - #ifdef BN_DEBUG # define PREDICT @@ -149,7 +145,7 @@ static unsigned int crypto_lock_rand = 0; /* may be set only when a thread * holds CRYPTO_LOCK_RAND * (to prevent double locking) */ /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ -static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */ +static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */ #ifdef PREDICT @@ -217,8 +213,10 @@ static void ssleay_rand_add(const void *buf, int num, double add) /* check if we already have the lock */ if (crypto_lock_rand) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = (locking_thread == CRYPTO_thread_id()); + do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); } else @@ -274,8 +272,16 @@ static void ssleay_rand_add(const void *buf, int num, double add) } else MD_Update(&m,&(state[st_idx]),j); - + + /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ MD_Update(&m,buf,j); + /* We know that line may cause programs such as + purify and valgrind to complain about use of + uninitialized data. The problem is not, it's + with the caller. Removing that line will make + sure you get really bad randomness and thereby + other problems such as very insecure keys. */ + MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); MD_Final(&m,local_md); md_c[1]++; @@ -336,14 +342,6 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) #endif int do_stir_pool = 0; -#ifdef OPENSSL_FIPS - if(FIPS_mode()) - { - FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD); - return 0; - } -#endif - #ifdef PREDICT if (rand_predictable) { @@ -384,7 +382,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - locking_thread = CRYPTO_thread_id(); + CRYPTO_THREADID_current(&locking_threadid); CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); crypto_lock_rand = 1; @@ -476,9 +474,15 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) #endif MD_Update(&m,local_md,MD_DIGEST_LENGTH); MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); -#ifndef PURIFY - MD_Update(&m,buf,j); /* purify complains */ + +#ifndef PURIFY /* purify complains */ + /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ + MD_Update(&m,buf,j); + /* We know that line may cause programs such as + purify and valgrind to complain about use of + uninitialized data. */ #endif + k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; if (k > 0) { @@ -539,15 +543,17 @@ static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) static int ssleay_rand_status(void) { + CRYPTO_THREADID cur; int ret; int do_not_lock; + CRYPTO_THREADID_current(&cur); /* check if we already have the lock * (could happen if a RAND_poll() implementation calls RAND_status()) */ if (crypto_lock_rand) { CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = (locking_thread == CRYPTO_thread_id()); + do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); } else @@ -559,7 +565,7 @@ static int ssleay_rand_status(void) /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - locking_thread = CRYPTO_thread_id(); + CRYPTO_THREADID_cpy(&locking_threadid, &cur); CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); crypto_lock_rand = 1; } diff --git a/crypto/openssl/crypto/rand/rand.h b/crypto/openssl/crypto/rand/rand.h index ea89153cba..ac6c021763 100644 --- a/crypto/openssl/crypto/rand/rand.h +++ b/crypto/openssl/crypto/rand/rand.h @@ -72,7 +72,7 @@ extern "C" { #endif #if defined(OPENSSL_FIPS) -#define FIPS_RAND_SIZE_T int +#define FIPS_RAND_SIZE_T size_t #endif /* Already defined in ossl_typ.h */ @@ -111,15 +111,6 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); int RAND_egd(const char *path); int RAND_egd_bytes(const char *path,int bytes); int RAND_poll(void); -#ifndef OPENSSL_NO_ENGINE -#ifdef OPENSSL_FIPS -void int_RAND_init_engine_callbacks(void); -void int_RAND_set_callbacks( - int (*set_rand_func)(const RAND_METHOD *meth, - const RAND_METHOD **pmeth), - const RAND_METHOD *(*get_rand_func)(const RAND_METHOD **pmeth)); -#endif -#endif #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) @@ -137,29 +128,11 @@ void ERR_load_RAND_strings(void); /* Error codes for the RAND functions. */ /* Function codes. */ -#define RAND_F_ENG_RAND_GET_RAND_METHOD 108 -#define RAND_F_FIPS_RAND 103 -#define RAND_F_FIPS_RAND_BYTES 102 -#define RAND_F_FIPS_RAND_GET_RAND_METHOD 109 -#define RAND_F_FIPS_RAND_SET_DT 106 -#define RAND_F_FIPS_SET_DT 104 -#define RAND_F_FIPS_SET_PRNG_SEED 107 -#define RAND_F_FIPS_SET_TEST_MODE 105 #define RAND_F_RAND_GET_RAND_METHOD 101 #define RAND_F_SSLEAY_RAND_BYTES 100 /* Reason codes. */ -#define RAND_R_NON_FIPS_METHOD 105 -#define RAND_R_NOT_IN_TEST_MODE 106 -#define RAND_R_NO_KEY_SET 107 -#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101 -#define RAND_R_PRNG_ERROR 108 -#define RAND_R_PRNG_KEYED 109 -#define RAND_R_PRNG_NOT_REKEYED 102 -#define RAND_R_PRNG_NOT_RESEEDED 103 #define RAND_R_PRNG_NOT_SEEDED 100 -#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110 -#define RAND_R_PRNG_STUCK 104 #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/rand/rand_egd.c b/crypto/openssl/crypto/rand/rand_egd.c index 50bce6caba..d53b916ebe 100644 --- a/crypto/openssl/crypto/rand/rand_egd.c +++ b/crypto/openssl/crypto/rand/rand_egd.c @@ -95,7 +95,7 @@ * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. */ -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) { return(-1); diff --git a/crypto/openssl/crypto/rand/rand_eng.c b/crypto/openssl/crypto/rand/rand_eng.c deleted file mode 100644 index 1669cef43c..0000000000 --- a/crypto/openssl/crypto/rand/rand_eng.c +++ /dev/null @@ -1,152 +0,0 @@ -/* crypto/rand/rand_lib.c */ -/* 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 -#include -#include "cryptlib.h" -#include "rand_lcl.h" -#include -#ifdef OPENSSL_FIPS -#include -#include -#endif - -#ifndef OPENSSL_NO_ENGINE -#include -#endif - -#if defined(OPENSSL_FIPS) && !defined(OPENSSL_NO_ENGINE) - -/* non-NULL if default_RAND_meth is ENGINE-provided */ -static ENGINE *funct_ref =NULL; - -int eng_RAND_set_rand_method(const RAND_METHOD *meth, const RAND_METHOD **pmeth) - { - if(funct_ref) - { - ENGINE_finish(funct_ref); - funct_ref = NULL; - } - *pmeth = meth; - return 1; - } - -const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth) - { - if (!*pmeth) - { - ENGINE *e = ENGINE_get_default_RAND(); - if(e) - { - *pmeth = ENGINE_get_RAND(e); - if(!*pmeth) - { - ENGINE_finish(e); - e = NULL; - } - } - if(e) - funct_ref = e; - else - if(FIPS_mode()) - *pmeth=FIPS_rand_method(); - else - *pmeth = RAND_SSLeay(); - } - - if(FIPS_mode() - && *pmeth != FIPS_rand_check()) - { - RANDerr(RAND_F_ENG_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD); - return 0; - } - - return *pmeth; - } - -int RAND_set_rand_engine(ENGINE *engine) - { - const RAND_METHOD *tmp_meth = NULL; - if(engine) - { - if(!ENGINE_init(engine)) - return 0; - tmp_meth = ENGINE_get_RAND(engine); - if(!tmp_meth) - { - ENGINE_finish(engine); - return 0; - } - } - /* This function releases any prior ENGINE so call it first */ - RAND_set_rand_method(tmp_meth); - funct_ref = engine; - return 1; - } - -void int_RAND_init_engine_callbacks(void) - { - static int done = 0; - if (done) - return; - int_RAND_set_callbacks(eng_RAND_set_rand_method, - eng_RAND_get_rand_method); - done = 1; - } - -#endif diff --git a/crypto/openssl/crypto/rand/rand_err.c b/crypto/openssl/crypto/rand/rand_err.c index 829fb44d77..03cda4dd92 100644 --- a/crypto/openssl/crypto/rand/rand_err.c +++ b/crypto/openssl/crypto/rand/rand_err.c @@ -1,6 +1,6 @@ /* crypto/rand/rand_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -70,14 +70,6 @@ static ERR_STRING_DATA RAND_str_functs[]= { -{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD), "ENG_RAND_GET_RAND_METHOD"}, -{ERR_FUNC(RAND_F_FIPS_RAND), "FIPS_RAND"}, -{ERR_FUNC(RAND_F_FIPS_RAND_BYTES), "FIPS_RAND_BYTES"}, -{ERR_FUNC(RAND_F_FIPS_RAND_GET_RAND_METHOD), "FIPS_RAND_GET_RAND_METHOD"}, -{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT), "FIPS_RAND_SET_DT"}, -{ERR_FUNC(RAND_F_FIPS_SET_DT), "FIPS_SET_DT"}, -{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED), "FIPS_SET_PRNG_SEED"}, -{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE), "FIPS_SET_TEST_MODE"}, {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, {0,NULL} @@ -85,17 +77,7 @@ static ERR_STRING_DATA RAND_str_functs[]= static ERR_STRING_DATA RAND_str_reasons[]= { -{ERR_REASON(RAND_R_NON_FIPS_METHOD) ,"non fips method"}, -{ERR_REASON(RAND_R_NOT_IN_TEST_MODE) ,"not in test mode"}, -{ERR_REASON(RAND_R_NO_KEY_SET) ,"no key set"}, -{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"}, -{ERR_REASON(RAND_R_PRNG_ERROR) ,"prng error"}, -{ERR_REASON(RAND_R_PRNG_KEYED) ,"prng keyed"}, -{ERR_REASON(RAND_R_PRNG_NOT_REKEYED) ,"prng not rekeyed"}, -{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED) ,"prng not reseeded"}, {ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, -{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"}, -{ERR_REASON(RAND_R_PRNG_STUCK) ,"prng stuck"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/rand/rand_lcl.h b/crypto/openssl/crypto/rand/rand_lcl.h index 18cc9b1e4a..618a8ec899 100644 --- a/crypto/openssl/crypto/rand/rand_lcl.h +++ b/crypto/openssl/crypto/rand/rand_lcl.h @@ -154,16 +154,5 @@ #define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL) #endif -#ifndef OPENSSL_NO_ENGINE -void int_RAND_set_callbacks( - int (*set_rand_func)(const RAND_METHOD *meth, - const RAND_METHOD **pmeth), - const RAND_METHOD *(*get_rand_func) - (const RAND_METHOD **pmeth)); -int eng_RAND_set_rand_method(const RAND_METHOD *meth, - const RAND_METHOD **pmeth); -const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth); -#endif - #endif diff --git a/crypto/openssl/crypto/rand/rand_lib.c b/crypto/openssl/crypto/rand/rand_lib.c index da6b4e0e86..513e338985 100644 --- a/crypto/openssl/crypto/rand/rand_lib.c +++ b/crypto/openssl/crypto/rand/rand_lib.c @@ -60,82 +60,15 @@ #include #include "cryptlib.h" #include -#include "rand_lcl.h" -#ifdef OPENSSL_FIPS -#include -#include -#endif - #ifndef OPENSSL_NO_ENGINE #include #endif -static const RAND_METHOD *default_RAND_meth = NULL; - -#ifdef OPENSSL_FIPS - -static int fips_RAND_set_rand_method(const RAND_METHOD *meth, - const RAND_METHOD **pmeth) - { - *pmeth = meth; - return 1; - } - -static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth) - { - if (!*pmeth) - { - if(FIPS_mode()) - *pmeth=FIPS_rand_method(); - else - *pmeth = RAND_SSLeay(); - } - - if(FIPS_mode() - && *pmeth != FIPS_rand_check()) - { - RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD); - return 0; - } - - return *pmeth; - } - -static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth, - const RAND_METHOD **pmeth) - = fips_RAND_set_rand_method; -static const RAND_METHOD *(*RAND_get_rand_method_func) - (const RAND_METHOD **pmeth) - = fips_RAND_get_rand_method; - -#ifndef OPENSSL_NO_ENGINE -void int_RAND_set_callbacks( - int (*set_rand_func)(const RAND_METHOD *meth, - const RAND_METHOD **pmeth), - const RAND_METHOD *(*get_rand_func) - (const RAND_METHOD **pmeth)) - { - RAND_set_rand_method_func = set_rand_func; - RAND_get_rand_method_func = get_rand_func; - } -#endif - -int RAND_set_rand_method(const RAND_METHOD *meth) - { - return RAND_set_rand_method_func(meth, &default_RAND_meth); - } - -const RAND_METHOD *RAND_get_rand_method(void) - { - return RAND_get_rand_method_func(&default_RAND_meth); - } - -#else - #ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref =NULL; #endif +static const RAND_METHOD *default_RAND_meth = NULL; int RAND_set_rand_method(const RAND_METHOD *meth) { @@ -196,8 +129,6 @@ int RAND_set_rand_engine(ENGINE *engine) } #endif -#endif - void RAND_cleanup(void) { const RAND_METHOD *meth = RAND_get_rand_method(); diff --git a/crypto/openssl/crypto/rand/rand_unix.c b/crypto/openssl/crypto/rand/rand_unix.c index 71b98ec212..e9ead3a529 100644 --- a/crypto/openssl/crypto/rand/rand_unix.c +++ b/crypto/openssl/crypto/rand/rand_unix.c @@ -133,7 +133,50 @@ # define FD_SETSIZE (8*sizeof(fd_set)) #endif -#ifdef __OpenBSD__ +#ifdef __VOS__ +int RAND_poll(void) +{ + unsigned char buf[ENTROPY_NEEDED]; + pid_t curr_pid; + uid_t curr_uid; + static int first=1; + int i; + long rnd = 0; + struct timespec ts; + unsigned seed; + +/* The VOS random() function starts from a static seed so its + initial value is predictable. If random() returns the + initial value, reseed it with dynamic data. The VOS + real-time clock has a granularity of 1 nsec so it should be + reasonably difficult to predict its exact value. Do not + gratuitously reseed the PRNG because other code in this + process or thread may be using it. */ + + if (first) { + first = 0; + rnd = random (); + if (rnd == 1804289383) { + clock_gettime (CLOCK_REALTIME, &ts); + curr_pid = getpid(); + curr_uid = getuid(); + seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid; + srandom (seed); + } + } + + for (i = 0; i < sizeof(buf); i++) { + if (i % 4 == 0) + rnd = random(); + buf[i] = rnd; + rnd >>= 8; + } + RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); + memset(buf, 0, sizeof(buf)); + + return 1; +} +#elif defined __OpenBSD__ int RAND_poll(void) { u_int32_t rnd = 0, i; @@ -163,7 +206,7 @@ int RAND_poll(void) static const char *randomfiles[] = { DEVRANDOM }; struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; int fd; - size_t i; + unsigned int i; #endif #ifdef DEVRANDOM_EGD static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; @@ -176,7 +219,8 @@ int RAND_poll(void) * have this. Use /dev/urandom if you can as /dev/random may block * if it runs out of random entries. */ - for (i=0; i 0) n += r; +#if defined(OPENSSL_SYS_BEOS_R5) + if (r == 0) + snooze(t.tv_usec); +#endif } else r = -1; @@ -311,6 +364,14 @@ int RAND_poll(void) l=time(NULL); RAND_add(&l,sizeof(l),0.0); +#if defined(OPENSSL_SYS_BEOS) + { + system_info sysInfo; + get_system_info(&sysInfo); + RAND_add(&sysInfo,sizeof(sysInfo),0); + } +#endif + #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) return 1; #else diff --git a/crypto/openssl/crypto/rand/randfile.c b/crypto/openssl/crypto/rand/randfile.c index 84276d7d46..4ed40b7b70 100644 --- a/crypto/openssl/crypto/rand/randfile.c +++ b/crypto/openssl/crypto/rand/randfile.c @@ -75,9 +75,7 @@ #ifndef NO_SYS_TYPES_H # include #endif -#ifdef MAC_OS_pre_X -# include -#else +#ifndef OPENSSL_NO_POSIX_IO # include #endif @@ -111,12 +109,15 @@ int RAND_load_file(const char *file, long bytes) * if bytes == -1, read complete file. */ MS_STATIC unsigned char buf[BUFSIZE]; +#ifndef OPENSSL_NO_POSIX_IO struct stat sb; +#endif int i,ret=0,n; FILE *in; if (file == NULL) return(0); +#ifndef OPENSSL_NO_POSIX_IO #ifdef PURIFY /* struct stat can have padding and unused fields that may not be * initialized in the call to stat(). We need to clear the entire @@ -125,9 +126,9 @@ int RAND_load_file(const char *file, long bytes) */ memset(&sb, 0, sizeof(sb)); #endif - if (stat(file,&sb) < 0) return(0); RAND_add(&sb,sizeof(sb),0.0); +#endif if (bytes == 0) return(ret); #ifdef OPENSSL_SYS_VMS @@ -136,8 +137,8 @@ int RAND_load_file(const char *file, long bytes) in=fopen(file,"rb"); #endif if (in == NULL) goto err; -#if defined(S_ISBLK) && defined(S_ISCHR) - if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { +#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO) + if (sb.st_mode & (S_IFBLK | S_IFCHR)) { /* this file is a device. we don't want read an infinite number * of bytes from a random device, nor do we want to use buffered * I/O because we will waste system entropy. @@ -179,6 +180,7 @@ int RAND_write_file(const char *file) int i,ret=0,rand_err=0; FILE *out = NULL; int n; +#ifndef OPENSSL_NO_POSIX_IO struct stat sb; i=stat(file,&sb); @@ -194,14 +196,16 @@ int RAND_write_file(const char *file) } #endif } +#endif -#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS) +#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS) { - /* For some reason Win32 can't write to files created this way */ - +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* chmod(..., 0600) is too late to protect the file, * permissions should be restrictive from the start */ - int fd = open(file, O_CREAT, 0600); + int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600); if (fd != -1) out = fdopen(fd, "wb"); } diff --git a/crypto/openssl/crypto/rc2/rc2.h b/crypto/openssl/crypto/rc2/rc2.h index e542ec94ff..34c8362317 100644 --- a/crypto/openssl/crypto/rc2/rc2.h +++ b/crypto/openssl/crypto/rc2/rc2.h @@ -79,9 +79,7 @@ typedef struct rc2_key_st RC2_INT data[64]; } RC2_KEY; -#ifdef OPENSSL_FIPS -void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); -#endif + void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key, int enc); diff --git a/crypto/openssl/crypto/rc2/rc2_skey.c b/crypto/openssl/crypto/rc2/rc2_skey.c index 4e000e5b99..0150b0e035 100644 --- a/crypto/openssl/crypto/rc2/rc2_skey.c +++ b/crypto/openssl/crypto/rc2/rc2_skey.c @@ -57,14 +57,9 @@ */ #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - #include "rc2_locl.h" -static unsigned char key_table[256]={ +static const unsigned char key_table[256]={ 0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79, 0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e, 0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5, @@ -99,19 +94,7 @@ static unsigned char key_table[256]={ * BSAFE uses the 'retarded' version. What I previously shipped is * the same as specifying 1024 for the 'bits' parameter. Bsafe uses * a version where the bits parameter is the same as len*8 */ - -#ifdef OPENSSL_FIPS void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) - { - if (FIPS_mode()) - FIPS_BAD_ABORT(RC2) - private_RC2_set_key(key, len, data, bits); - } -void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, - int bits) -#else -void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) -#endif { int i,j; unsigned char *k; diff --git a/crypto/openssl/crypto/rc4/rc4.h b/crypto/openssl/crypto/rc4/rc4.h index 2d8620d33b..29d1acccf5 100644 --- a/crypto/openssl/crypto/rc4/rc4.h +++ b/crypto/openssl/crypto/rc4/rc4.h @@ -64,6 +64,8 @@ #error RC4 is disabled. #endif +#include + #ifdef __cplusplus extern "C" { #endif @@ -76,11 +78,8 @@ typedef struct rc4_key_st const char *RC4_options(void); -#ifdef OPENSSL_FIPS -void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); -#endif void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); -void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, unsigned char *outdata); #ifdef __cplusplus diff --git a/crypto/openssl/crypto/rc4/rc4_enc.c b/crypto/openssl/crypto/rc4/rc4_enc.c index 0660ea60a2..8c4fc6c7a3 100644 --- a/crypto/openssl/crypto/rc4/rc4_enc.c +++ b/crypto/openssl/crypto/rc4/rc4_enc.c @@ -67,12 +67,12 @@ * Date: Wed, 14 Sep 1994 06:35:31 GMT */ -void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, unsigned char *outdata) { register RC4_INT *d; register RC4_INT x,y,tx,ty; - int i; + size_t i; x=key->x; y=key->y; @@ -120,8 +120,8 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, (RC4_CHUNK)d[(tx+ty)&0xff]\ ) - if ( ( ((unsigned long)indata & (sizeof(RC4_CHUNK)-1)) | - ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 ) + if ( ( ((size_t)indata & (sizeof(RC4_CHUNK)-1)) | + ((size_t)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 ) { RC4_CHUNK ichunk,otp; const union { long one; char little; } is_endian = {1}; @@ -157,7 +157,7 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, if (!is_endian.little) { /* BIG-ENDIAN CASE */ # define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) - for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK)) + for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK)) { ichunk = *(RC4_CHUNK *)indata; otp = RC4_STEP<>3L); + i=len>>3; if (i) { for (;;) @@ -296,7 +296,7 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, if (--i == 0) break; } } - i=(int)len&0x07; + i=len&0x07; if (i) { for (;;) diff --git a/crypto/openssl/crypto/rc4/rc4_skey.c b/crypto/openssl/crypto/rc4/rc4_skey.c index 4478d1a4b3..b22c40b0bd 100644 --- a/crypto/openssl/crypto/rc4/rc4_skey.c +++ b/crypto/openssl/crypto/rc4/rc4_skey.c @@ -59,11 +59,6 @@ #include #include "rc4_locl.h" #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT; @@ -90,11 +85,7 @@ const char *RC4_options(void) * Date: Wed, 14 Sep 1994 06:35:31 GMT */ -#ifdef OPENSSL_FIPS -void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) -#else void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) -#endif { register RC4_INT tmp; register int id1,id2; @@ -128,20 +119,14 @@ void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) * implementations suffer from significant performance * losses then, e.g. PIII exhibits >2x deterioration, * and so does Opteron. In order to assure optimal - * all-round performance, we detect P4 at run-time by - * checking upon reserved bit 20 in CPU capability + * all-round performance, let us [try to] detect P4 at + * run-time by checking upon HTT bit in CPU capability * vector and set up compressed key schedule, which is * recognized by correspondingly updated assembler - * module... Bit 20 is set up by OPENSSL_ia32_cpuid. - * + * module... * */ -#ifdef OPENSSL_FIPS - unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); - if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { -#else if (OPENSSL_ia32cap_P & (1<<28)) { -#endif unsigned char *cp=(unsigned char *)d; for (i=0;i<256;i++) cp[i]=i; diff --git a/crypto/openssl/crypto/rc5/rc5.h b/crypto/openssl/crypto/rc5/rc5.h deleted file mode 100644 index f73a2a02a4..0000000000 --- a/crypto/openssl/crypto/rc5/rc5.h +++ /dev/null @@ -1,121 +0,0 @@ -/* crypto/rc5/rc5.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_RC5_H -#define HEADER_RC5_H - -#include /* OPENSSL_NO_RC5 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef OPENSSL_NO_RC5 -#error RC5 is disabled. -#endif - -#define RC5_ENCRYPT 1 -#define RC5_DECRYPT 0 - -/* 32 bit. For Alpha, things may get weird */ -#define RC5_32_INT unsigned long - -#define RC5_32_BLOCK 8 -#define RC5_32_KEY_LENGTH 16 /* This is a default, max is 255 */ - -/* This are the only values supported. Tweak the code if you want more - * The most supported modes will be - * RC5-32/12/16 - * RC5-32/16/8 - */ -#define RC5_8_ROUNDS 8 -#define RC5_12_ROUNDS 12 -#define RC5_16_ROUNDS 16 - -typedef struct rc5_key_st - { - /* Number of rounds */ - int rounds; - RC5_32_INT data[2*(RC5_16_ROUNDS+1)]; - } RC5_32_KEY; - -#ifdef OPENSSL_FIPS -void private_RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, - int rounds); -#endif -void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, - int rounds); -void RC5_32_ecb_encrypt(const unsigned char *in,unsigned char *out,RC5_32_KEY *key, - int enc); -void RC5_32_encrypt(unsigned long *data,RC5_32_KEY *key); -void RC5_32_decrypt(unsigned long *data,RC5_32_KEY *key); -void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, - long length, RC5_32_KEY *ks, unsigned char *iv, - int enc); -void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC5_32_KEY *schedule, - unsigned char *ivec, int *num, int enc); -void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC5_32_KEY *schedule, - unsigned char *ivec, int *num); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/crypto/openssl/crypto/rc5/rc5_ecb.c b/crypto/openssl/crypto/rc5/rc5_ecb.c deleted file mode 100644 index e72b535507..0000000000 --- a/crypto/openssl/crypto/rc5/rc5_ecb.c +++ /dev/null @@ -1,80 +0,0 @@ -/* crypto/rc5/rc5_ecb.c */ -/* 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 -#include "rc5_locl.h" -#include - -const char RC5_version[]="RC5" OPENSSL_VERSION_PTEXT; - -void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out, - RC5_32_KEY *ks, int encrypt) - { - unsigned long l,d[2]; - - c2l(in,l); d[0]=l; - c2l(in,l); d[1]=l; - if (encrypt) - RC5_32_encrypt(d,ks); - else - RC5_32_decrypt(d,ks); - l=d[0]; l2c(l,out); - l=d[1]; l2c(l,out); - l=d[0]=d[1]=0; - } - diff --git a/crypto/openssl/crypto/rc5/rc5_enc.c b/crypto/openssl/crypto/rc5/rc5_enc.c deleted file mode 100644 index f327d32a76..0000000000 --- a/crypto/openssl/crypto/rc5/rc5_enc.c +++ /dev/null @@ -1,215 +0,0 @@ -/* crypto/rc5/rc5_enc.c */ -/* 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 -#include -#include "rc5_locl.h" - -void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, - long length, RC5_32_KEY *ks, unsigned char *iv, - int encrypt) - { - register unsigned long tin0,tin1; - register unsigned long tout0,tout1,xor0,xor1; - register long l=length; - unsigned long tin[2]; - - if (encrypt) - { - c2l(iv,tout0); - c2l(iv,tout1); - iv-=8; - for (l-=8; l>=0; l-=8) - { - c2l(in,tin0); - c2l(in,tin1); - tin0^=tout0; - tin1^=tout1; - tin[0]=tin0; - tin[1]=tin1; - RC5_32_encrypt(tin,ks); - tout0=tin[0]; l2c(tout0,out); - tout1=tin[1]; l2c(tout1,out); - } - if (l != -8) - { - c2ln(in,tin0,tin1,l+8); - tin0^=tout0; - tin1^=tout1; - tin[0]=tin0; - tin[1]=tin1; - RC5_32_encrypt(tin,ks); - tout0=tin[0]; l2c(tout0,out); - tout1=tin[1]; l2c(tout1,out); - } - l2c(tout0,iv); - l2c(tout1,iv); - } - else - { - c2l(iv,xor0); - c2l(iv,xor1); - iv-=8; - for (l-=8; l>=0; l-=8) - { - c2l(in,tin0); tin[0]=tin0; - c2l(in,tin1); tin[1]=tin1; - RC5_32_decrypt(tin,ks); - tout0=tin[0]^xor0; - tout1=tin[1]^xor1; - l2c(tout0,out); - l2c(tout1,out); - xor0=tin0; - xor1=tin1; - } - if (l != -8) - { - c2l(in,tin0); tin[0]=tin0; - c2l(in,tin1); tin[1]=tin1; - RC5_32_decrypt(tin,ks); - tout0=tin[0]^xor0; - tout1=tin[1]^xor1; - l2cn(tout0,tout1,out,l+8); - xor0=tin0; - xor1=tin1; - } - l2c(xor0,iv); - l2c(xor1,iv); - } - tin0=tin1=tout0=tout1=xor0=xor1=0; - tin[0]=tin[1]=0; - } - -void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key) - { - RC5_32_INT a,b,*s; - - s=key->data; - - a=d[0]+s[0]; - b=d[1]+s[1]; - E_RC5_32(a,b,s, 2); - E_RC5_32(a,b,s, 4); - E_RC5_32(a,b,s, 6); - E_RC5_32(a,b,s, 8); - E_RC5_32(a,b,s,10); - E_RC5_32(a,b,s,12); - E_RC5_32(a,b,s,14); - E_RC5_32(a,b,s,16); - if (key->rounds == 12) - { - E_RC5_32(a,b,s,18); - E_RC5_32(a,b,s,20); - E_RC5_32(a,b,s,22); - E_RC5_32(a,b,s,24); - } - else if (key->rounds == 16) - { - /* Do a full expansion to avoid a jump */ - E_RC5_32(a,b,s,18); - E_RC5_32(a,b,s,20); - E_RC5_32(a,b,s,22); - E_RC5_32(a,b,s,24); - E_RC5_32(a,b,s,26); - E_RC5_32(a,b,s,28); - E_RC5_32(a,b,s,30); - E_RC5_32(a,b,s,32); - } - d[0]=a; - d[1]=b; - } - -void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key) - { - RC5_32_INT a,b,*s; - - s=key->data; - - a=d[0]; - b=d[1]; - if (key->rounds == 16) - { - D_RC5_32(a,b,s,32); - D_RC5_32(a,b,s,30); - D_RC5_32(a,b,s,28); - D_RC5_32(a,b,s,26); - /* Do a full expansion to avoid a jump */ - D_RC5_32(a,b,s,24); - D_RC5_32(a,b,s,22); - D_RC5_32(a,b,s,20); - D_RC5_32(a,b,s,18); - } - else if (key->rounds == 12) - { - D_RC5_32(a,b,s,24); - D_RC5_32(a,b,s,22); - D_RC5_32(a,b,s,20); - D_RC5_32(a,b,s,18); - } - D_RC5_32(a,b,s,16); - D_RC5_32(a,b,s,14); - D_RC5_32(a,b,s,12); - D_RC5_32(a,b,s,10); - D_RC5_32(a,b,s, 8); - D_RC5_32(a,b,s, 6); - D_RC5_32(a,b,s, 4); - D_RC5_32(a,b,s, 2); - d[0]=a-s[0]; - d[1]=b-s[1]; - } - diff --git a/crypto/openssl/crypto/rc5/rc5_locl.h b/crypto/openssl/crypto/rc5/rc5_locl.h deleted file mode 100644 index 282dd38822..0000000000 --- a/crypto/openssl/crypto/rc5/rc5_locl.h +++ /dev/null @@ -1,207 +0,0 @@ -/* crypto/rc5/rc5_locl.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.] - */ - -#include - -#undef c2l -#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<<24L) - -/* NOTE - c is not incremented as per c2l */ -#undef c2ln -#define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -#undef l2c -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) - -/* NOTE - c is not incremented as per l2c */ -#undef l2cn -#define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -/* NOTE - c is not incremented as per n2l */ -#define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -/* NOTE - c is not incremented as per l2n */ -#define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - } \ - } - -#undef n2l -#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) - -#undef l2n -#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC) -#define ROTATE_l32(a,n) _lrotl(a,n) -#define ROTATE_r32(a,n) _lrotr(a,n) -#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) -# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -# define ROTATE_l32(a,n) ({ register unsigned int ret; \ - asm ("roll %%cl,%0" \ - : "=r"(ret) \ - : "c"(n),"0"(a) \ - : "cc"); \ - ret; \ - }) -# define ROTATE_r32(a,n) ({ register unsigned int ret; \ - asm ("rorl %%cl,%0" \ - : "=r"(ret) \ - : "c"(n),"0"(a) \ - : "cc"); \ - ret; \ - }) -# endif -#endif -#ifndef ROTATE_l32 -#define ROTATE_l32(a,n) (((a)<<(n&0x1f))|(((a)&0xffffffff)>>(32-(n&0x1f)))) -#endif -#ifndef ROTATE_r32 -#define ROTATE_r32(a,n) (((a)<<(32-(n&0x1f)))|(((a)&0xffffffff)>>(n&0x1f))) -#endif - -#define RC5_32_MASK 0xffffffffL - -#define RC5_16_P 0xB7E1 -#define RC5_16_Q 0x9E37 -#define RC5_32_P 0xB7E15163L -#define RC5_32_Q 0x9E3779B9L -#define RC5_64_P 0xB7E151628AED2A6BLL -#define RC5_64_Q 0x9E3779B97F4A7C15LL - -#define E_RC5_32(a,b,s,n) \ - a^=b; \ - a=ROTATE_l32(a,b); \ - a+=s[n]; \ - a&=RC5_32_MASK; \ - b^=a; \ - b=ROTATE_l32(b,a); \ - b+=s[n+1]; \ - b&=RC5_32_MASK; - -#define D_RC5_32(a,b,s,n) \ - b-=s[n+1]; \ - b&=RC5_32_MASK; \ - b=ROTATE_r32(b,a); \ - b^=a; \ - a-=s[n]; \ - a&=RC5_32_MASK; \ - a=ROTATE_r32(a,b); \ - a^=b; - - - diff --git a/crypto/openssl/crypto/rc5/rc5_skey.c b/crypto/openssl/crypto/rc5/rc5_skey.c deleted file mode 100644 index 247fa6500c..0000000000 --- a/crypto/openssl/crypto/rc5/rc5_skey.c +++ /dev/null @@ -1,130 +0,0 @@ -/* crypto/rc5/rc5_skey.c */ -/* 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 -#include -#ifdef OPENSSL_FIPS -#include -#endif - -#include "rc5_locl.h" - -#ifdef OPENSSL_FIPS -void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, - int rounds) - { - if (FIPS_mode()) - FIPS_BAD_ABORT(RC5) - private_RC5_32_set_key(key, len, data, rounds); - } -void private_RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, - int rounds) -#else -void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, - int rounds) -#endif - { - RC5_32_INT L[64],l,ll,A,B,*S,k; - int i,j,m,c,t,ii,jj; - - if ( (rounds != RC5_16_ROUNDS) && - (rounds != RC5_12_ROUNDS) && - (rounds != RC5_8_ROUNDS)) - rounds=RC5_16_ROUNDS; - - key->rounds=rounds; - S= &(key->data[0]); - j=0; - for (i=0; i<=(len-8); i+=8) - { - c2l(data,l); - L[j++]=l; - c2l(data,l); - L[j++]=l; - } - ii=len-i; - if (ii) - { - k=len&0x07; - c2ln(data,l,ll,k); - L[j+0]=l; - L[j+1]=ll; - } - - c=(len+3)/4; - t=(rounds+1)*2; - S[0]=RC5_32_P; - for (i=1; ic)?t:c; - j*=3; - ii=jj=0; - A=B=0; - for (i=0; i= t) ii=0; - if (++jj >= c) jj=0; - } - } - diff --git a/crypto/openssl/crypto/rc5/rc5cfb64.c b/crypto/openssl/crypto/rc5/rc5cfb64.c deleted file mode 100644 index 3a8b60bc7a..0000000000 --- a/crypto/openssl/crypto/rc5/rc5cfb64.c +++ /dev/null @@ -1,122 +0,0 @@ -/* crypto/rc5/rc5cfb64.c */ -/* 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 -#include "rc5_locl.h" - -/* 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 RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC5_32_KEY *schedule, - unsigned char *ivec, int *num, int encrypt) - { - register unsigned long v0,v1,t; - register int n= *num; - register long l=length; - unsigned long ti[2]; - unsigned char *iv,c,cc; - - iv=(unsigned char *)ivec; - if (encrypt) - { - while (l--) - { - if (n == 0) - { - c2l(iv,v0); ti[0]=v0; - c2l(iv,v1); ti[1]=v1; - RC5_32_encrypt((unsigned long *)ti,schedule); - iv=(unsigned char *)ivec; - t=ti[0]; l2c(t,iv); - t=ti[1]; l2c(t,iv); - iv=(unsigned char *)ivec; - } - c= *(in++)^iv[n]; - *(out++)=c; - iv[n]=c; - n=(n+1)&0x07; - } - } - else - { - while (l--) - { - if (n == 0) - { - c2l(iv,v0); ti[0]=v0; - c2l(iv,v1); ti[1]=v1; - RC5_32_encrypt((unsigned long *)ti,schedule); - iv=(unsigned char *)ivec; - t=ti[0]; l2c(t,iv); - t=ti[1]; l2c(t,iv); - iv=(unsigned char *)ivec; - } - cc= *(in++); - c=iv[n]; - iv[n]=cc; - *(out++)=c^cc; - n=(n+1)&0x07; - } - } - v0=v1=ti[0]=ti[1]=t=c=cc=0; - *num=n; - } - diff --git a/crypto/openssl/crypto/rc5/rc5ofb64.c b/crypto/openssl/crypto/rc5/rc5ofb64.c deleted file mode 100644 index d412215f3c..0000000000 --- a/crypto/openssl/crypto/rc5/rc5ofb64.c +++ /dev/null @@ -1,111 +0,0 @@ -/* crypto/rc5/rc5ofb64.c */ -/* 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 -#include "rc5_locl.h" - -/* The input and output encrypted as though 64bit ofb mode is being - * used. The extra state information to record how much of the - * 64bit block we have used is contained in *num; - */ -void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC5_32_KEY *schedule, - unsigned char *ivec, int *num) - { - register unsigned long v0,v1,t; - register int n= *num; - register long l=length; - unsigned char d[8]; - register char *dp; - unsigned long ti[2]; - unsigned char *iv; - int save=0; - - iv=(unsigned char *)ivec; - c2l(iv,v0); - c2l(iv,v1); - ti[0]=v0; - ti[1]=v1; - dp=(char *)d; - l2c(v0,dp); - l2c(v1,dp); - while (l--) - { - if (n == 0) - { - RC5_32_encrypt((unsigned long *)ti,schedule); - dp=(char *)d; - t=ti[0]; l2c(t,dp); - t=ti[1]; l2c(t,dp); - save++; - } - *(out++)= *(in++)^d[n]; - n=(n+1)&0x07; - } - if (save) - { - v0=ti[0]; - v1=ti[1]; - iv=(unsigned char *)ivec; - l2c(v0,iv); - l2c(v1,iv); - } - t=v0=v1=ti[0]=ti[1]=0; - *num=n; - } - diff --git a/crypto/openssl/crypto/ripemd/ripemd.h b/crypto/openssl/crypto/ripemd/ripemd.h index 3b6d04386d..5942eb6180 100644 --- a/crypto/openssl/crypto/ripemd/ripemd.h +++ b/crypto/openssl/crypto/ripemd/ripemd.h @@ -70,7 +70,7 @@ extern "C" { #error RIPEMD is disabled. #endif -#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#if defined(__LP32__) #define RIPEMD160_LONG unsigned long #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) #define RIPEMD160_LONG unsigned long @@ -90,9 +90,7 @@ typedef struct RIPEMD160state_st RIPEMD160_LONG data[RIPEMD160_LBLOCK]; unsigned int num; } RIPEMD160_CTX; -#ifdef OPENSSL_FIPS -int private_RIPEMD160_Init(RIPEMD160_CTX *c); -#endif + int RIPEMD160_Init(RIPEMD160_CTX *c); int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); diff --git a/crypto/openssl/crypto/ripemd/rmd_dgst.c b/crypto/openssl/crypto/ripemd/rmd_dgst.c index ead11d075a..59b017f8c0 100644 --- a/crypto/openssl/crypto/ripemd/rmd_dgst.c +++ b/crypto/openssl/crypto/ripemd/rmd_dgst.c @@ -59,11 +59,6 @@ #include #include "rmd_locl.h" #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT; @@ -74,16 +69,14 @@ const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT; void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num); # endif -FIPS_NON_FIPS_MD_Init(RIPEMD160) +int RIPEMD160_Init(RIPEMD160_CTX *c) { + memset (c,0,sizeof(*c)); c->A=RIPEMD160_A; c->B=RIPEMD160_B; c->C=RIPEMD160_C; c->D=RIPEMD160_D; c->E=RIPEMD160_E; - c->Nl=0; - c->Nh=0; - c->num=0; return 1; } diff --git a/crypto/openssl/crypto/ripemd/rmd_locl.h b/crypto/openssl/crypto/ripemd/rmd_locl.h index ce12a8000e..f14b346e66 100644 --- a/crypto/openssl/crypto/ripemd/rmd_locl.h +++ b/crypto/openssl/crypto/ripemd/rmd_locl.h @@ -72,7 +72,7 @@ */ #ifdef RMD160_ASM # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) -# define ripemd160_block_host_order ripemd160_block_asm_data_order +# define ripemd160_block_data_order ripemd160_block_asm_data_order # endif #endif diff --git a/crypto/openssl/crypto/rsa/rsa.h b/crypto/openssl/crypto/rsa/rsa.h index 5bb932ae15..cf74343657 100644 --- a/crypto/openssl/crypto/rsa/rsa.h +++ b/crypto/openssl/crypto/rsa/rsa.h @@ -74,25 +74,6 @@ #error RSA is disabled. #endif -/* If this flag is set the RSA method is FIPS compliant and can be used - * in FIPS mode. This is set in the validated module method. If an - * application sets this flag in its own methods it is its reposibility - * to ensure the result is compliant. - */ - -#define RSA_FLAG_FIPS_METHOD 0x0400 - -/* If this flag is set the operations normally disabled in FIPS mode are - * permitted it is then the applications responsibility to ensure that the - * usage is compliant. - */ - -#define RSA_FLAG_NON_FIPS_ALLOW 0x0400 - -#ifdef OPENSSL_FIPS -#define FIPS_RSA_SIZE_T int -#endif - #ifdef __cplusplus extern "C" { #endif @@ -136,7 +117,8 @@ struct rsa_meth_st unsigned char *sigret, unsigned int *siglen, const RSA *rsa); int (*rsa_verify)(int dtype, const unsigned char *m, unsigned int m_length, - unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); + const unsigned char *sigbuf, unsigned int siglen, + const RSA *rsa); /* If this callback is NULL, the builtin software RSA key-gen will be used. This * is for behavioural compatibility whilst the code gets rewired, but one day * it would be nice to assume there are no such things as "builtin software" @@ -182,8 +164,6 @@ struct rsa_st # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif -#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 - #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif @@ -238,11 +218,37 @@ struct rsa_st #endif +#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) + #define RSA_PKCS1_PADDING 1 #define RSA_SSLV23_PADDING 2 #define RSA_NO_PADDING 3 #define RSA_PKCS1_OAEP_PADDING 4 #define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +#define RSA_PKCS1_PSS_PADDING 6 #define RSA_PKCS1_PADDING_SIZE 11 @@ -261,11 +267,6 @@ RSA * RSA_generate_key(int bits, unsigned long e,void /* New version */ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); -int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, - const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, - const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, - const BIGNUM *e, BN_GENCB *cb); -int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb); int RSA_check_key(const RSA *); /* next 4 return -1 on error */ @@ -283,11 +284,6 @@ int RSA_up_ref(RSA *r); int RSA_flags(const RSA *r); -#ifdef OPENSSL_FIPS -RSA *FIPS_rsa_new(void); -void FIPS_rsa_free(RSA *r); -#endif - void RSA_set_default_method(const RSA_METHOD *meth); const RSA_METHOD *RSA_get_default_method(void); const RSA_METHOD *RSA_get_method(const RSA *rsa); @@ -333,7 +329,7 @@ RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int RSA_sign(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, RSA *rsa); int RSA_verify(int type, const unsigned char *m, unsigned int m_length, - unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); /* The following 2 function sign and verify a ASN1_OCTET_STRING * object inside PKCS#1 padded RSA encryption */ @@ -401,9 +397,15 @@ void ERR_load_RSA_strings(void); /* Error codes for the RSA functions. */ /* Function codes. */ -#define RSA_F_FIPS_RSA_SIGN 140 -#define RSA_F_FIPS_RSA_VERIFY 141 +#define RSA_F_CHECK_PADDING_MD 140 +#define RSA_F_DO_RSA_PRINT 146 +#define RSA_F_INT_RSA_VERIFY 145 #define RSA_F_MEMORY_LOCK 100 +#define RSA_F_OLD_RSA_PRIV_DECODE 147 +#define RSA_F_PKEY_RSA_CTRL 143 +#define RSA_F_PKEY_RSA_CTRL_STR 144 +#define RSA_F_PKEY_RSA_SIGN 142 +#define RSA_F_PKEY_RSA_VERIFYRECOVER 141 #define RSA_F_RSA_BUILTIN_KEYGEN 129 #define RSA_F_RSA_CHECK_KEY 123 #define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 @@ -434,11 +436,10 @@ void ERR_load_RSA_strings(void); #define RSA_F_RSA_PADDING_CHECK_X931 128 #define RSA_F_RSA_PRINT 115 #define RSA_F_RSA_PRINT_FP 116 -#define RSA_F_RSA_PRIVATE_ENCRYPT 137 -#define RSA_F_RSA_PUBLIC_DECRYPT 138 +#define RSA_F_RSA_PRIV_DECODE 137 +#define RSA_F_RSA_PRIV_ENCODE 138 +#define RSA_F_RSA_PUB_DECODE 139 #define RSA_F_RSA_SETUP_BLINDING 136 -#define RSA_F_RSA_SET_DEFAULT_METHOD 139 -#define RSA_F_RSA_SET_METHOD 142 #define RSA_F_RSA_SIGN 117 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 #define RSA_F_RSA_VERIFY 119 @@ -464,20 +465,25 @@ void ERR_load_RSA_strings(void); #define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 #define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 #define RSA_R_FIRST_OCTET_INVALID 133 +#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +#define RSA_R_INVALID_DIGEST_LENGTH 143 #define RSA_R_INVALID_HEADER 137 +#define RSA_R_INVALID_KEYBITS 145 #define RSA_R_INVALID_MESSAGE_LENGTH 131 #define RSA_R_INVALID_PADDING 138 +#define RSA_R_INVALID_PADDING_MODE 141 +#define RSA_R_INVALID_PSS_SALTLEN 146 #define RSA_R_INVALID_TRAILER 139 +#define RSA_R_INVALID_X931_DIGEST 142 #define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 #define RSA_R_KEY_SIZE_TOO_SMALL 120 #define RSA_R_LAST_OCTET_INVALID 134 #define RSA_R_MODULUS_TOO_LARGE 105 -#define RSA_R_NON_FIPS_METHOD 141 #define RSA_R_NO_PUBLIC_EXPONENT 140 #define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 #define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 #define RSA_R_OAEP_DECODING_ERROR 121 -#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 142 +#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 #define RSA_R_PADDING_CHECK_FAILED 114 #define RSA_R_P_NOT_PRIME 128 #define RSA_R_Q_NOT_PRIME 129 @@ -488,6 +494,7 @@ void ERR_load_RSA_strings(void); #define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 #define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 #define RSA_R_UNKNOWN_PADDING_TYPE 118 +#define RSA_R_VALUE_MISSING 147 #define RSA_R_WRONG_SIGNATURE_LENGTH 119 #ifdef __cplusplus diff --git a/crypto/openssl/crypto/rsa/rsa_ameth.c b/crypto/openssl/crypto/rsa/rsa_ameth.c new file mode 100644 index 0000000000..8c3209885e --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_ameth.c @@ -0,0 +1,349 @@ +/* crypto/rsa/rsa_ameth.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_CMS +#include +#endif +#include "asn1_locl.h" + +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) + { + unsigned char *penc = NULL; + int penclen; + penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); + if (penclen <= 0) + return 0; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), + V_ASN1_NULL, NULL, penc, penclen)) + return 1; + + OPENSSL_free(penc); + return 0; + } + +static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) + { + const unsigned char *p; + int pklen; + RSA *rsa = NULL; + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) + return 0; + if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) + { + RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA (pkey, rsa); + return 1; + } + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 + || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0) + return 0; + return 1; + } + +static int old_rsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + RSA *rsa; + if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen))) + { + RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, 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) + { + return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); + } + +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) + { + unsigned char *rk = NULL; + int rklen; + rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); + + if (rklen <= 0) + { + RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, + V_ASN1_NULL, NULL, rk, rklen)) + { + RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; + } + +static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) + { + const unsigned char *p; + int pklen; + if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) + return 0; + return old_rsa_priv_decode(pkey, &p, pklen); + } + +static int int_rsa_size(const EVP_PKEY *pkey) + { + return RSA_size(pkey->pkey.rsa); + } + +static int rsa_bits(const EVP_PKEY *pkey) + { + return BN_num_bits(pkey->pkey.rsa->n); + } + +static void int_rsa_free(EVP_PKEY *pkey) + { + RSA_free(pkey->pkey.rsa); + } + + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) + { + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; + } + +static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) + { + char *str; + const char *s; + unsigned char *m=NULL; + int ret=0, mod_len = 0; + size_t buf_len=0; + + update_buflen(x->n, &buf_len); + update_buflen(x->e, &buf_len); + + if (priv) + { + update_buflen(x->d, &buf_len); + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->dmp1, &buf_len); + update_buflen(x->dmq1, &buf_len); + update_buflen(x->iqmp, &buf_len); + } + + m=(unsigned char *)OPENSSL_malloc(buf_len+10); + if (m == NULL) + { + RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + + if(!BIO_indent(bp,off,128)) + goto err; + + if (priv && x->d) + { + if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len) + <= 0) goto err; + str = "modulus:"; + s = "publicExponent:"; + } + else + { + if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len) + <= 0) goto err; + str = "Modulus:"; + s= "Exponent:"; + } + if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err; + if (!ASN1_bn_print(bp,s,x->e,m,off)) + goto err; + if (priv) + { + if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off)) + goto err; + if (!ASN1_bn_print(bp,"prime1:",x->p,m,off)) + goto err; + if (!ASN1_bn_print(bp,"prime2:",x->q,m,off)) + goto err; + if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off)) + goto err; + if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off)) + goto err; + if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off)) + goto err; + } + ret=1; +err: + if (m != NULL) OPENSSL_free(m); + return(ret); + } + +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); + } + + +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); + } + + +static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) + { + X509_ALGOR *alg = NULL; + switch (op) + { + + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg); + break; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 0) + CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg); + break; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 1; + + default: + return -2; + + } + + if (alg) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, 0); + + return 1; + + } + + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = + { + { + EVP_PKEY_RSA, + EVP_PKEY_RSA, + ASN1_PKEY_SIGPARAM_NULL, + + "RSA", + "OpenSSL RSA method", + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + rsa_pub_print, + + rsa_priv_decode, + rsa_priv_encode, + rsa_priv_print, + + int_rsa_size, + rsa_bits, + + 0,0,0,0,0,0, + + int_rsa_free, + rsa_pkey_ctrl, + old_rsa_priv_decode, + old_rsa_priv_encode + }, + + { + EVP_PKEY_RSA2, + EVP_PKEY_RSA, + ASN1_PKEY_ALIAS + } + }; diff --git a/crypto/openssl/crypto/rsa/rsa_asn1.c b/crypto/openssl/crypto/rsa/rsa_asn1.c index 6e8a803e81..4efca8cdc8 100644 --- a/crypto/openssl/crypto/rsa/rsa_asn1.c +++ b/crypto/openssl/crypto/rsa/rsa_asn1.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-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 @@ -62,19 +62,9 @@ #include #include -static ASN1_METHOD method={ - (I2D_OF(void)) i2d_RSAPrivateKey, - (D2I_OF(void)) d2i_RSAPrivateKey, - (void *(*)(void)) RSA_new, - (void (*)(void *)) RSA_free}; - -ASN1_METHOD *RSAPrivateKey_asn1_meth(void) - { - return(&method); - } - /* Override the default free and new methods */ -static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +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(); diff --git a/crypto/openssl/crypto/rsa/rsa_eay.c b/crypto/openssl/crypto/rsa/rsa_eay.c index 0ac6418449..c5eaeeae6b 100644 --- a/crypto/openssl/crypto/rsa/rsa_eay.c +++ b/crypto/openssl/crypto/rsa/rsa_eay.c @@ -115,7 +115,7 @@ #include #include -#if !defined(RSA_NULL) && !defined(OPENSSL_FIPS) +#ifndef RSA_NULL static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,int padding); @@ -256,6 +256,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; int got_write_lock = 0; + CRYPTO_THREADID cur; CRYPTO_r_lock(CRYPTO_LOCK_RSA); @@ -273,7 +274,8 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) if (ret == NULL) goto err; - if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { /* rsa->blinding is ours! */ diff --git a/crypto/openssl/crypto/rsa/rsa_eng.c b/crypto/openssl/crypto/rsa/rsa_eng.c deleted file mode 100644 index 2f21ddbe74..0000000000 --- a/crypto/openssl/crypto/rsa/rsa_eng.c +++ /dev/null @@ -1,357 +0,0 @@ -/* crypto/rsa/rsa_lib.c */ -/* 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 -#include -#include "cryptlib.h" -#include -#include -#include -#include -#ifndef OPENSSL_NO_ENGINE -#include -#endif - -const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; - -static const RSA_METHOD *default_RSA_meth=NULL; - -RSA *RSA_new(void) - { - RSA *r=RSA_new_method(NULL); - - return r; - } - -void RSA_set_default_method(const RSA_METHOD *meth) - { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) - { - RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD); - return; - } -#endif - default_RSA_meth = meth; - } - -const RSA_METHOD *RSA_get_default_method(void) - { - if (default_RSA_meth == NULL) - { -#ifdef RSA_NULL - default_RSA_meth=RSA_null_method(); -#else -#if 0 /* was: #ifdef RSAref */ - default_RSA_meth=RSA_PKCS1_RSAref(); -#else - default_RSA_meth=RSA_PKCS1_SSLeay(); -#endif -#endif - } - - return default_RSA_meth; - } - -const RSA_METHOD *RSA_get_method(const RSA *rsa) - { - return rsa->meth; - } - -int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) - { - /* NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. */ - const RSA_METHOD *mtmp; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) - { - RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD); - return 0; - } -#endif - mtmp = rsa->meth; - if (mtmp->finish) mtmp->finish(rsa); -#ifndef OPENSSL_NO_ENGINE - if (rsa->engine) - { - ENGINE_finish(rsa->engine); - rsa->engine = NULL; - } -#endif - rsa->meth = meth; - if (meth->init) meth->init(rsa); - return 1; - } - -RSA *RSA_new_method(ENGINE *engine) - { - RSA *ret; - - ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); - if (ret == NULL) - { - RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->meth = RSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - if (engine) - { - if (!ENGINE_init(engine)) - { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); - OPENSSL_free(ret); - return NULL; - } - ret->engine = engine; - } - else - ret->engine = ENGINE_get_default_RSA(); - if(ret->engine) - { - ret->meth = ENGINE_get_RSA(ret->engine); - if(!ret->meth) - { - RSAerr(RSA_F_RSA_NEW_METHOD, - ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) - { - RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD); -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - OPENSSL_free(ret); - return NULL; - } -#endif - - ret->pad=0; - ret->version=0; - ret->n=NULL; - ret->e=NULL; - ret->d=NULL; - ret->p=NULL; - ret->q=NULL; - ret->dmp1=NULL; - ret->dmq1=NULL; - ret->iqmp=NULL; - ret->references=1; - ret->_method_mod_n=NULL; - ret->_method_mod_p=NULL; - ret->_method_mod_q=NULL; - ret->blinding=NULL; - ret->mt_blinding=NULL; - ret->bignum_data=NULL; - ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) - { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - OPENSSL_free(ret); - return(NULL); - } - - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) - { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); - OPENSSL_free(ret); - ret=NULL; - } - return(ret); - } - -void RSA_free(RSA *r) - { - int i; - - if (r == NULL) return; - - i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA); -#ifdef REF_PRINT - REF_PRINT("RSA",r); -#endif - if (i > 0) return; -#ifdef REF_CHECK - if (i < 0) - { - fprintf(stderr,"RSA_free, bad reference count\n"); - abort(); - } -#endif - - if (r->meth->finish) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); - - if (r->n != NULL) BN_clear_free(r->n); - if (r->e != NULL) BN_clear_free(r->e); - if (r->d != NULL) BN_clear_free(r->d); - if (r->p != NULL) BN_clear_free(r->p); - if (r->q != NULL) BN_clear_free(r->q); - if (r->dmp1 != NULL) BN_clear_free(r->dmp1); - if (r->dmq1 != NULL) BN_clear_free(r->dmq1); - if (r->iqmp != NULL) BN_clear_free(r->iqmp); - if (r->blinding != NULL) BN_BLINDING_free(r->blinding); - if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); - if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); - OPENSSL_free(r); - } - -int RSA_up_ref(RSA *r) - { - int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); -#ifdef REF_PRINT - REF_PRINT("RSA",r); -#endif -#ifdef REF_CHECK - if (i < 2) - { - fprintf(stderr, "RSA_up_ref, bad reference count\n"); - abort(); - } -#endif - return ((i > 1) ? 1 : 0); - } - -int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) - { - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, - new_func, dup_func, free_func); - } - -int RSA_set_ex_data(RSA *r, int idx, void *arg) - { - return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); - } - -void *RSA_get_ex_data(const RSA *r, int idx) - { - return(CRYPTO_get_ex_data(&r->ex_data,idx)); - } - -int RSA_flags(const RSA *r) - { - return((r == NULL)?0:r->meth->flags); - } - -int RSA_memory_lock(RSA *r) - { - int i,j,k,off; - char *p; - BIGNUM *bn,**t[6],*b; - BN_ULONG *ul; - - if (r->d == NULL) return(1); - t[0]= &r->d; - t[1]= &r->p; - t[2]= &r->q; - t[3]= &r->dmp1; - t[4]= &r->dmq1; - t[5]= &r->iqmp; - k=sizeof(BIGNUM)*6; - off=k/sizeof(BN_ULONG)+1; - j=1; - for (i=0; i<6; i++) - j+= (*t[i])->top; - if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) - { - RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); - return(0); - } - bn=(BIGNUM *)p; - ul=(BN_ULONG *)&(p[off]); - for (i=0; i<6; i++) - { - b= *(t[i]); - *(t[i])= &(bn[i]); - memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM)); - bn[i].flags=BN_FLG_STATIC_DATA; - bn[i].d=ul; - memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top); - ul+=b->top; - BN_clear_free(b); - } - - /* I should fix this so it can still be done */ - r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC); - - r->bignum_data=p; - return(1); - } diff --git a/crypto/openssl/crypto/rsa/rsa_err.c b/crypto/openssl/crypto/rsa/rsa_err.c index 501f5ea389..cf9f1106b0 100644 --- a/crypto/openssl/crypto/rsa/rsa_err.c +++ b/crypto/openssl/crypto/rsa/rsa_err.c @@ -1,6 +1,6 @@ /* crypto/rsa/rsa_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 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 @@ -70,9 +70,15 @@ static ERR_STRING_DATA RSA_str_functs[]= { -{ERR_FUNC(RSA_F_FIPS_RSA_SIGN), "FIPS_RSA_SIGN"}, -{ERR_FUNC(RSA_F_FIPS_RSA_VERIFY), "FIPS_RSA_VERIFY"}, +{ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"}, +{ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"}, +{ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"}, {ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, +{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"}, +{ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"}, +{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"}, +{ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"}, +{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"}, {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"}, {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, @@ -103,11 +109,10 @@ static ERR_STRING_DATA RSA_str_functs[]= {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"}, {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"}, {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, -{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, -{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, +{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"}, +{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"}, +{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, -{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"}, -{ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"}, {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"}, {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, @@ -136,20 +141,25 @@ static ERR_STRING_DATA RSA_str_reasons[]= {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"}, {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"}, {ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"}, +{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"}, +{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"}, {ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"}, +{ERR_REASON(RSA_R_INVALID_KEYBITS) ,"invalid keybits"}, {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"}, {ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"}, +{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"}, +{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN) ,"invalid pss saltlen"}, {ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"}, +{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"}, {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"}, {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"}, {ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, -{ERR_REASON(RSA_R_NON_FIPS_METHOD) ,"non fips method"}, {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"}, {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"}, {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"}, {ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"}, -{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, +{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"}, {ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"}, {ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"}, {ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"}, @@ -160,6 +170,7 @@ static ERR_STRING_DATA RSA_str_reasons[]= {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"}, {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"}, {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"}, +{ERR_REASON(RSA_R_VALUE_MISSING) ,"value missing"}, {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/rsa/rsa_gen.c b/crypto/openssl/crypto/rsa/rsa_gen.c index 41278f83c6..767f7ab682 100644 --- a/crypto/openssl/crypto/rsa/rsa_gen.c +++ b/crypto/openssl/crypto/rsa/rsa_gen.c @@ -68,8 +68,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); /* NB: this wrapper would normally be placed in rsa_lib.c and the static @@ -219,4 +217,3 @@ err: return ok; } -#endif diff --git a/crypto/openssl/crypto/rsa/rsa_lib.c b/crypto/openssl/crypto/rsa/rsa_lib.c index 5714841f4c..de45088d76 100644 --- a/crypto/openssl/crypto/rsa/rsa_lib.c +++ b/crypto/openssl/crypto/rsa/rsa_lib.c @@ -67,6 +67,224 @@ #include #endif +const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; + +static const RSA_METHOD *default_RSA_meth=NULL; + +RSA *RSA_new(void) + { + RSA *r=RSA_new_method(NULL); + + return r; + } + +void RSA_set_default_method(const RSA_METHOD *meth) + { + default_RSA_meth = meth; + } + +const RSA_METHOD *RSA_get_default_method(void) + { + if (default_RSA_meth == NULL) + { +#ifdef RSA_NULL + default_RSA_meth=RSA_null_method(); +#else +#if 0 /* was: #ifdef RSAref */ + default_RSA_meth=RSA_PKCS1_RSAref(); +#else + default_RSA_meth=RSA_PKCS1_SSLeay(); +#endif +#endif + } + + return default_RSA_meth; + } + +const RSA_METHOD *RSA_get_method(const RSA *rsa) + { + return rsa->meth; + } + +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) + { + /* NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. */ + const RSA_METHOD *mtmp; + mtmp = rsa->meth; + if (mtmp->finish) mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + if (rsa->engine) + { + ENGINE_finish(rsa->engine); + rsa->engine = NULL; + } +#endif + rsa->meth = meth; + if (meth->init) meth->init(rsa); + return 1; + } + +RSA *RSA_new_method(ENGINE *engine) + { + RSA *ret; + + ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); + if (ret == NULL) + { + RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) + { + if (!ENGINE_init(engine)) + { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } + else + ret->engine = ENGINE_get_default_RSA(); + if(ret->engine) + { + ret->meth = ENGINE_get_RSA(ret->engine); + if(!ret->meth) + { + RSAerr(RSA_F_RSA_NEW_METHOD, + ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad=0; + ret->version=0; + ret->n=NULL; + ret->e=NULL; + ret->d=NULL; + ret->p=NULL; + ret->q=NULL; + ret->dmp1=NULL; + ret->dmq1=NULL; + ret->iqmp=NULL; + ret->references=1; + ret->_method_mod_n=NULL; + ret->_method_mod_p=NULL; + ret->_method_mod_q=NULL; + ret->blinding=NULL; + ret->mt_blinding=NULL; + ret->bignum_data=NULL; + ret->flags=ret->meth->flags; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) + { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return(NULL); + } + + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) + { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret=NULL; + } + return(ret); + } + +void RSA_free(RSA *r) + { + int i; + + if (r == NULL) return; + + i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA",r); +#endif + if (i > 0) return; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"RSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); + + if (r->n != NULL) BN_clear_free(r->n); + if (r->e != NULL) BN_clear_free(r->e); + if (r->d != NULL) BN_clear_free(r->d); + if (r->p != NULL) BN_clear_free(r->p); + if (r->q != NULL) BN_clear_free(r->q); + if (r->dmp1 != NULL) BN_clear_free(r->dmp1); + if (r->dmq1 != NULL) BN_clear_free(r->dmq1); + if (r->iqmp != NULL) BN_clear_free(r->iqmp); + if (r->blinding != NULL) BN_BLINDING_free(r->blinding); + if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); + if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); + OPENSSL_free(r); + } + +int RSA_up_ref(RSA *r) + { + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA",r); +#endif +#ifdef REF_CHECK + if (i < 2) + { + fprintf(stderr, "RSA_up_ref, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); + } + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) + { + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, + new_func, dup_func, free_func); + } + +int RSA_set_ex_data(RSA *r, int idx, void *arg) + { + return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); + } + +void *RSA_get_ex_data(const RSA *r, int idx) + { + return(CRYPTO_get_ex_data(&r->ex_data,idx)); + } + +int RSA_size(const RSA *r) + { + return(BN_num_bytes(r->n)); + } + int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -76,13 +294,6 @@ int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); } @@ -95,19 +306,12 @@ int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); } -int RSA_size(const RSA *r) +int RSA_flags(const RSA *r) { - return(BN_num_bytes(r->n)); + return((r == NULL)?0:r->meth->flags); } void RSA_blinding_off(RSA *rsa) @@ -222,7 +426,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } - BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id()); + CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); if (in_ctx == NULL) @@ -232,3 +436,48 @@ err: return ret; } + +int RSA_memory_lock(RSA *r) + { + int i,j,k,off; + char *p; + BIGNUM *bn,**t[6],*b; + BN_ULONG *ul; + + if (r->d == NULL) return(1); + t[0]= &r->d; + t[1]= &r->p; + t[2]= &r->q; + t[3]= &r->dmp1; + t[4]= &r->dmq1; + t[5]= &r->iqmp; + k=sizeof(BIGNUM)*6; + off=k/sizeof(BN_ULONG)+1; + j=1; + for (i=0; i<6; i++) + j+= (*t[i])->top; + if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) + { + RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); + return(0); + } + bn=(BIGNUM *)p; + ul=(BN_ULONG *)&(p[off]); + for (i=0; i<6; i++) + { + b= *(t[i]); + *(t[i])= &(bn[i]); + memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM)); + bn[i].flags=BN_FLG_STATIC_DATA; + bn[i].d=ul; + memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top); + ul+=b->top; + BN_clear_free(b); + } + + /* I should fix this so it can still be done */ + r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC); + + r->bignum_data=p; + return(1); + } diff --git a/crypto/openssl/crypto/rsa/rsa_locl.h b/crypto/openssl/crypto/rsa/rsa_locl.h new file mode 100644 index 0000000000..f5d2d56628 --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_locl.h @@ -0,0 +1,4 @@ +extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, + RSA *rsa); diff --git a/crypto/openssl/crypto/rsa/rsa_oaep.c b/crypto/openssl/crypto/rsa/rsa_oaep.c index 546ae5fcb2..e238d10e5c 100644 --- a/crypto/openssl/crypto/rsa/rsa_oaep.c +++ b/crypto/openssl/crypto/rsa/rsa_oaep.c @@ -28,7 +28,7 @@ #include #include -int MGF1(unsigned char *mask, long len, +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen); int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, @@ -76,11 +76,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, return 0; } - MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); + if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0) + return 0; for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) db[i] ^= dbmask[i]; - MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); + if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0) + return 0; for (i = 0; i < SHA_DIGEST_LENGTH; i++) seed[i] ^= seedmask[i]; @@ -133,11 +135,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, maskeddb = padded_from + SHA_DIGEST_LENGTH; - MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); + if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen)) + return -1; for (i = 0; i < SHA_DIGEST_LENGTH; i++) seed[i] ^= padded_from[i]; - MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); + if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH)) + return -1; for (i = 0; i < dblen; i++) db[i] ^= maskeddb[i]; @@ -187,7 +191,9 @@ int PKCS1_MGF1(unsigned char *mask, long len, int mdlen; EVP_MD_CTX_init(&c); - mdlen = M_EVP_MD_size(dgst); + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; for (i = 0; outlen < len; i++) { cnt[0] = (unsigned char)((i >> 24) & 255); @@ -213,7 +219,8 @@ int PKCS1_MGF1(unsigned char *mask, long len, return 0; } -int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen) +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen) { return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); } diff --git a/crypto/openssl/crypto/rsa/rsa_pmeth.c b/crypto/openssl/crypto/rsa/rsa_pmeth.c new file mode 100644 index 0000000000..c6892ecd09 --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_pmeth.c @@ -0,0 +1,587 @@ +/* crypto/rsa/rsa_pmeth.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "evp_locl.h" +#include "rsa_locl.h" + +/* RSA pkey context structure */ + +typedef struct + { + /* Key gen parameters */ + int nbits; + BIGNUM *pub_exp; + /* Keygen callback info */ + int gentmp[2]; + /* RSA padding mode */ + int pad_mode; + /* message digest */ + const EVP_MD *md; + /* PSS/OAEP salt length */ + int saltlen; + /* Temp buffer */ + unsigned char *tbuf; + } RSA_PKEY_CTX; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) + { + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) + return 0; + rctx->nbits = 1024; + rctx->pub_exp = NULL; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->md = NULL; + rctx->tbuf = NULL; + + rctx->saltlen = -2; + + ctx->data = rctx; + ctx->keygen_info = rctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; + } + +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + RSA_PKEY_CTX *dctx, *sctx; + if (!pkey_rsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp) + { + dctx->pub_exp = BN_dup(sctx->pub_exp); + if (!dctx->pub_exp) + return 0; + } + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + return 1; + } + +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) + { + if (ctx->tbuf) + return 1; + ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); + if (!ctx->tbuf) + return 0; + return 1; + } + +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) + { + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx) + { + if (rctx->pub_exp) + BN_free(rctx->pub_exp); + if (rctx->tbuf) + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx); + } + } + +static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + + if (rctx->md) + { + if (tbslen != (size_t)EVP_MD_size(rctx->md)) + { + RSAerr(RSA_F_PKEY_RSA_SIGN, + RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } + if (rctx->pad_mode == RSA_X931_PADDING) + { + if (!setup_tbuf(rctx, ctx)) + return -1; + memcpy(rctx->tbuf, tbs, tbslen); + rctx->tbuf[tbslen] = + RSA_X931_hash_id(EVP_MD_type(rctx->md)); + ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, + sig, rsa, RSA_X931_PADDING); + } + else if (rctx->pad_mode == RSA_PKCS1_PADDING) + { + unsigned int sltmp; + ret = RSA_sign(EVP_MD_type(rctx->md), + tbs, tbslen, sig, &sltmp, rsa); + if (ret <= 0) + return ret; + ret = sltmp; + } + else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) + { + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs, + rctx->md, rctx->saltlen)) + return -1; + ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, + sig, rsa, RSA_NO_PADDING); + } + else + return -1; + } + else + ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *siglen = ret; + return 1; + } + + +static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx->md) + { + if (rctx->pad_mode == RSA_X931_PADDING) + { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, + rctx->tbuf, ctx->pkey->pkey.rsa, + RSA_X931_PADDING); + if (ret < 1) + return 0; + ret--; + if (rctx->tbuf[ret] != + RSA_X931_hash_id(EVP_MD_type(rctx->md))) + { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_ALGORITHM_MISMATCH); + return 0; + } + if (ret != EVP_MD_size(rctx->md)) + { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_INVALID_DIGEST_LENGTH); + return 0; + } + if (rout) + memcpy(rout, rctx->tbuf, ret); + } + else if (rctx->pad_mode == RSA_PKCS1_PADDING) + { + size_t sltmp; + ret = int_rsa_verify(EVP_MD_type(rctx->md), + NULL, 0, rout, &sltmp, + sig, siglen, ctx->pkey->pkey.rsa); + if (ret <= 0) + return 0; + ret = sltmp; + } + else + return -1; + } + else + ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *routlen = ret; + return 1; + } + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) + { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + size_t rslen; + if (rctx->md) + { + if (rctx->pad_mode == RSA_PKCS1_PADDING) + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + sig, siglen, rsa); + if (rctx->pad_mode == RSA_X931_PADDING) + { + if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, + sig, siglen) <= 0) + return 0; + } + else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) + { + int ret; + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, RSA_NO_PADDING); + if (ret <= 0) + return 0; + ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md, + rctx->tbuf, rctx->saltlen); + if (ret <= 0) + return 0; + return 1; + } + else + return -1; + } + else + { + if (!setup_tbuf(rctx, ctx)) + return -1; + rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, rctx->pad_mode); + if (rslen == 0) + return 0; + } + + if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) + return 0; + + return 1; + + } + + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; + } + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; + } + +static int check_padding_md(const EVP_MD *md, int padding) + { + if (!md) + return 1; + + if (padding == RSA_NO_PADDING) + { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) + { + if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) + { + RSAerr(RSA_F_CHECK_PADDING_MD, + RSA_R_INVALID_X931_DIGEST); + return 0; + } + return 1; + } + + return 1; + } + + +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + RSA_PKEY_CTX *rctx = ctx->data; + switch (type) + { + case EVP_PKEY_CTRL_RSA_PADDING: + if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) + { + if (!check_padding_md(rctx->md, p1)) + return 0; + if (p1 == RSA_PKCS1_PSS_PADDING) + { + if (!(ctx->operation & + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + if (p1 == RSA_PKCS1_OAEP_PADDING) + { + if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + } + bad_pad: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return -2; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + if (p1 < -2) + return -2; + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) + { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + rctx->saltlen = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) + { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); + return -2; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (!p2) + return -2; + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) + return 0; + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: +#endif + return 1; + case EVP_PKEY_CTRL_PEER_KEY: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + + default: + return -2; + + } + } + +static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!value) + { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); + return 0; + } + if (!strcmp(type, "rsa_padding_mode")) + { + int pm; + if (!strcmp(value, "pkcs1")) + pm = RSA_PKCS1_PADDING; + else if (!strcmp(value, "sslv23")) + pm = RSA_SSLV23_PADDING; + else if (!strcmp(value, "none")) + pm = RSA_NO_PADDING; + else if (!strcmp(value, "oeap")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "x931")) + pm = RSA_X931_PADDING; + else if (!strcmp(value, "pss")) + pm = RSA_PKCS1_PSS_PADDING; + else + { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, + RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (!strcmp(type, "rsa_pss_saltlen")) + { + int saltlen; + saltlen = atoi(value); + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); + } + + if (!strcmp(type, "rsa_keygen_bits")) + { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); + } + + if (!strcmp(type, "rsa_keygen_pubexp")) + { + int ret; + BIGNUM *pubexp = NULL; + if (!BN_asc2bn(&pubexp, value)) + return 0; + ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); + if (ret <= 0) + BN_free(pubexp); + return ret; + } + + return -2; + } + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (!rctx->pub_exp) + { + rctx->pub_exp = BN_new(); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) + return 0; + } + rsa = RSA_new(); + if (!rsa) + return 0; + if (ctx->pkey_gencb) + { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } + else + pcb = NULL; + ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); + if (ret > 0) + EVP_PKEY_assign_RSA(pkey, rsa); + else + RSA_free(rsa); + return ret; + } + +const EVP_PKEY_METHOD rsa_pkey_meth = + { + EVP_PKEY_RSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + + 0,0, + + 0, + pkey_rsa_keygen, + + 0, + pkey_rsa_sign, + + 0, + pkey_rsa_verify, + + 0, + pkey_rsa_verifyrecover, + + + 0,0,0,0, + + 0, + pkey_rsa_encrypt, + + 0, + pkey_rsa_decrypt, + + 0,0, + + pkey_rsa_ctrl, + pkey_rsa_ctrl_str + + + }; diff --git a/crypto/openssl/crypto/pem/pem_x509.c b/crypto/openssl/crypto/rsa/rsa_prn.c similarity index 80% copy from crypto/openssl/crypto/pem/pem_x509.c copy to crypto/openssl/crypto/rsa/rsa_prn.c index 3f709f13e6..224db0fae5 100644 --- a/crypto/openssl/crypto/pem/pem_x509.c +++ b/crypto/openssl/crypto/rsa/rsa_prn.c @@ -1,9 +1,9 @@ -/* pem_x509.c */ +/* crypto/rsa/rsa_prn.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. + * project 2006. */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -57,13 +57,37 @@ */ #include -#undef SSLEAY_MACROS #include "cryptlib.h" -#include +#include #include -#include -#include -#include -IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) +#ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=RSA_print(b,x,off); + BIO_free(b); + return(ret); + } +#endif + +int RSA_print(BIO *bp, const RSA *x, int off) + { + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; + } diff --git a/crypto/openssl/crypto/rsa/rsa_pss.c b/crypto/openssl/crypto/rsa/rsa_pss.c index 2bda491a09..ac211e2ffe 100644 --- a/crypto/openssl/crypto/rsa/rsa_pss.c +++ b/crypto/openssl/crypto/rsa/rsa_pss.c @@ -81,7 +81,9 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, EVP_MD_CTX ctx; unsigned char H_[EVP_MAX_MD_SIZE]; - hLen = M_EVP_MD_size(Hash); + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -126,7 +128,8 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); goto err; } - PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash); + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0) + goto err; for (i = 0; i < maskedDBLen; i++) DB[i] ^= EM[i]; if (MSBits) @@ -176,7 +179,9 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; - hLen = M_EVP_MD_size(Hash); + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -232,7 +237,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ - PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash)) + goto err; p = EM; diff --git a/crypto/openssl/crypto/rsa/rsa_sign.c b/crypto/openssl/crypto/rsa/rsa_sign.c index 743dfd7650..0be4ec7fb0 100644 --- a/crypto/openssl/crypto/rsa/rsa_sign.c +++ b/crypto/openssl/crypto/rsa/rsa_sign.c @@ -62,6 +62,7 @@ #include #include #include +#include "rsa_locl.h" /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 @@ -90,14 +91,6 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i = SSL_SIG_LENGTH; s = m; } else { - /* NB: in FIPS mode block anything that isn't a TLS signature */ -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif sig.algor= &algor; sig.algor->algorithm=OBJ_nid2obj(type); if (sig.algor->algorithm == NULL) @@ -137,12 +130,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i2d_X509_SIG(&sig,&p); s=tmps; } -#ifdef OPENSSL_FIPS - /* Bypass algorithm blocking: this is allowed if we get this far */ - i=rsa->meth->rsa_priv_enc(i,s,sigret,rsa,RSA_PKCS1_PADDING); -#else i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING); -#endif if (i <= 0) ret=0; else @@ -155,8 +143,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, return(ret); } -int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, - unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, + RSA *rsa) { int i,ret=0,sigtype; unsigned char *s; @@ -164,49 +155,38 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } - if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + if((dtype == NID_md5_sha1) && rm) { - return rsa->meth->rsa_verify(dtype, m, m_len, - sigbuf, siglen, rsa); + i = RSA_public_decrypt((int)siglen, + sigbuf,rm,rsa,RSA_PKCS1_PADDING); + if (i <= 0) + return 0; + *prm_len = i; + return 1; } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { - RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); + RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } - if(dtype == NID_md5_sha1) - { - if (m_len != SSL_SIG_LENGTH) - { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); + if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; - } - } - /* NB: in FIPS mode block anything that isn't a TLS signature */ -#ifdef OPENSSL_FIPS - else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } - /* Bypass algorithm blocking: this is allowed */ - i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); -#else + } i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); -#endif if (i <= 0) goto err; /* Special case: SSL signature */ if(dtype == NID_md5_sha1) { if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p=s; @@ -217,7 +197,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, /* Excess data can be used to create forgeries */ if(p != s+i) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } @@ -226,7 +206,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, if(sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } @@ -252,15 +232,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, } else { - RSAerr(RSA_F_RSA_VERIFY, + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } } - if ( ((unsigned int)sig->digest->length != m_len) || + if (rm) + { + const EVP_MD *md; + md = EVP_get_digestbynid(dtype); + if (md && (EVP_MD_size(md) != sig->digest->length)) + RSAerr(RSA_F_INT_RSA_VERIFY, + RSA_R_INVALID_DIGEST_LENGTH); + else + { + memcpy(rm, sig->digest->data, + sig->digest->length); + *prm_len = sig->digest->length; + ret = 1; + } + } + else if (((unsigned int)sig->digest->length != m_len) || (memcmp(m,sig->digest->data,m_len) != 0)) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); } else ret=1; @@ -275,3 +270,16 @@ err: return(ret); } +int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, + RSA *rsa) + { + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + { + return rsa->meth->rsa_verify(dtype, m, m_len, + sigbuf, siglen, rsa); + } + + return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); + } diff --git a/crypto/openssl/crypto/rsa/rsa_x931g.c b/crypto/openssl/crypto/rsa/rsa_x931g.c deleted file mode 100644 index bf94f8be7a..0000000000 --- a/crypto/openssl/crypto/rsa/rsa_x931g.c +++ /dev/null @@ -1,255 +0,0 @@ -/* crypto/rsa/rsa_gen.c */ -/* 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 -#include -#include -#include -#include -#include - -#ifndef OPENSSL_FIPS - -/* X9.31 RSA key derivation and generation */ - -int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, - const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, - const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, - const BIGNUM *e, BN_GENCB *cb) - { - BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL; - BN_CTX *ctx=NULL,*ctx2=NULL; - - if (!rsa) - goto err; - - ctx = BN_CTX_new(); - if (!ctx) - goto err; - BN_CTX_start(ctx); - - r0 = BN_CTX_get(ctx); - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - r3 = BN_CTX_get(ctx); - - if (r3 == NULL) - goto err; - if (!rsa->e) - { - rsa->e = BN_dup(e); - if (!rsa->e) - goto err; - } - else - e = rsa->e; - - /* If not all parameters present only calculate what we can. - * This allows test programs to output selective parameters. - */ - - if (Xp && !rsa->p) - { - rsa->p = BN_new(); - if (!rsa->p) - goto err; - - if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, - Xp, Xp1, Xp2, e, ctx, cb)) - goto err; - } - - if (Xq && !rsa->q) - { - rsa->q = BN_new(); - if (!rsa->q) - goto err; - if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, - Xq, Xq1, Xq2, e, ctx, cb)) - goto err; - } - - if (!rsa->p || !rsa->q) - { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return 2; - } - - /* Since both primes are set we can now calculate all remaining - * components. - */ - - /* calculate n */ - rsa->n=BN_new(); - if (rsa->n == NULL) - goto err; - 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 */ - if (!BN_sub(r2,rsa->q,BN_value_one())) - goto err; /* q-1 */ - if (!BN_mul(r0,r1,r2,ctx)) - goto err; /* (p-1)(q-1) */ - - if (!BN_gcd(r3, r1, r2, ctx)) - goto err; - - if (!BN_div(r0, NULL, r0, r3, ctx)) - goto err; /* LCM((p-1)(q-1)) */ - - ctx2 = BN_CTX_new(); - if (!ctx2) - goto err; - - rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ - if (rsa->d == NULL) - goto err; - - /* calculate d mod (p-1) */ - rsa->dmp1=BN_new(); - if (rsa->dmp1 == NULL) - goto err; - if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) - goto err; - - /* calculate d mod (q-1) */ - rsa->dmq1=BN_new(); - if (rsa->dmq1 == NULL) - goto err; - if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) - goto err; - - /* calculate inverse of q mod p */ - rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); - - err: - if (ctx) - { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (ctx2) - BN_CTX_free(ctx2); - /* If this is set all calls successful */ - if (rsa && rsa->iqmp != NULL) - return 1; - - return 0; - - } - -int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb) - { - int ok = 0; - BIGNUM *Xp = NULL, *Xq = NULL; - BN_CTX *ctx = NULL; - - ctx = BN_CTX_new(); - if (!ctx) - goto error; - - BN_CTX_start(ctx); - Xp = BN_CTX_get(ctx); - Xq = BN_CTX_get(ctx); - if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) - goto error; - - rsa->p = BN_new(); - rsa->q = BN_new(); - if (!rsa->p || !rsa->q) - goto error; - - /* Generate two primes from Xp, Xq */ - - if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, - e, ctx, cb)) - goto error; - - if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, - e, ctx, cb)) - goto error; - - /* Since rsa->p and rsa->q are valid this call will just derive - * remaining RSA components. - */ - - if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) - goto error; - - ok = 1; - - error: - if (ctx) - { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - if (ok) - return 1; - - return 0; - - } - -#endif diff --git a/crypto/openssl/crypto/seed/seed.c b/crypto/openssl/crypto/seed/seed.c new file mode 100644 index 0000000000..2bc384a19f --- /dev/null +++ b/crypto/openssl/crypto/seed/seed.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). 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. Neither the name of author 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 AUTHOR AND CONTRIBUTORS ``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 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. + * + */ +#ifndef OPENSSL_NO_SEED + +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include +#include "seed_locl.h" + +static const seed_word SS[4][256] = { { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298 +}, { + 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0, + 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, + 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3, + 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43, + 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, + 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890, + 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3, + 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, + 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83, + 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430, + 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, + 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1, + 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1, + 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171, + 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951, + 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0, + 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, + 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41, + 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62, + 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, + 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303, + 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901, + 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, + 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343, + 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971, + 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, + 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642, + 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1, + 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, + 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, + 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783, + 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3 +}, { + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a +}, { + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437 +} }; + +/* key schedule constants - golden ratio */ +#define KC0 0x9e3779b9 +#define KC1 0x3c6ef373 +#define KC2 0x78dde6e6 +#define KC3 0xf1bbcdcc +#define KC4 0xe3779b99 +#define KC5 0xc6ef3733 +#define KC6 0x8dde6e67 +#define KC7 0x1bbcdccf +#define KC8 0x3779b99e +#define KC9 0x6ef3733c +#define KC10 0xdde6e678 +#define KC11 0xbbcdccf1 +#define KC12 0x779b99e3 +#define KC13 0xef3733c6 +#define KC14 0xde6e678d +#define KC15 0xbcdccf1b + +#if defined(OPENSSL_SMALL_FOOTPRINT) +static const seed_word KC[] = { + KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7, + KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15 }; +#endif + +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(rawkey , x1); + char2word(rawkey+4 , x2); + char2word(rawkey+8 , x3); + char2word(rawkey+12, x4); + + t0 = (x1 + x3 - KC0) & 0xffffffff; + t1 = (x2 - x4 + KC0) & 0xffffffff; KEYUPDATE_TEMP(t0, t1, &ks->data[0]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1); KEYUPDATE_TEMP(t0, t1, &ks->data[2]); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2); KEYUPDATE_TEMP(t0, t1, &ks->data[4]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3); KEYUPDATE_TEMP(t0, t1, &ks->data[6]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4); KEYUPDATE_TEMP(t0, t1, &ks->data[8]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5); KEYUPDATE_TEMP(t0, t1, &ks->data[10]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6); KEYUPDATE_TEMP(t0, t1, &ks->data[12]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7); KEYUPDATE_TEMP(t0, t1, &ks->data[14]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8); KEYUPDATE_TEMP(t0, t1, &ks->data[16]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9); KEYUPDATE_TEMP(t0, t1, &ks->data[18]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10); KEYUPDATE_TEMP(t0, t1, &ks->data[20]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11); KEYUPDATE_TEMP(t0, t1, &ks->data[22]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12); KEYUPDATE_TEMP(t0, t1, &ks->data[24]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13); KEYUPDATE_TEMP(t0, t1, &ks->data[26]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14); KEYUPDATE_TEMP(t0, t1, &ks->data[28]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15); KEYUPDATE_TEMP(t0, t1, &ks->data[30]); +#else + { + int i; + for (i=2; i<16; i+=2) { + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]); + KEYUPDATE_TEMP(t0, t1, &ks->data[i*2]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i+1]); + KEYUPDATE_TEMP(t0, t1, &ks->data[i*2+2]); + } + } +#endif +} + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(s, x1); + char2word(s+4, x2); + char2word(s+8, x3); + char2word(s+12, x4); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + E_SEED(t0, t1, x1, x2, x3, x4, 0); + E_SEED(t0, t1, x3, x4, x1, x2, 2); + E_SEED(t0, t1, x1, x2, x3, x4, 4); + E_SEED(t0, t1, x3, x4, x1, x2, 6); + E_SEED(t0, t1, x1, x2, x3, x4, 8); + E_SEED(t0, t1, x3, x4, x1, x2, 10); + E_SEED(t0, t1, x1, x2, x3, x4, 12); + E_SEED(t0, t1, x3, x4, x1, x2, 14); + E_SEED(t0, t1, x1, x2, x3, x4, 16); + E_SEED(t0, t1, x3, x4, x1, x2, 18); + E_SEED(t0, t1, x1, x2, x3, x4, 20); + E_SEED(t0, t1, x3, x4, x1, x2, 22); + E_SEED(t0, t1, x1, x2, x3, x4, 24); + E_SEED(t0, t1, x3, x4, x1, x2, 26); + E_SEED(t0, t1, x1, x2, x3, x4, 28); + E_SEED(t0, t1, x3, x4, x1, x2, 30); +#else + { + int i; + for (i=0;i<30;i+=4) { + E_SEED(t0,t1,x1,x2,x3,x4,i); + E_SEED(t0,t1,x3,x4,x1,x2,i+2); + } + } +#endif + + word2char(x3, d); + word2char(x4, d+4); + word2char(x1, d+8); + word2char(x2, d+12); +} + +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(s, x1); + char2word(s+4, x2); + char2word(s+8, x3); + char2word(s+12, x4); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + E_SEED(t0, t1, x1, x2, x3, x4, 30); + E_SEED(t0, t1, x3, x4, x1, x2, 28); + E_SEED(t0, t1, x1, x2, x3, x4, 26); + E_SEED(t0, t1, x3, x4, x1, x2, 24); + E_SEED(t0, t1, x1, x2, x3, x4, 22); + E_SEED(t0, t1, x3, x4, x1, x2, 20); + E_SEED(t0, t1, x1, x2, x3, x4, 18); + E_SEED(t0, t1, x3, x4, x1, x2, 16); + E_SEED(t0, t1, x1, x2, x3, x4, 14); + E_SEED(t0, t1, x3, x4, x1, x2, 12); + E_SEED(t0, t1, x1, x2, x3, x4, 10); + E_SEED(t0, t1, x3, x4, x1, x2, 8); + E_SEED(t0, t1, x1, x2, x3, x4, 6); + E_SEED(t0, t1, x3, x4, x1, x2, 4); + E_SEED(t0, t1, x1, x2, x3, x4, 2); + E_SEED(t0, t1, x3, x4, x1, x2, 0); +#else + { + int i; + for (i=30; i>0; i-=4) { + E_SEED(t0, t1, x1, x2, x3, x4, i); + E_SEED(t0, t1, x3, x4, x1, x2, i-2); + + } + } +#endif + + word2char(x3, d); + word2char(x4, d+4); + word2char(x1, d+8); + word2char(x2, d+12); +} + +#endif /* OPENSSL_NO_SEED */ diff --git a/crypto/openssl/crypto/evp/m_ecdsa.c b/crypto/openssl/crypto/seed/seed.h similarity index 52% copy from crypto/openssl/crypto/evp/m_ecdsa.c copy to crypto/openssl/crypto/seed/seed.h index fad270faca..6ffa5f024e 100644 --- a/crypto/openssl/crypto/evp/m_ecdsa.c +++ b/crypto/openssl/crypto/seed/seed.h @@ -1,6 +1,30 @@ -/* crypto/evp/m_ecdsa.c */ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). 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. Neither the name of author 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 AUTHOR AND CONTRIBUTORS ``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 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. + * + */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * 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 @@ -52,97 +76,62 @@ * 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 -#include "cryptlib.h" -#include -#include -#include - -#ifndef OPENSSL_NO_SHA -static int init(EVP_MD_CTX *ctx) - { return SHA1_Init(ctx->md_data); } - -static int update(EVP_MD_CTX *ctx,const void *data,size_t count) - { return SHA1_Update(ctx->md_data,data,count); } - -static int final(EVP_MD_CTX *ctx,unsigned char *md) - { return SHA1_Final(md,ctx->md_data); } - -static const EVP_MD ecdsa_md= - { - NID_ecdsa_with_SHA1, - NID_ecdsa_with_SHA1, - SHA_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_ECDSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *)+sizeof(SHA_CTX), - }; - -const EVP_MD *EVP_ecdsa(void) - { - return(&ecdsa_md); - } + +#ifndef HEADER_SEED_H +#define HEADER_SEED_H + +#include +#include +#include + +#ifdef OPENSSL_NO_SEED +#error SEED is disabled. +#endif + +#ifdef AES_LONG /* look whether we need 'long' to get 32 bits */ +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif #endif + +#if !defined(NO_SYS_TYPES_H) +# include +#endif + +#define SEED_BLOCK_SIZE 16 +#define SEED_KEY_LENGTH 16 + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct seed_key_st { +#ifdef SEED_LONG + unsigned long data[32]; +#else + unsigned int data[32]; +#endif +} SEED_KEY_SCHEDULE; + + +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_H */ diff --git a/crypto/openssl/crypto/o_time.h b/crypto/openssl/crypto/seed/seed_cbc.c similarity index 75% copy from crypto/openssl/crypto/o_time.h copy to crypto/openssl/crypto/seed/seed_cbc.c index e66044626d..6c3f9b527a 100644 --- a/crypto/openssl/crypto/o_time.h +++ b/crypto/openssl/crypto/seed/seed_cbc.c @@ -1,9 +1,6 @@ -/* crypto/o_time.h -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2001. - */ +/* crypto/seed/seed_cbc.c -*- mode:C; c-file-style: "eay" -*- */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * 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 @@ -20,12 +17,12 @@ * 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/)" + * 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. + * 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 @@ -34,7 +31,7 @@ * 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/)" + * 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 @@ -50,17 +47,17 @@ * 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). - * */ -#ifndef HEADER_O_TIME_H -#define HEADER_O_TIME_H - -#include - -struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +#include +#include -#endif +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc) + { + if (enc) + CRYPTO_cbc128_encrypt(in,out,len,ks,ivec,(block128_f)SEED_encrypt); + else + CRYPTO_cbc128_decrypt(in,out,len,ks,ivec,(block128_f)SEED_decrypt); + } diff --git a/crypto/openssl/crypto/evp/dig_eng.c b/crypto/openssl/crypto/seed/seed_cfb.c similarity index 74% rename from crypto/openssl/crypto/evp/dig_eng.c rename to crypto/openssl/crypto/seed/seed_cfb.c index 64cdf9366c..694597dd06 100644 --- a/crypto/openssl/crypto/evp/dig_eng.c +++ b/crypto/openssl/crypto/seed/seed_cfb.c @@ -1,4 +1,53 @@ -/* crypto/evp/digest.c */ +/* crypto/seed/seed_cfb.c -*- mode:C; c-file-style: "eay" -*- */ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,126 +104,13 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -/* ==================================================================== - * Copyright (c) 1998-2001 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 -#include "cryptlib.h" -#include -#include -#ifndef OPENSSL_NO_ENGINE -#include -#endif -#include "evp_locl.h" - -#ifndef OPENSSL_NO_ENGINE -#ifdef OPENSSL_FIPS - -static int do_evp_md_engine_full(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) - { - if (*ptype) - { - /* Ensure an ENGINE left lying around from last time is cleared - * (the previous check attempted to avoid this if the same - * ENGINE and EVP_MD could be used). */ - if(ctx->engine) - ENGINE_finish(ctx->engine); - if(impl) - { - if (!ENGINE_init(impl)) - { - EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR); - return 0; - } - } - else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_digest_engine((*ptype)->type); - if(impl) - { - /* There's an ENGINE for this job ... (apparently) */ - const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type); - if(!d) - { - /* Same comment from evp_enc.c */ - EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR); - return 0; - } - /* We'll use the ENGINE's private digest definition */ - *ptype = d; - /* Store the ENGINE functional reference so we know - * 'type' came from an ENGINE and we need to release - * it when done. */ - ctx->engine = impl; - } - else - ctx->engine = NULL; - } - else - if(!ctx->digest) - { - EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_NO_DIGEST_SET); - return 0; - } - return 1; - } +#include +#include -void int_EVP_MD_init_engine_callbacks(void) +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc) { - int_EVP_MD_set_engine_callbacks( - ENGINE_init, ENGINE_finish, do_evp_md_engine_full); + CRYPTO_cfb128_encrypt(in,out,len,ks,ivec,num,enc,(block128_f)SEED_encrypt); } -#endif -#endif diff --git a/crypto/openssl/crypto/o_time.h b/crypto/openssl/crypto/seed/seed_ecb.c similarity index 76% copy from crypto/openssl/crypto/o_time.h copy to crypto/openssl/crypto/seed/seed_ecb.c index e66044626d..e63f5ae14e 100644 --- a/crypto/openssl/crypto/o_time.h +++ b/crypto/openssl/crypto/seed/seed_ecb.c @@ -1,9 +1,6 @@ -/* crypto/o_time.h -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2001. - */ +/* crypto/seed/seed_ecb.c -*- mode:C; c-file-style: "eay" -*- */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * 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 @@ -20,12 +17,12 @@ * 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/)" + * 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. + * 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 @@ -34,7 +31,7 @@ * 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/)" + * 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 @@ -50,17 +47,14 @@ * 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). - * */ -#ifndef HEADER_O_TIME_H -#define HEADER_O_TIME_H - -#include - -struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +#include -#endif +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc) + { + if (enc) + SEED_encrypt(in, out, ks); + else + SEED_decrypt(in, out, ks); + } diff --git a/crypto/openssl/crypto/seed/seed_locl.h b/crypto/openssl/crypto/seed/seed_locl.h new file mode 100644 index 0000000000..fd456b6422 --- /dev/null +++ b/crypto/openssl/crypto/seed/seed_locl.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). 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. Neither the name of author 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 AUTHOR AND CONTRIBUTORS ``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 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. + * + */ +#ifndef HEADER_SEED_LOCL_H +#define HEADER_SEED_LOCL_H + +#include "openssl/e_os2.h" +#include + + +#ifdef SEED_LONG /* need 32-bit type */ +typedef unsigned long seed_word; +#else +typedef unsigned int seed_word; +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#define G_FUNC(v) \ + SS[0][(unsigned char) (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \ + SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff] + +#define char2word(c, i) \ + (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3])) + +#define word2char(l, c) \ + *((c)+0) = (unsigned char)((l)>>24) & 0xff; \ + *((c)+1) = (unsigned char)((l)>>16) & 0xff; \ + *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \ + *((c)+3) = (unsigned char)((l)) & 0xff + +#define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC) \ + (T0) = (X3); \ + (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff; \ + (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff; \ + (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ + (T1) = ((X2) + (KC) - (X4)) & 0xffffffff + +#define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC) \ + (T0) = (X1); \ + (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff; \ + (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff; \ + (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ + (T1) = ((X2) + (KC) - (X4)) & 0xffffffff + +#define KEYUPDATE_TEMP(T0, T1, K) \ + (K)[0] = G_FUNC((T0)); \ + (K)[1] = G_FUNC((T1)) + +#define XOR_SEEDBLOCK(DST, SRC) \ + ((DST))[0] ^= ((SRC))[0]; \ + ((DST))[1] ^= ((SRC))[1]; \ + ((DST))[2] ^= ((SRC))[2]; \ + ((DST))[3] ^= ((SRC))[3] + +#define MOV_SEEDBLOCK(DST, SRC) \ + ((DST))[0] = ((SRC))[0]; \ + ((DST))[1] = ((SRC))[1]; \ + ((DST))[2] = ((SRC))[2]; \ + ((DST))[3] = ((SRC))[3] + +# define CHAR2WORD(C, I) \ + char2word((C), (I)[0]); \ + char2word((C+4), (I)[1]); \ + char2word((C+8), (I)[2]); \ + char2word((C+12), (I)[3]) + +# define WORD2CHAR(I, C) \ + word2char((I)[0], (C)); \ + word2char((I)[1], (C+4)); \ + word2char((I)[2], (C+8)); \ + word2char((I)[3], (C+12)) + +# define E_SEED(T0, T1, X1, X2, X3, X4, rbase) \ + (T0) = (X3) ^ (ks->data)[(rbase)]; \ + (T1) = (X4) ^ (ks->data)[(rbase)+1]; \ + (T1) ^= (T0); \ + (T1) = G_FUNC((T1)); \ + (T0) = ((T0) + (T1)) & 0xffffffff; \ + (T0) = G_FUNC((T0)); \ + (T1) = ((T1) + (T0)) & 0xffffffff; \ + (T1) = G_FUNC((T1)); \ + (T0) = ((T0) + (T1)) & 0xffffffff; \ + (X1) ^= (T0); \ + (X2) ^= (T1) + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_LOCL_H */ diff --git a/crypto/openssl/crypto/aes/aes_ofb.c b/crypto/openssl/crypto/seed/seed_ofb.c similarity index 86% copy from crypto/openssl/crypto/aes/aes_ofb.c copy to crypto/openssl/crypto/seed/seed_ofb.c index f358bb39e2..3c8ba33bb9 100644 --- a/crypto/openssl/crypto/aes/aes_ofb.c +++ b/crypto/openssl/crypto/seed/seed_ofb.c @@ -1,6 +1,6 @@ -/* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */ +/* crypto/seed/seed_ofb.c -*- mode:C; c-file-style: "eay" -*- */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * 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 @@ -105,38 +105,12 @@ * [including the GNU Public Licence.] */ -#ifndef AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include +#include +#include -#include -#include "aes_locl.h" - -/* The input and output encrypted as though 128bit ofb mode is being - * used. The extra state information to record how much of the - * 128bit block we have used is contained in *num; - */ -void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, - unsigned char *ivec, int *num) { - - unsigned int n; - unsigned long l=length; - - assert(in && out && key && ivec && num); - - n = *num; - - while (l--) { - if (n == 0) { - AES_encrypt(ivec, ivec, key); - } - *(out++) = *(in++) ^ ivec[n]; - n = (n+1) % AES_BLOCK_SIZE; +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num) + { + CRYPTO_ofb128_encrypt(in,out,len,ks,ivec,num,(block128_f)SEED_encrypt); } - - *num=n; -} diff --git a/crypto/openssl/crypto/sha/sha.h b/crypto/openssl/crypto/sha/sha.h index 47a2c29f66..16cacf9fc0 100644 --- a/crypto/openssl/crypto/sha/sha.h +++ b/crypto/openssl/crypto/sha/sha.h @@ -81,7 +81,7 @@ extern "C" { * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#if defined(__LP32__) #define SHA_LONG unsigned long #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) #define SHA_LONG unsigned long @@ -106,9 +106,6 @@ typedef struct SHAstate_st } SHA_CTX; #ifndef OPENSSL_NO_SHA0 -#ifdef OPENSSL_FIPS -int private_SHA_Init(SHA_CTX *c); -#endif int SHA_Init(SHA_CTX *c); int SHA_Update(SHA_CTX *c, const void *data, size_t len); int SHA_Final(unsigned char *md, SHA_CTX *c); diff --git a/crypto/openssl/crypto/sha/sha1_one.c b/crypto/openssl/crypto/sha/sha1_one.c index 4831174198..7c65b60276 100644 --- a/crypto/openssl/crypto/sha/sha1_one.c +++ b/crypto/openssl/crypto/sha/sha1_one.c @@ -61,7 +61,7 @@ #include #include -#if !defined(OPENSSL_NO_SHA1) +#ifndef OPENSSL_NO_SHA1 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) { SHA_CTX c; diff --git a/crypto/openssl/crypto/sha/sha1dgst.c b/crypto/openssl/crypto/sha/sha1dgst.c index d31f0781a0..50d1925cde 100644 --- a/crypto/openssl/crypto/sha/sha1dgst.c +++ b/crypto/openssl/crypto/sha/sha1dgst.c @@ -63,10 +63,6 @@ #define SHA_1 #include -#ifdef OPENSSL_FIPS -#include -#endif - const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT; diff --git a/crypto/openssl/crypto/sha/sha256.c b/crypto/openssl/crypto/sha/sha256.c index 3256a83e98..8952d87673 100644 --- a/crypto/openssl/crypto/sha/sha256.c +++ b/crypto/openssl/crypto/sha/sha256.c @@ -12,39 +12,29 @@ #include #include -#ifdef OPENSSL_FIPS -#include -#endif - #include const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; int SHA224_Init (SHA256_CTX *c) { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif + memset (c,0,sizeof(*c)); c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL; - c->Nl=0; c->Nh=0; - c->num=0; c->md_len=SHA224_DIGEST_LENGTH; + c->md_len=SHA224_DIGEST_LENGTH; return 1; } int SHA256_Init (SHA256_CTX *c) { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif + memset (c,0,sizeof(*c)); c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL; - c->Nl=0; c->Nh=0; - c->num=0; c->md_len=SHA256_DIGEST_LENGTH; + c->md_len=SHA256_DIGEST_LENGTH; return 1; } @@ -94,21 +84,21 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c) */ #define HASH_MAKE_STRING(c,s) do { \ unsigned long ll; \ - unsigned int xn; \ + unsigned int nn; \ switch ((c)->md_len) \ { case SHA224_DIGEST_LENGTH: \ - for (xn=0;xnh[xn]; HOST_l2c(ll,(s)); } \ + for (nn=0;nnh[nn]; HOST_l2c(ll,(s)); } \ break; \ case SHA256_DIGEST_LENGTH: \ - for (xn=0;xnh[xn]; HOST_l2c(ll,(s)); } \ + for (nn=0;nnh[nn]; HOST_l2c(ll,(s)); } \ break; \ default: \ if ((c)->md_len > SHA256_DIGEST_LENGTH) \ return 0; \ - for (xn=0;xn<(c)->md_len/4;xn++) \ - { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ + for (nn=0;nn<(c)->md_len/4;nn++) \ + { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \ break; \ } \ } while (0) diff --git a/crypto/openssl/crypto/sha/sha512.c b/crypto/openssl/crypto/sha/sha512.c index 9e91bcad04..cbc0e58c48 100644 --- a/crypto/openssl/crypto/sha/sha512.c +++ b/crypto/openssl/crypto/sha/sha512.c @@ -5,10 +5,6 @@ * ==================================================================== */ #include -#ifdef OPENSSL_FIPS -#include -#endif - #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) /* * IMPLEMENTATION NOTES. @@ -65,9 +61,19 @@ const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT; int SHA384_Init (SHA512_CTX *c) { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif +#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) + /* maintain dword order required by assembler module */ + unsigned int *h = (unsigned int *)c->h; + + h[0] = 0xcbbb9d5d; h[1] = 0xc1059ed8; + h[2] = 0x629a292a; h[3] = 0x367cd507; + h[4] = 0x9159015a; h[5] = 0x3070dd17; + h[6] = 0x152fecd8; h[7] = 0xf70e5939; + h[8] = 0x67332667; h[9] = 0xffc00b31; + h[10] = 0x8eb44a87; h[11] = 0x68581511; + h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7; + h[14] = 0x47b5481d; h[15] = 0xbefa4fa4; +#else c->h[0]=U64(0xcbbb9d5dc1059ed8); c->h[1]=U64(0x629a292a367cd507); c->h[2]=U64(0x9159015a3070dd17); @@ -76,6 +82,7 @@ int SHA384_Init (SHA512_CTX *c) c->h[5]=U64(0x8eb44a8768581511); c->h[6]=U64(0xdb0c2e0d64f98fa7); c->h[7]=U64(0x47b5481dbefa4fa4); +#endif c->Nl=0; c->Nh=0; c->num=0; c->md_len=SHA384_DIGEST_LENGTH; return 1; @@ -83,9 +90,19 @@ int SHA384_Init (SHA512_CTX *c) int SHA512_Init (SHA512_CTX *c) { -#ifdef OPENSSL_FIPS - FIPS_selftest_check(); -#endif +#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) + /* maintain dword order required by assembler module */ + unsigned int *h = (unsigned int *)c->h; + + h[0] = 0x6a09e667; h[1] = 0xf3bcc908; + h[2] = 0xbb67ae85; h[3] = 0x84caa73b; + h[4] = 0x3c6ef372; h[5] = 0xfe94f82b; + h[6] = 0xa54ff53a; h[7] = 0x5f1d36f1; + h[8] = 0x510e527f; h[9] = 0xade682d1; + h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f; + h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b; + h[14] = 0x5be0cd19; h[15] = 0x137e2179; +#else c->h[0]=U64(0x6a09e667f3bcc908); c->h[1]=U64(0xbb67ae8584caa73b); c->h[2]=U64(0x3c6ef372fe94f82b); @@ -94,6 +111,7 @@ int SHA512_Init (SHA512_CTX *c) c->h[5]=U64(0x9b05688c2b3e6c1f); c->h[6]=U64(0x1f83d9abfb41bd6b); c->h[7]=U64(0x5be0cd19137e2179); +#endif c->Nl=0; c->Nh=0; c->num=0; c->md_len=SHA512_DIGEST_LENGTH; return 1; @@ -142,6 +160,24 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c) if (md==0) return 0; +#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) + /* recall assembler dword order... */ + n = c->md_len; + if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH) + { + unsigned int *h = (unsigned int *)c->h, t; + + for (n/=4;n;n--) + { + t = *(h++); + *(md++) = (unsigned char)(t>>24); + *(md++) = (unsigned char)(t>>16); + *(md++) = (unsigned char)(t>>8); + *(md++) = (unsigned char)(t); + } + } + else return 0; +#else switch (c->md_len) { /* Let compiler decide if it's appropriate to unroll... */ @@ -178,7 +214,7 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c) /* ... as well as make sure md_len is not abused. */ default: return 0; } - +#endif return 1; } @@ -204,7 +240,7 @@ int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len) if (len < n) { - memcpy (p+c->num,data,len), c->num += len; + memcpy (p+c->num,data,len), c->num += (unsigned int)len; return 1; } else { @@ -314,7 +350,7 @@ static const SHA_LONG64 K512[80] = { #ifndef PEDANTIC # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) # if defined(__x86_64) || defined(__x86_64__) -# define ROTR(a,n) ({ unsigned long ret; \ +# define ROTR(a,n) ({ SHA_LONG64 ret; \ asm ("rorq %1,%0" \ : "=r"(ret) \ : "J"(n),"0"(a) \ @@ -337,20 +373,21 @@ static const SHA_LONG64 K512[80] = { ((SHA_LONG64)hi)<<32|lo; }) # else # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ - unsigned int hi=p[0],lo=p[1]; \ + unsigned int hi=p[0],lo=p[1]; \ asm ("bswapl %0; bswapl %1;" \ : "=r"(lo),"=r"(hi) \ : "0"(lo),"1"(hi)); \ ((SHA_LONG64)hi)<<32|lo; }) # endif # elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) -# define ROTR(a,n) ({ unsigned long ret; \ +# define ROTR(a,n) ({ SHA_LONG64 ret; \ asm ("rotrdi %0,%1,%2" \ : "=r"(ret) \ : "r"(a),"K"(n)); ret; }) # endif # elif defined(_MSC_VER) # if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# pragma intrinsic(_rotr64) # define ROTR(a,n) _rotr64((a),n) # endif # if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) @@ -398,15 +435,66 @@ static const SHA_LONG64 K512[80] = { #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -#if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) -#define GO_FOR_SSE2(ctx,in,num) do { \ - void sha512_block_sse2(void *,const void *,size_t); \ - if (!(OPENSSL_ia32cap_P & (1<<26))) break; \ - sha512_block_sse2(ctx->h,in,num); return; \ - } while (0) + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +/* + * This code should give better results on 32-bit CPU with less than + * ~24 registers, both size and performance wise... + */ +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) + { + const SHA_LONG64 *W=in; + SHA_LONG64 A,E,T; + SHA_LONG64 X[9+80],*F; + int i; + + while (num--) { + + F = X+80; + A = ctx->h[0]; F[1] = ctx->h[1]; + F[2] = ctx->h[2]; F[3] = ctx->h[3]; + E = ctx->h[4]; F[5] = ctx->h[5]; + F[6] = ctx->h[6]; F[7] = ctx->h[7]; + + for (i=0;i<16;i++,F--) + { +#ifdef B_ENDIAN + T = W[i]; +#else + T = PULL64(W[i]); #endif + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A,F[1],F[2]); + } + + for (;i<80;i++,F--) + { + T = sigma0(F[8+16-1]); + T += sigma1(F[8+16-14]); + T += F[8+16] + F[8+16-9]; + + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A,F[1],F[2]); + } -#ifdef OPENSSL_SMALL_FOOTPRINT + ctx->h[0] += A; ctx->h[1] += F[1]; + ctx->h[2] += F[2]; ctx->h[3] += F[3]; + ctx->h[4] += E; ctx->h[5] += F[5]; + ctx->h[6] += F[6]; ctx->h[7] += F[7]; + + W+=SHA_LBLOCK; + } + } + +#elif defined(OPENSSL_SMALL_FOOTPRINT) static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) { @@ -415,10 +503,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num SHA_LONG64 X[16]; int i; -#ifdef GO_FOR_SSE2 - GO_FOR_SSE2(ctx,in,num); -#endif - while (num--) { a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; @@ -463,11 +547,11 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num h = Sigma0(a) + Maj(a,b,c); \ d += T1; h += T1; } while (0) -#define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \ - s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ - s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ - T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ - ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) +#define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \ + ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0) static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) { @@ -476,10 +560,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num SHA_LONG64 X[16]; int i; -#ifdef GO_FOR_SSE2 - GO_FOR_SSE2(ctx,in,num); -#endif - while (num--) { a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; @@ -521,16 +601,24 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); #endif - for (i=16;i<80;i+=8) + for (i=16;i<80;i+=16) { - ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X); - ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X); - ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X); - ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X); - ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X); - ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X); - ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X); - ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X); + ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X); + ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X); + ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X); + ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X); + ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X); + ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X); + ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X); + ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X); + ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X); + ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X); + ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X); + ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X); + ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X); + ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X); + ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X); + ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X); } ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; @@ -544,13 +632,10 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num #endif /* SHA512_ASM */ -#else /* OPENSSL_NO_SHA512 */ +#else /* !OPENSSL_NO_SHA512 */ -/* Sensitive compilers ("Compaq C V6.4-005 on OpenVMS VAX V7.3", for - * example) dislike a statement-free file, complaining: - * "%CC-W-EMPTYFILE, Source file does not contain any declarations." - */ - -int sha512_dummy(); +#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) +static void *dummy=&dummy; +#endif -#endif /* OPENSSL_NO_SHA512 */ +#endif /* !OPENSSL_NO_SHA512 */ diff --git a/crypto/openssl/crypto/sha/sha_dgst.c b/crypto/openssl/crypto/sha/sha_dgst.c index 598f4d721a..70eb56032c 100644 --- a/crypto/openssl/crypto/sha/sha_dgst.c +++ b/crypto/openssl/crypto/sha/sha_dgst.c @@ -57,12 +57,6 @@ */ #include -#include -#ifdef OPENSSL_FIPS -#include -#endif - -#include #if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA) #undef SHA_1 diff --git a/crypto/openssl/crypto/sha/sha_locl.h b/crypto/openssl/crypto/sha/sha_locl.h index da46ddfe79..672c26eee1 100644 --- a/crypto/openssl/crypto/sha/sha_locl.h +++ b/crypto/openssl/crypto/sha/sha_locl.h @@ -122,23 +122,14 @@ void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num); #define INIT_DATA_h3 0x10325476UL #define INIT_DATA_h4 0xc3d2e1f0UL -#if defined(SHA_0) && defined(OPENSSL_FIPS) -FIPS_NON_FIPS_MD_Init(SHA) -#else int HASH_INIT (SHA_CTX *c) -#endif { -#if defined(SHA_1) && defined(OPENSSL_FIPS) - FIPS_selftest_check(); -#endif + memset (c,0,sizeof(*c)); c->h0=INIT_DATA_h0; c->h1=INIT_DATA_h1; c->h2=INIT_DATA_h2; c->h3=INIT_DATA_h3; c->h4=INIT_DATA_h4; - c->Nl=0; - c->Nh=0; - c->num=0; return 1; } diff --git a/crypto/openssl/crypto/stack/safestack.h b/crypto/openssl/crypto/stack/safestack.h index 78cc485e6d..891cb84a51 100644 --- a/crypto/openssl/crypto/stack/safestack.h +++ b/crypto/openssl/crypto/stack/safestack.h @@ -57,18 +57,27 @@ #include -#ifdef DEBUG_SAFESTACK - #ifndef CHECKED_PTR_OF #define CHECKED_PTR_OF(type, p) \ ((void*) (1 ? p : (type*)0)) #endif +/* In C++ we get problems because an explicit cast is needed from (void *) + * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +#define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + #define CHECKED_SK_FREE_FUNC(type, p) \ ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) +#define CHECKED_SK_FREE_FUNC2(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type))0))) + #define CHECKED_SK_CMP_FUNC(type, p) \ - ((int (*)(const char * const *, const char * const *)) \ + ((int (*)(const void *, const void *)) \ ((1 ? p : (int (*)(const type * const *, const type * const *))0))) #define STACK_OF(type) struct stack_st_##type @@ -77,11 +86,51 @@ #define DECLARE_STACK_OF(type) \ STACK_OF(type) \ { \ - STACK stack; \ + _STACK stack; \ + }; +#define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ }; #define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/ + +/* Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * +o * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as + * mentioned above, instead of a single char each entry is a + * NUL-terminated array of chars. So, we have to implement STRING + * specially for STACK_OF. This is dealt with in the autogenerated + * macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* Similarly, we sometimes use a block of characters, NOT + * nul-terminated. These should also be distinguished from "normal" + * stacks. */ + +typedef void *OPENSSL_BLOCK; +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + /* SKM_sk_... stack macros are internal to safestack.h: * never use them directly, use sk__... instead */ #define SKM_sk_new(type, cmp) \ @@ -89,52 +138,55 @@ STACK_OF(type) \ #define SKM_sk_new_null(type) \ ((STACK_OF(type) *)sk_new_null()) #define SKM_sk_free(type, st) \ - sk_free(CHECKED_PTR_OF(STACK_OF(type), st)) + sk_free(CHECKED_STACK_OF(type, st)) #define SKM_sk_num(type, st) \ - sk_num(CHECKED_PTR_OF(STACK_OF(type), st)) + sk_num(CHECKED_STACK_OF(type, st)) #define SKM_sk_value(type, st,i) \ - ((type *)sk_value(CHECKED_PTR_OF(STACK_OF(type), st), i)) + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) #define SKM_sk_set(type, st,i,val) \ - sk_set(CHECKED_PTR_OF(STACK_OF(type), st), i, CHECKED_PTR_OF(type, val)) + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) #define SKM_sk_zero(type, st) \ - sk_zero(CHECKED_PTR_OF(STACK_OF(type), st)) -#define SKM_sk_push(type, st,val) \ - sk_push(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) -#define SKM_sk_unshift(type, st,val) \ - sk_unshift(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) -#define SKM_sk_find(type, st,val) \ - sk_find(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) -#define SKM_sk_delete(type, st,i) \ - (type *)sk_delete(CHECKED_PTR_OF(STACK_OF(type), st), i) -#define SKM_sk_delete_ptr(type, st,ptr) \ - (type *)sk_delete_ptr(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, ptr)) -#define SKM_sk_insert(type, st,val,i) \ - sk_insert(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val), i) -#define SKM_sk_set_cmp_func(type, st,cmp) \ + sk_zero(CHECKED_STACK_OF(type, st)) +#define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +#define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +#define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +#define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +#define SKM_sk_set_cmp_func(type, st, cmp) \ ((int (*)(const type * const *,const type * const *)) \ - sk_set_cmp_func(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_CMP_FUNC(type, cmp))) + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) #define SKM_sk_dup(type, st) \ - (STACK_OF(type) *)sk_dup(CHECKED_PTR_OF(STACK_OF(type), st)) -#define SKM_sk_pop_free(type, st,free_func) \ - sk_pop_free(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_FREE_FUNC(type, free_func)) + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) #define SKM_sk_shift(type, st) \ - (type *)sk_shift(CHECKED_PTR_OF(STACK_OF(type), st)) + (type *)sk_shift(CHECKED_STACK_OF(type, st)) #define SKM_sk_pop(type, st) \ - (type *)sk_pop(CHECKED_PTR_OF(STACK_OF(type), st)) + (type *)sk_pop(CHECKED_STACK_OF(type, st)) #define SKM_sk_sort(type, st) \ - sk_sort(CHECKED_PTR_OF(STACK_OF(type), st)) + sk_sort(CHECKED_STACK_OF(type, st)) #define SKM_sk_is_sorted(type, st) \ - sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st)) + sk_is_sorted(CHECKED_STACK_OF(type, st)) #define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - (STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \ + (STACK_OF(type) *)d2i_ASN1_SET((STACK_OF(OPENSSL_BLOCK) **)CHECKED_STACK_OF(type, st), \ pp, length, \ CHECKED_D2I_OF(type, d2i_func), \ CHECKED_SK_FREE_FUNC(type, free_func), \ ex_tag, ex_class) #define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ - i2d_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), pp, \ + i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ CHECKED_I2D_OF(type, i2d_func), \ ex_tag, ex_class, is_set) @@ -151,72 +203,8 @@ STACK_OF(type) \ CHECKED_SK_FREE_FUNC(type, free_func), \ pass, passlen, oct, seq) -#else - -#define STACK_OF(type) STACK -#define PREDECLARE_STACK_OF(type) /* nada */ -#define DECLARE_STACK_OF(type) /* nada */ -#define IMPLEMENT_STACK_OF(type) /* nada */ - -#define SKM_sk_new(type, cmp) \ - sk_new((int (*)(const char * const *, const char * const *))(cmp)) -#define SKM_sk_new_null(type) \ - sk_new_null() -#define SKM_sk_free(type, st) \ - sk_free(st) -#define SKM_sk_num(type, st) \ - sk_num(st) -#define SKM_sk_value(type, st,i) \ - ((type *)sk_value(st, i)) -#define SKM_sk_set(type, st,i,val) \ - ((type *)sk_set(st, i,(char *)val)) -#define SKM_sk_zero(type, st) \ - sk_zero(st) -#define SKM_sk_push(type, st,val) \ - sk_push(st, (char *)val) -#define SKM_sk_unshift(type, st,val) \ - sk_unshift(st, (char *)val) -#define SKM_sk_find(type, st,val) \ - sk_find(st, (char *)val) -#define SKM_sk_delete(type, st,i) \ - ((type *)sk_delete(st, i)) -#define SKM_sk_delete_ptr(type, st,ptr) \ - ((type *)sk_delete_ptr(st,(char *)ptr)) -#define SKM_sk_insert(type, st,val,i) \ - sk_insert(st, (char *)val, i) -#define SKM_sk_set_cmp_func(type, st,cmp) \ - ((int (*)(const type * const *,const type * const *)) \ - sk_set_cmp_func(st, (int (*)(const char * const *, const char * const *))(cmp))) -#define SKM_sk_dup(type, st) \ - sk_dup(st) -#define SKM_sk_pop_free(type, st,free_func) \ - sk_pop_free(st, (void (*)(void *))free_func) -#define SKM_sk_shift(type, st) \ - ((type *)sk_shift(st)) -#define SKM_sk_pop(type, st) \ - ((type *)sk_pop(st)) -#define SKM_sk_sort(type, st) \ - sk_sort(st) -#define SKM_sk_is_sorted(type, st) \ - sk_is_sorted(st) - -#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - d2i_ASN1_SET(st,pp,length, (void *(*)(void ** ,const unsigned char ** ,long))d2i_func, (void (*)(void *))free_func, ex_tag,ex_class) -#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ - i2d_ASN1_SET(st,pp,(int (*)(void *, unsigned char **))i2d_func,ex_tag,ex_class,is_set) - -#define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ - ASN1_seq_pack(st, (int (*)(void *, unsigned char **))i2d_func, buf, len) -#define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ - ASN1_seq_unpack(buf,len,(void *(*)(void **,const unsigned char **,long))d2i_func, (void(*)(void *))free_func) - -#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ - ((STACK *)PKCS12_decrypt_d2i(algor,(char *(*)())d2i_func, (void(*)(void *))free_func,pass,passlen,oct,seq)) - -#endif - /* This block of defines is updated by util/mkstack.pl, please do not touch! */ -#define sk_ACCESS_DESCRIPTION_new(st) SKM_sk_new(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) #define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) #define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) #define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) @@ -238,7 +226,7 @@ STACK_OF(type) \ #define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) #define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) -#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st)) +#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) #define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) #define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) #define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) @@ -260,7 +248,7 @@ STACK_OF(type) \ #define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) #define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) -#define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) #define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) #define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) #define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) @@ -282,7 +270,7 @@ STACK_OF(type) \ #define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) #define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) -#define sk_ASN1_INTEGER_new(st) SKM_sk_new(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) #define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) #define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) #define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) @@ -304,7 +292,7 @@ STACK_OF(type) \ #define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) #define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) -#define sk_ASN1_OBJECT_new(st) SKM_sk_new(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) #define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) #define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) #define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) @@ -326,7 +314,7 @@ STACK_OF(type) \ #define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) #define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) -#define sk_ASN1_STRING_TABLE_new(st) SKM_sk_new(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) #define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) #define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) #define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) @@ -348,7 +336,7 @@ STACK_OF(type) \ #define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) #define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) -#define sk_ASN1_TYPE_new(st) SKM_sk_new(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) #define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) #define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) #define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) @@ -370,7 +358,29 @@ STACK_OF(type) \ #define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) #define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) -#define sk_ASN1_VALUE_new(st) SKM_sk_new(ASN1_VALUE, (st)) +#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) + +#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) #define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) #define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) #define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) @@ -392,7 +402,7 @@ STACK_OF(type) \ #define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) #define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) -#define sk_BIO_new(st) SKM_sk_new(BIO, (st)) +#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) #define sk_BIO_new_null() SKM_sk_new_null(BIO) #define sk_BIO_free(st) SKM_sk_free(BIO, (st)) #define sk_BIO_num(st) SKM_sk_num(BIO, (st)) @@ -414,7 +424,51 @@ STACK_OF(type) \ #define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) #define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) -#define sk_CMS_CertificateChoices_new(st) SKM_sk_new(CMS_CertificateChoices, (st)) +#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) + +#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) + +#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) #define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) #define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) #define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) @@ -436,7 +490,7 @@ STACK_OF(type) \ #define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) #define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) -#define sk_CMS_RecipientInfo_new(st) SKM_sk_new(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) #define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) #define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) #define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) @@ -458,7 +512,7 @@ STACK_OF(type) \ #define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) #define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) -#define sk_CMS_RevocationInfoChoice_new(st) SKM_sk_new(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) #define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) #define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) #define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) @@ -480,7 +534,7 @@ STACK_OF(type) \ #define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) #define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) -#define sk_CMS_SignerInfo_new(st) SKM_sk_new(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) #define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) #define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) #define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) @@ -502,7 +556,7 @@ STACK_OF(type) \ #define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) #define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) -#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) #define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) #define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) #define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) @@ -524,7 +578,7 @@ STACK_OF(type) \ #define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) #define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) -#define sk_CONF_MODULE_new(st) SKM_sk_new(CONF_MODULE, (st)) +#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) #define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) #define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) #define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) @@ -546,7 +600,7 @@ STACK_OF(type) \ #define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) #define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) -#define sk_CONF_VALUE_new(st) SKM_sk_new(CONF_VALUE, (st)) +#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) #define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) #define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) #define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) @@ -568,7 +622,7 @@ STACK_OF(type) \ #define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) #define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) -#define sk_CRYPTO_EX_DATA_FUNCS_new(st) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) #define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) #define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) #define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) @@ -590,7 +644,7 @@ STACK_OF(type) \ #define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) #define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) -#define sk_CRYPTO_dynlock_new(st) SKM_sk_new(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) #define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) #define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) #define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) @@ -612,7 +666,7 @@ STACK_OF(type) \ #define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) #define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) -#define sk_DIST_POINT_new(st) SKM_sk_new(DIST_POINT, (st)) +#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) #define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) #define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) #define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) @@ -634,7 +688,7 @@ STACK_OF(type) \ #define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) #define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) -#define sk_ENGINE_new(st) SKM_sk_new(ENGINE, (st)) +#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) #define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) #define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) #define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) @@ -656,7 +710,7 @@ STACK_OF(type) \ #define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) #define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) -#define sk_ENGINE_CLEANUP_ITEM_new(st) SKM_sk_new(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) #define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) #define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) #define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) @@ -678,7 +732,117 @@ STACK_OF(type) \ #define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) #define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) -#define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME, (st)) +#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) + +#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) + +#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) + +#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) + +#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) + +#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) #define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) #define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) #define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) @@ -700,7 +864,7 @@ STACK_OF(type) \ #define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) #define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) -#define sk_GENERAL_NAMES_new(st) SKM_sk_new(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) #define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) #define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) #define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) @@ -722,7 +886,7 @@ STACK_OF(type) \ #define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) #define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) -#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) #define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) #define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) #define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) @@ -744,7 +908,7 @@ STACK_OF(type) \ #define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) #define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) -#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st)) +#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) #define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) #define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) #define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) @@ -766,7 +930,7 @@ STACK_OF(type) \ #define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) #define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) -#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) #define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) #define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) #define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) @@ -788,7 +952,7 @@ STACK_OF(type) \ #define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) #define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) -#define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) #define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) #define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) #define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) @@ -810,7 +974,7 @@ STACK_OF(type) \ #define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) #define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) -#define sk_KRB5_AUTHDATA_new(st) SKM_sk_new(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) #define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) #define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) #define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) @@ -832,7 +996,7 @@ STACK_OF(type) \ #define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) #define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) -#define sk_KRB5_AUTHENTBODY_new(st) SKM_sk_new(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) #define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) #define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) #define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) @@ -854,7 +1018,7 @@ STACK_OF(type) \ #define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) #define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) -#define sk_KRB5_CHECKSUM_new(st) SKM_sk_new(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) #define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) #define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) #define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) @@ -876,7 +1040,7 @@ STACK_OF(type) \ #define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) #define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) -#define sk_KRB5_ENCDATA_new(st) SKM_sk_new(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) #define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) #define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) #define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) @@ -898,7 +1062,7 @@ STACK_OF(type) \ #define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) #define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) -#define sk_KRB5_ENCKEY_new(st) SKM_sk_new(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) #define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) #define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) #define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) @@ -920,7 +1084,7 @@ STACK_OF(type) \ #define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) #define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) -#define sk_KRB5_PRINCNAME_new(st) SKM_sk_new(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) #define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) #define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) #define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) @@ -942,7 +1106,7 @@ STACK_OF(type) \ #define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) #define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) -#define sk_KRB5_TKTBODY_new(st) SKM_sk_new(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) #define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) #define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) #define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) @@ -964,7 +1128,29 @@ STACK_OF(type) \ #define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) #define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) -#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st)) +#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) +#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) +#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) +#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) +#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) +#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) +#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) +#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) +#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) +#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) +#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) + +#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) #define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) #define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) #define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) @@ -986,7 +1172,7 @@ STACK_OF(type) \ #define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) #define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) -#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st)) +#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) #define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) #define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) #define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) @@ -1008,7 +1194,7 @@ STACK_OF(type) \ #define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) #define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) -#define sk_NAME_FUNCS_new(st) SKM_sk_new(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) #define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) #define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) #define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) @@ -1030,7 +1216,7 @@ STACK_OF(type) \ #define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) #define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) -#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) #define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) #define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) #define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) @@ -1052,7 +1238,7 @@ STACK_OF(type) \ #define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) #define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) -#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) #define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) #define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) #define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) @@ -1074,7 +1260,7 @@ STACK_OF(type) \ #define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) #define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) -#define sk_OCSP_RESPID_new(st) SKM_sk_new(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) #define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) #define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) #define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) @@ -1096,7 +1282,7 @@ STACK_OF(type) \ #define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) #define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) -#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) #define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) #define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) #define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) @@ -1118,7 +1304,7 @@ STACK_OF(type) \ #define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) #define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) -#define sk_PKCS12_SAFEBAG_new(st) SKM_sk_new(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) #define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) #define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) #define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) @@ -1140,7 +1326,7 @@ STACK_OF(type) \ #define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) #define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) -#define sk_PKCS7_new(st) SKM_sk_new(PKCS7, (st)) +#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) #define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) #define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) #define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) @@ -1162,7 +1348,7 @@ STACK_OF(type) \ #define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) #define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) -#define sk_PKCS7_RECIP_INFO_new(st) SKM_sk_new(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) #define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) #define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) #define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) @@ -1184,7 +1370,7 @@ STACK_OF(type) \ #define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) #define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) -#define sk_PKCS7_SIGNER_INFO_new(st) SKM_sk_new(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) #define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) #define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) #define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) @@ -1206,7 +1392,7 @@ STACK_OF(type) \ #define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) #define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) -#define sk_POLICYINFO_new(st) SKM_sk_new(POLICYINFO, (st)) +#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) #define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) #define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) #define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) @@ -1228,7 +1414,7 @@ STACK_OF(type) \ #define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) #define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) -#define sk_POLICYQUALINFO_new(st) SKM_sk_new(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) #define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) #define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) #define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) @@ -1250,7 +1436,7 @@ STACK_OF(type) \ #define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) #define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) -#define sk_POLICY_MAPPING_new(st) SKM_sk_new(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) #define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) #define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) #define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) @@ -1272,7 +1458,7 @@ STACK_OF(type) \ #define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) #define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) -#define sk_SSL_CIPHER_new(st) SKM_sk_new(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) #define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) #define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) #define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) @@ -1294,7 +1480,7 @@ STACK_OF(type) \ #define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) #define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) -#define sk_SSL_COMP_new(st) SKM_sk_new(SSL_COMP, (st)) +#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) #define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) #define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) #define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) @@ -1316,7 +1502,51 @@ STACK_OF(type) \ #define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) #define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) -#define sk_STORE_OBJECT_new(st) SKM_sk_new(STORE_OBJECT, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) + +#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) + +#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) #define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) #define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) #define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) @@ -1338,7 +1568,7 @@ STACK_OF(type) \ #define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) #define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) -#define sk_SXNETID_new(st) SKM_sk_new(SXNETID, (st)) +#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) #define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) #define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) #define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) @@ -1360,7 +1590,7 @@ STACK_OF(type) \ #define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) #define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) -#define sk_UI_STRING_new(st) SKM_sk_new(UI_STRING, (st)) +#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) #define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) #define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) #define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) @@ -1382,7 +1612,7 @@ STACK_OF(type) \ #define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) #define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) -#define sk_X509_new(st) SKM_sk_new(X509, (st)) +#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) #define sk_X509_new_null() SKM_sk_new_null(X509) #define sk_X509_free(st) SKM_sk_free(X509, (st)) #define sk_X509_num(st) SKM_sk_num(X509, (st)) @@ -1404,7 +1634,7 @@ STACK_OF(type) \ #define sk_X509_sort(st) SKM_sk_sort(X509, (st)) #define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) -#define sk_X509V3_EXT_METHOD_new(st) SKM_sk_new(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) #define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) #define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) #define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) @@ -1426,7 +1656,7 @@ STACK_OF(type) \ #define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) #define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) -#define sk_X509_ALGOR_new(st) SKM_sk_new(X509_ALGOR, (st)) +#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) #define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) #define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) #define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) @@ -1448,7 +1678,7 @@ STACK_OF(type) \ #define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) #define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) -#define sk_X509_ATTRIBUTE_new(st) SKM_sk_new(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) #define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) #define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) #define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) @@ -1470,7 +1700,7 @@ STACK_OF(type) \ #define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) #define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) -#define sk_X509_CRL_new(st) SKM_sk_new(X509_CRL, (st)) +#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) #define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) #define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) #define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) @@ -1492,7 +1722,7 @@ STACK_OF(type) \ #define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) #define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) -#define sk_X509_EXTENSION_new(st) SKM_sk_new(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) #define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) #define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) #define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) @@ -1514,7 +1744,7 @@ STACK_OF(type) \ #define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) #define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) -#define sk_X509_INFO_new(st) SKM_sk_new(X509_INFO, (st)) +#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) #define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) #define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) #define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) @@ -1536,7 +1766,7 @@ STACK_OF(type) \ #define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) #define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) -#define sk_X509_LOOKUP_new(st) SKM_sk_new(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) #define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) #define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) #define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) @@ -1558,7 +1788,7 @@ STACK_OF(type) \ #define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) #define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) -#define sk_X509_NAME_new(st) SKM_sk_new(X509_NAME, (st)) +#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) #define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) #define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) #define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) @@ -1580,7 +1810,7 @@ STACK_OF(type) \ #define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) #define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) -#define sk_X509_NAME_ENTRY_new(st) SKM_sk_new(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) #define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) #define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) #define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) @@ -1602,7 +1832,7 @@ STACK_OF(type) \ #define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) #define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) -#define sk_X509_OBJECT_new(st) SKM_sk_new(X509_OBJECT, (st)) +#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) #define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) #define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) #define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) @@ -1624,7 +1854,7 @@ STACK_OF(type) \ #define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) #define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) -#define sk_X509_POLICY_DATA_new(st) SKM_sk_new(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) #define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) #define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) #define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) @@ -1646,7 +1876,7 @@ STACK_OF(type) \ #define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) #define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) -#define sk_X509_POLICY_NODE_new(st) SKM_sk_new(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) #define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) #define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) #define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) @@ -1668,29 +1898,7 @@ STACK_OF(type) \ #define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) #define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_REF_new(st) SKM_sk_new(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_new_null() SKM_sk_new_null(X509_POLICY_REF) -#define sk_X509_POLICY_REF_free(st) SKM_sk_free(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_num(st) SKM_sk_num(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_value(st, i) SKM_sk_value(X509_POLICY_REF, (st), (i)) -#define sk_X509_POLICY_REF_set(st, i, val) SKM_sk_set(X509_POLICY_REF, (st), (i), (val)) -#define sk_X509_POLICY_REF_zero(st) SKM_sk_zero(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_push(st, val) SKM_sk_push(X509_POLICY_REF, (st), (val)) -#define sk_X509_POLICY_REF_unshift(st, val) SKM_sk_unshift(X509_POLICY_REF, (st), (val)) -#define sk_X509_POLICY_REF_find(st, val) SKM_sk_find(X509_POLICY_REF, (st), (val)) -#define sk_X509_POLICY_REF_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_REF, (st), (val)) -#define sk_X509_POLICY_REF_delete(st, i) SKM_sk_delete(X509_POLICY_REF, (st), (i)) -#define sk_X509_POLICY_REF_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_REF, (st), (ptr)) -#define sk_X509_POLICY_REF_insert(st, val, i) SKM_sk_insert(X509_POLICY_REF, (st), (val), (i)) -#define sk_X509_POLICY_REF_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_REF, (st), (cmp)) -#define sk_X509_POLICY_REF_dup(st) SKM_sk_dup(X509_POLICY_REF, st) -#define sk_X509_POLICY_REF_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_REF, (st), (free_func)) -#define sk_X509_POLICY_REF_shift(st) SKM_sk_shift(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_pop(st) SKM_sk_pop(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_sort(st) SKM_sk_sort(X509_POLICY_REF, (st)) -#define sk_X509_POLICY_REF_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_REF, (st)) - -#define sk_X509_PURPOSE_new(st) SKM_sk_new(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) #define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) #define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) #define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) @@ -1712,7 +1920,7 @@ STACK_OF(type) \ #define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) #define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) -#define sk_X509_REVOKED_new(st) SKM_sk_new(X509_REVOKED, (st)) +#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) #define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) #define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) #define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) @@ -1734,7 +1942,7 @@ STACK_OF(type) \ #define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) #define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) -#define sk_X509_TRUST_new(st) SKM_sk_new(X509_TRUST, (st)) +#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) #define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) #define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) #define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) @@ -1756,7 +1964,7 @@ STACK_OF(type) \ #define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) #define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) -#define sk_X509_VERIFY_PARAM_new(st) SKM_sk_new(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) #define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) #define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) #define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) @@ -1778,6 +1986,125 @@ STACK_OF(type) \ #define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) #define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) +#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) +#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) +#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) +#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) +#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) +#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) +#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) +#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) +#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) +#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) +#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) +#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) +#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) +#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) +#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) +#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) +#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) +#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) +#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) +#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) +#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) + +#define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +#define sk_void_new_null() SKM_sk_new_null(void) +#define sk_void_free(st) SKM_sk_free(void, (st)) +#define sk_void_num(st) SKM_sk_num(void, (st)) +#define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +#define sk_void_zero(st) SKM_sk_zero(void, (st)) +#define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +#define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +#define sk_void_dup(st) SKM_sk_dup(void, st) +#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +#define sk_void_shift(st) SKM_sk_shift(void, (st)) +#define sk_void_pop(st) SKM_sk_pop(void, (st)) +#define sk_void_sort(st) SKM_sk_sort(void, (st)) +#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) + +#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) +#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) +#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i)) +#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func)) +#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val), i) +#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i, CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) +#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, ptr)) +#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ + ((int (*)(const void * const *,const void * const *)) \ + sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_CMP_FUNC(void, cmp))) +#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st)) +#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) + + +#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i)) +#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func)) +#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st)) +#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) + + +#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i)) +#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func)) +#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val), i) +#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i, CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, ptr)) +#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st)) +#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) + + #define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) #define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ @@ -1814,6 +2141,15 @@ STACK_OF(type) \ #define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) +#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) + #define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) #define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ @@ -1823,6 +2159,24 @@ STACK_OF(type) \ #define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) +#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) + #define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) #define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ @@ -1981,6 +2335,240 @@ STACK_OF(type) \ #define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) + +#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) + +#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) +#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) +#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) +#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) +#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) +#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) +#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) +#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) +#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) +#define lh_APP_INFO_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_stats_bio(lh,out) \ + LHM_lh_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) + +#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +#define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) + +#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) +#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) +#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) +#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) + +#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +#define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) + +#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) + +#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) + +#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +#define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) + +#define lh_MEM_new() LHM_lh_new(MEM,mem) +#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) +#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) +#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) +#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) +#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) +#define lh_MEM_error(lh) LHM_lh_error(MEM,lh) +#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) +#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) +#define lh_MEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(MEM,lh,out) +#define lh_MEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(MEM,lh,out) +#define lh_MEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(MEM,lh,out) +#define lh_MEM_free(lh) LHM_lh_free(MEM,lh) + +#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +#define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) + +#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) +#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) +#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) + +#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) + +#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +#define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) /* End of util/mkstack.pl block, you may now edit :-) */ #endif /* !defined HEADER_SAFESTACK_H */ diff --git a/crypto/openssl/crypto/stack/stack.c b/crypto/openssl/crypto/stack/stack.c index 378bd7c796..76cf1a1168 100644 --- a/crypto/openssl/crypto/stack/stack.c +++ b/crypto/openssl/crypto/stack/stack.c @@ -77,10 +77,10 @@ const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT; #include -int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * const *))) - (const char * const *, const char * const *) +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *))) + (const void *, const void *) { - int (*old)(const char * const *,const char * const *)=sk->comp; + int (*old)(const void *,const void *)=sk->comp; if (sk->comp != c) sk->sorted=0; @@ -89,9 +89,9 @@ int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * cons return old; } -STACK *sk_dup(STACK *sk) +_STACK *sk_dup(_STACK *sk) { - STACK *ret; + _STACK *ret; char **s; if ((ret=sk_new(sk->comp)) == NULL) goto err; @@ -112,19 +112,19 @@ err: return(NULL); } -STACK *sk_new_null(void) +_STACK *sk_new_null(void) { - return sk_new((int (*)(const char * const *, const char * const *))0); + return sk_new((int (*)(const void *, const void *))0); } -STACK *sk_new(int (*c)(const char * const *, const char * const *)) +_STACK *sk_new(int (*c)(const void *, const void *)) { - STACK *ret; + _STACK *ret; int i; - if ((ret=(STACK *)OPENSSL_malloc(sizeof(STACK))) == NULL) + if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL) goto err; - if ((ret->data=(char **)OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL) + if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL) goto err; for (i=0; idata[i]=NULL; @@ -139,14 +139,14 @@ err: return(NULL); } -int sk_insert(STACK *st, char *data, int loc) +int sk_insert(_STACK *st, void *data, int loc) { char **s; if(st == NULL) return 0; if (st->num_alloc <= st->num+1) { - s=(char **)OPENSSL_realloc((char *)st->data, + s=OPENSSL_realloc((char *)st->data, (unsigned int)sizeof(char *)*st->num_alloc*2); if (s == NULL) return(0); @@ -160,14 +160,14 @@ int sk_insert(STACK *st, char *data, int loc) int i; char **f,**t; - f=(char **)st->data; - t=(char **)&(st->data[1]); + f=st->data; + t=&(st->data[1]); for (i=st->num; i>=loc; i--) t[i]=f[i]; #ifdef undef /* no memmove on sunos :-( */ - memmove( (char *)&(st->data[loc+1]), - (char *)&(st->data[loc]), + memmove(&(st->data[loc+1]), + &(st->data[loc]), sizeof(char *)*(st->num-loc)); #endif st->data[loc]=data; @@ -177,7 +177,7 @@ int sk_insert(STACK *st, char *data, int loc) return(st->num); } -char *sk_delete_ptr(STACK *st, char *p) +void *sk_delete_ptr(_STACK *st, void *p) { int i; @@ -187,7 +187,7 @@ char *sk_delete_ptr(STACK *st, char *p) return(NULL); } -char *sk_delete(STACK *st, int loc) +void *sk_delete(_STACK *st, int loc) { char *ret; int i,j; @@ -210,11 +210,11 @@ char *sk_delete(STACK *st, int loc) return(ret); } -static int internal_find(STACK *st, char *data, int ret_val_options) +static int internal_find(_STACK *st, void *data, int ret_val_options) { - char **r; + const void * const *r; int i; - int (*comp_func)(const void *,const void *); + if(st == NULL) return -1; if (st->comp == NULL) @@ -226,53 +226,46 @@ static int internal_find(STACK *st, char *data, int ret_val_options) } sk_sort(st); if (data == NULL) return(-1); - /* This (and the "qsort" below) are the two places in OpenSSL - * where we need to convert from our standard (type **,type **) - * compare callback type to the (void *,void *) type required by - * bsearch. However, the "data" it is being called(back) with are - * not (type *) pointers, but the *pointers* to (type *) pointers, - * so we get our extra level of pointer dereferencing that way. */ - comp_func=(int (*)(const void *,const void *))(st->comp); - r=(char **)OBJ_bsearch_ex((char *)&data,(char *)st->data, - st->num,sizeof(char *),comp_func,ret_val_options); + r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp, + ret_val_options); if (r == NULL) return(-1); - return((int)(r-st->data)); + return (int)((char **)r-st->data); } -int sk_find(STACK *st, char *data) +int sk_find(_STACK *st, void *data) { return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); } -int sk_find_ex(STACK *st, char *data) +int sk_find_ex(_STACK *st, void *data) { return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); } -int sk_push(STACK *st, char *data) +int sk_push(_STACK *st, void *data) { return(sk_insert(st,data,st->num)); } -int sk_unshift(STACK *st, char *data) +int sk_unshift(_STACK *st, void *data) { return(sk_insert(st,data,0)); } -char *sk_shift(STACK *st) +void *sk_shift(_STACK *st) { if (st == NULL) return(NULL); if (st->num <= 0) return(NULL); return(sk_delete(st,0)); } -char *sk_pop(STACK *st) +void *sk_pop(_STACK *st) { if (st == NULL) return(NULL); if (st->num <= 0) return(NULL); return(sk_delete(st,st->num-1)); } -void sk_zero(STACK *st) +void sk_zero(_STACK *st) { if (st == NULL) return; if (st->num <= 0) return; @@ -280,7 +273,7 @@ void sk_zero(STACK *st) st->num=0; } -void sk_pop_free(STACK *st, void (*func)(void *)) +void sk_pop_free(_STACK *st, void (*func)(void *)) { int i; @@ -291,32 +284,32 @@ void sk_pop_free(STACK *st, void (*func)(void *)) sk_free(st); } -void sk_free(STACK *st) +void sk_free(_STACK *st) { if (st == NULL) return; if (st->data != NULL) OPENSSL_free(st->data); OPENSSL_free(st); } -int sk_num(const STACK *st) +int sk_num(const _STACK *st) { if(st == NULL) return -1; return st->num; } -char *sk_value(const STACK *st, int i) +void *sk_value(const _STACK *st, int i) { if(!st || (i < 0) || (i >= st->num)) return NULL; return st->data[i]; } -char *sk_set(STACK *st, int i, char *value) +void *sk_set(_STACK *st, int i, void *value) { if(!st || (i < 0) || (i >= st->num)) return NULL; return (st->data[i] = value); } -void sk_sort(STACK *st) +void sk_sort(_STACK *st) { if (st && !st->sorted) { @@ -333,7 +326,7 @@ void sk_sort(STACK *st) } } -int sk_is_sorted(const STACK *st) +int sk_is_sorted(const _STACK *st) { if (!st) return 1; diff --git a/crypto/openssl/crypto/stack/stack.h b/crypto/openssl/crypto/stack/stack.h index 5cbb116a8b..ce35e554eb 100644 --- a/crypto/openssl/crypto/stack/stack.h +++ b/crypto/openssl/crypto/stack/stack.h @@ -70,37 +70,36 @@ typedef struct stack_st int sorted; int num_alloc; - int (*comp)(const char * const *, const char * const *); - } STACK; + int (*comp)(const void *, const void *); + } _STACK; /* Use STACK_OF(...) instead */ #define M_sk_num(sk) ((sk) ? (sk)->num:-1) #define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) -int sk_num(const STACK *); -char *sk_value(const STACK *, int); +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); -char *sk_set(STACK *, int, char *); +void *sk_set(_STACK *, int, void *); -STACK *sk_new(int (*cmp)(const char * const *, const char * const *)); -STACK *sk_new_null(void); -void sk_free(STACK *); -void sk_pop_free(STACK *st, void (*func)(void *)); -int sk_insert(STACK *sk,char *data,int where); -char *sk_delete(STACK *st,int loc); -char *sk_delete_ptr(STACK *st, char *p); -int sk_find(STACK *st,char *data); -int sk_find_ex(STACK *st,char *data); -int sk_push(STACK *st,char *data); -int sk_unshift(STACK *st,char *data); -char *sk_shift(STACK *st); -char *sk_pop(STACK *st); -void sk_zero(STACK *st); -int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *, - const char * const *))) - (const char * const *, const char * const *); -STACK *sk_dup(STACK *st); -void sk_sort(STACK *st); -int sk_is_sorted(const STACK *st); +_STACK *sk_new(int (*cmp)(const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func)(void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *))) + (const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/store/README b/crypto/openssl/crypto/store/README deleted file mode 100644 index 966168f6a5..0000000000 --- a/crypto/openssl/crypto/store/README +++ /dev/null @@ -1,95 +0,0 @@ -The STORE type -============== - -A STORE, as defined in this code section, is really a rather simple -thing which stores objects and per-object associations to a number -of attributes. What attributes are supported entirely depends on -the particular implementation of a STORE. It has some support for -generation of certain objects (for example, keys and CRLs). - - -Supported object types ----------------------- - -For now, the objects that are supported are the following: - -X.509 certificate -X.509 CRL -private key -public key -number -arbitrary (application) data - -The intention is that a STORE should be able to store everything -needed by an application that wants a cert/key store, as well as -the data a CA might need to store (this includes the serial number -counter, which explains the support for numbers). - - -Supported attribute types -------------------------- - -For now, the following attributes are supported: - -Friendly Name - the value is a normal C string -Key ID - the value is a 160 bit SHA1 hash -Issuer Key ID - the value is a 160 bit SHA1 hash -Subject Key ID - the value is a 160 bit SHA1 hash -Issuer/Serial Hash - the value is a 160 bit SHA1 hash -Issuer - the value is a X509_NAME -Serial - the value is a BIGNUM -Subject - the value is a X509_NAME -Certificate Hash - the value is a 160 bit SHA1 hash -Email - the value is a normal C string -Filename - the value is a normal C string - -It is expected that these attributes should be enough to support -the need from most, if not all, current applications. Applications -that need to do certificate verification would typically use Subject -Key ID, Issuer/Serial Hash or Subject to look up issuer certificates. -S/MIME applications would typically use Email to look up recipient -and signer certificates. - -There's added support for combined sets of attributes to search for, -with the special OR attribute. - - -Supported basic functionality ------------------------------ - -The functions that are supported through the STORE type are these: - -generate_object - for example to generate keys and CRLs -get_object - to look up one object - NOTE: this function is really rather - redundant and probably of lesser usage - than the list functions -store_object - store an object and the attributes - associated with it -modify_object - modify the attributes associated with - a specific object -revoke_object - revoke an object - NOTE: this only marks an object as - invalid, it doesn't remove the object - from the database -delete_object - remove an object from the database -list_object - list objects associated with a given - set of attributes - NOTE: this is really four functions: - list_start, list_next, list_end and - list_endp -update_store - update the internal data of the store -lock_store - lock the store -unlock_store - unlock the store - -The list functions need some extra explanation: list_start is -used to set up a lookup. That's where the attributes to use in -the search are set up. It returns a search context. list_next -returns the next object searched for. list_end closes the search. -list_endp is used to check if we have reached the end. - -A few words on the store functions as well: update_store is -typically used by a CA application to update the internal -structure of a database. This may for example involve automatic -removal of expired certificates. lock_store and unlock_store -are used for locking a store to allow exclusive writes. diff --git a/crypto/openssl/crypto/store/store.h b/crypto/openssl/crypto/store/store.h deleted file mode 100644 index 64583377a9..0000000000 --- a/crypto/openssl/crypto/store/store.h +++ /dev/null @@ -1,554 +0,0 @@ -/* crypto/store/store.h -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 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). - * - */ - -#ifndef HEADER_STORE_H -#define HEADER_STORE_H - -#include -#ifndef OPENSSL_NO_DEPRECATED -#include -#include -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Already defined in ossl_typ.h */ -/* typedef struct store_st STORE; */ -/* typedef struct store_method_st STORE_METHOD; */ - - -/* All the following functions return 0, a negative number or NULL on error. - When everything is fine, they return a positive value or a non-NULL - pointer, all depending on their purpose. */ - -/* Creators and destructor. */ -STORE *STORE_new_method(const STORE_METHOD *method); -STORE *STORE_new_engine(ENGINE *engine); -void STORE_free(STORE *ui); - - -/* Give a user interface parametrised control commands. This can be used to - send down an integer, a data pointer or a function pointer, as well as - be used to get information from a STORE. */ -int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void)); - -/* A control to set the directory with keys and certificates. Used by the - built-in directory level method. */ -#define STORE_CTRL_SET_DIRECTORY 0x0001 -/* A control to set a file to load. Used by the built-in file level method. */ -#define STORE_CTRL_SET_FILE 0x0002 -/* A control to set a configuration file to load. Can be used by any method - that wishes to load a configuration file. */ -#define STORE_CTRL_SET_CONF_FILE 0x0003 -/* A control to set a the section of the loaded configuration file. Can be - used by any method that wishes to load a configuration file. */ -#define STORE_CTRL_SET_CONF_SECTION 0x0004 - - -/* Some methods may use extra data */ -#define STORE_set_app_data(s,arg) STORE_set_ex_data(s,0,arg) -#define STORE_get_app_data(s) STORE_get_ex_data(s,0) -int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int STORE_set_ex_data(STORE *r,int idx,void *arg); -void *STORE_get_ex_data(STORE *r, int idx); - -/* Use specific methods instead of the built-in one */ -const STORE_METHOD *STORE_get_method(STORE *store); -const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth); - -/* The standard OpenSSL methods. */ -/* This is the in-memory method. It does everything except revoking and updating, - and is of course volatile. It's used by other methods that have an in-memory - cache. */ -const STORE_METHOD *STORE_Memory(void); -#if 0 /* Not yet implemented */ -/* This is the directory store. It does everything except revoking and updating, - and uses STORE_Memory() to cache things in memory. */ -const STORE_METHOD *STORE_Directory(void); -/* This is the file store. It does everything except revoking and updating, - and uses STORE_Memory() to cache things in memory. Certificates are added - to it with the store operation, and it will only get cached certificates. */ -const STORE_METHOD *STORE_File(void); -#endif - -/* Store functions take a type code for the type of data they should store - or fetch */ -typedef enum STORE_object_types - { - STORE_OBJECT_TYPE_X509_CERTIFICATE= 0x01, /* X509 * */ - STORE_OBJECT_TYPE_X509_CRL= 0x02, /* X509_CRL * */ - STORE_OBJECT_TYPE_PRIVATE_KEY= 0x03, /* EVP_PKEY * */ - STORE_OBJECT_TYPE_PUBLIC_KEY= 0x04, /* EVP_PKEY * */ - STORE_OBJECT_TYPE_NUMBER= 0x05, /* BIGNUM * */ - STORE_OBJECT_TYPE_ARBITRARY= 0x06, /* BUF_MEM * */ - STORE_OBJECT_TYPE_NUM= 0x06 /* The amount of known - object types */ - } STORE_OBJECT_TYPES; -/* List of text strings corresponding to the object types. */ -extern const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1]; - -/* Some store functions take a parameter list. Those parameters come with - one of the following codes. The comments following the codes below indicate - what type the value should be a pointer to. */ -typedef enum STORE_params - { - STORE_PARAM_EVP_TYPE= 0x01, /* int */ - STORE_PARAM_BITS= 0x02, /* size_t */ - STORE_PARAM_KEY_PARAMETERS= 0x03, /* ??? */ - STORE_PARAM_KEY_NO_PARAMETERS= 0x04, /* N/A */ - STORE_PARAM_AUTH_PASSPHRASE= 0x05, /* char * */ - STORE_PARAM_AUTH_KRB5_TICKET= 0x06, /* void * */ - STORE_PARAM_TYPE_NUM= 0x06 /* The amount of known - parameter types */ - } STORE_PARAM_TYPES; -/* Parameter value sizes. -1 means unknown, anything else is the required size. */ -extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1]; - -/* Store functions take attribute lists. Those attributes come with codes. - The comments following the codes below indicate what type the value should - be a pointer to. */ -typedef enum STORE_attribs - { - STORE_ATTR_END= 0x00, - STORE_ATTR_FRIENDLYNAME= 0x01, /* C string */ - STORE_ATTR_KEYID= 0x02, /* 160 bit string (SHA1) */ - STORE_ATTR_ISSUERKEYID= 0x03, /* 160 bit string (SHA1) */ - STORE_ATTR_SUBJECTKEYID= 0x04, /* 160 bit string (SHA1) */ - STORE_ATTR_ISSUERSERIALHASH= 0x05, /* 160 bit string (SHA1) */ - STORE_ATTR_ISSUER= 0x06, /* X509_NAME * */ - STORE_ATTR_SERIAL= 0x07, /* BIGNUM * */ - STORE_ATTR_SUBJECT= 0x08, /* X509_NAME * */ - STORE_ATTR_CERTHASH= 0x09, /* 160 bit string (SHA1) */ - STORE_ATTR_EMAIL= 0x0a, /* C string */ - STORE_ATTR_FILENAME= 0x0b, /* C string */ - STORE_ATTR_TYPE_NUM= 0x0b, /* The amount of known - attribute types */ - STORE_ATTR_OR= 0xff /* This is a special - separator, which - expresses the OR - operation. */ - } STORE_ATTR_TYPES; -/* Attribute value sizes. -1 means unknown, anything else is the required size. */ -extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1]; - -typedef enum STORE_certificate_status - { - STORE_X509_VALID= 0x00, - STORE_X509_EXPIRED= 0x01, - STORE_X509_SUSPENDED= 0x02, - STORE_X509_REVOKED= 0x03 - } STORE_CERTIFICATE_STATUS; - -/* Engine store functions will return a structure that contains all the necessary - * information, including revokation status for certificates. This is really not - * needed for application authors, as the ENGINE framework functions will extract - * the OpenSSL-specific information when at all possible. However, for engine - * authors, it's crucial to know this structure. */ -typedef struct STORE_OBJECT_st - { - STORE_OBJECT_TYPES type; - union - { - struct - { - STORE_CERTIFICATE_STATUS status; - X509 *certificate; - } x509; - X509_CRL *crl; - EVP_PKEY *key; - BIGNUM *number; - BUF_MEM *arbitrary; - } data; - } STORE_OBJECT; -DECLARE_STACK_OF(STORE_OBJECT) -STORE_OBJECT *STORE_OBJECT_new(void); -void STORE_OBJECT_free(STORE_OBJECT *data); - - - -/* The following functions handle the storage. They return 0, a negative number - or NULL on error, anything else on success. */ -X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -X509 *STORE_list_certificate_next(STORE *e, void *handle); -int STORE_list_certificate_end(STORE *e, void *handle); -int STORE_list_certificate_endp(STORE *e, void *handle); -EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_store_private_key(STORE *e, EVP_PKEY *data, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle); -int STORE_list_private_key_end(STORE *e, void *handle); -int STORE_list_private_key_endp(STORE *e, void *handle); -EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_store_public_key(STORE *e, EVP_PKEY *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle); -int STORE_list_public_key_end(STORE *e, void *handle); -int STORE_list_public_key_endp(STORE *e, void *handle); -X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -X509_CRL *STORE_list_crl_next(STORE *e, void *handle); -int STORE_list_crl_end(STORE *e, void *handle); -int STORE_list_crl_endp(STORE *e, void *handle); -int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); - - -/* Create and manipulate methods */ -STORE_METHOD *STORE_create_method(char *name); -void STORE_destroy_method(STORE_METHOD *store_method); - -/* These callback types are use for store handlers */ -typedef int (*STORE_INITIALISE_FUNC_PTR)(STORE *); -typedef void (*STORE_CLEANUP_FUNC_PTR)(STORE *); -typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle); -typedef int (*STORE_END_OBJECT_FUNC_PTR)(STORE *, void *handle); -typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -typedef int (*STORE_STORE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, STORE_OBJECT *data, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]); -typedef int (*STORE_GENERIC_FUNC_PTR)(STORE *, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -typedef int (*STORE_CTRL_FUNC_PTR)(STORE *, int cmd, long l, void *p, void (*f)(void)); - -int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f); -int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f); -int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f); -int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f); -int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f); -int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR store_f); -int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f); -int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f); -int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f); -int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f); -int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f); -int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR); -int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR); -int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR); -int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f); - -STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm); -STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm); -STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm); -STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm); -STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm); -STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm); -STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm); -STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm); -STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm); -STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm); -STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm); -STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm); -STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm); -STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm); -STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm); - -/* Method helper structures and functions. */ - -/* This structure is the result of parsing through the information in a list - of OPENSSL_ITEMs. It stores all the necessary information in a structured - way.*/ -typedef struct STORE_attr_info_st STORE_ATTR_INFO; - -/* Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO. - Note that we do this in the list form, since the list of OPENSSL_ITEMs can - come in blocks separated with STORE_ATTR_OR. Note that the value returned - by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). */ -void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes); -STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle); -int STORE_parse_attrs_end(void *handle); -int STORE_parse_attrs_endp(void *handle); - -/* Creator and destructor */ -STORE_ATTR_INFO *STORE_ATTR_INFO_new(void); -int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs); - -/* Manipulators */ -char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code); -unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs, - STORE_ATTR_TYPES code); -X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code); -BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code); -int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - char *cstr, size_t cstr_size); -int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - unsigned char *sha1str, size_t sha1str_size); -int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - X509_NAME *dn); -int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - BIGNUM *number); -int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - char *cstr, size_t cstr_size); -int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - unsigned char *sha1str, size_t sha1str_size); -int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - X509_NAME *dn); -int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - BIGNUM *number); - -/* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values - in each contained attribute. */ -int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); -/* Check if the set of attributes in a is within the range of attributes - set in b. */ -int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); -/* Check if the set of attributes in a are also set in b. */ -int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); -/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */ -int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); - - -/* BEGIN ERROR CODES */ -/* The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_STORE_strings(void); - -/* Error codes for the STORE functions. */ - -/* Function codes. */ -#define STORE_F_MEM_DELETE 134 -#define STORE_F_MEM_GENERATE 135 -#define STORE_F_MEM_LIST_END 168 -#define STORE_F_MEM_LIST_NEXT 136 -#define STORE_F_MEM_LIST_START 137 -#define STORE_F_MEM_MODIFY 169 -#define STORE_F_MEM_STORE 138 -#define STORE_F_STORE_ATTR_INFO_GET0_CSTR 139 -#define STORE_F_STORE_ATTR_INFO_GET0_DN 140 -#define STORE_F_STORE_ATTR_INFO_GET0_NUMBER 141 -#define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR 142 -#define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR 143 -#define STORE_F_STORE_ATTR_INFO_MODIFY_DN 144 -#define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER 145 -#define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR 146 -#define STORE_F_STORE_ATTR_INFO_SET_CSTR 147 -#define STORE_F_STORE_ATTR_INFO_SET_DN 148 -#define STORE_F_STORE_ATTR_INFO_SET_NUMBER 149 -#define STORE_F_STORE_ATTR_INFO_SET_SHA1STR 150 -#define STORE_F_STORE_CERTIFICATE 170 -#define STORE_F_STORE_CTRL 161 -#define STORE_F_STORE_DELETE_ARBITRARY 158 -#define STORE_F_STORE_DELETE_CERTIFICATE 102 -#define STORE_F_STORE_DELETE_CRL 103 -#define STORE_F_STORE_DELETE_NUMBER 104 -#define STORE_F_STORE_DELETE_PRIVATE_KEY 105 -#define STORE_F_STORE_DELETE_PUBLIC_KEY 106 -#define STORE_F_STORE_GENERATE_CRL 107 -#define STORE_F_STORE_GENERATE_KEY 108 -#define STORE_F_STORE_GET_ARBITRARY 159 -#define STORE_F_STORE_GET_CERTIFICATE 109 -#define STORE_F_STORE_GET_CRL 110 -#define STORE_F_STORE_GET_NUMBER 111 -#define STORE_F_STORE_GET_PRIVATE_KEY 112 -#define STORE_F_STORE_GET_PUBLIC_KEY 113 -#define STORE_F_STORE_LIST_CERTIFICATE_END 114 -#define STORE_F_STORE_LIST_CERTIFICATE_ENDP 153 -#define STORE_F_STORE_LIST_CERTIFICATE_NEXT 115 -#define STORE_F_STORE_LIST_CERTIFICATE_START 116 -#define STORE_F_STORE_LIST_CRL_END 117 -#define STORE_F_STORE_LIST_CRL_ENDP 154 -#define STORE_F_STORE_LIST_CRL_NEXT 118 -#define STORE_F_STORE_LIST_CRL_START 119 -#define STORE_F_STORE_LIST_PRIVATE_KEY_END 120 -#define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP 155 -#define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT 121 -#define STORE_F_STORE_LIST_PRIVATE_KEY_START 122 -#define STORE_F_STORE_LIST_PUBLIC_KEY_END 123 -#define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP 156 -#define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT 124 -#define STORE_F_STORE_LIST_PUBLIC_KEY_START 125 -#define STORE_F_STORE_MODIFY_ARBITRARY 162 -#define STORE_F_STORE_MODIFY_CERTIFICATE 163 -#define STORE_F_STORE_MODIFY_CRL 164 -#define STORE_F_STORE_MODIFY_NUMBER 165 -#define STORE_F_STORE_MODIFY_PRIVATE_KEY 166 -#define STORE_F_STORE_MODIFY_PUBLIC_KEY 167 -#define STORE_F_STORE_NEW_ENGINE 133 -#define STORE_F_STORE_NEW_METHOD 132 -#define STORE_F_STORE_PARSE_ATTRS_END 151 -#define STORE_F_STORE_PARSE_ATTRS_ENDP 172 -#define STORE_F_STORE_PARSE_ATTRS_NEXT 152 -#define STORE_F_STORE_PARSE_ATTRS_START 171 -#define STORE_F_STORE_REVOKE_CERTIFICATE 129 -#define STORE_F_STORE_REVOKE_PRIVATE_KEY 130 -#define STORE_F_STORE_REVOKE_PUBLIC_KEY 131 -#define STORE_F_STORE_STORE_ARBITRARY 157 -#define STORE_F_STORE_STORE_CERTIFICATE 100 -#define STORE_F_STORE_STORE_CRL 101 -#define STORE_F_STORE_STORE_NUMBER 126 -#define STORE_F_STORE_STORE_PRIVATE_KEY 127 -#define STORE_F_STORE_STORE_PUBLIC_KEY 128 - -/* Reason codes. */ -#define STORE_R_ALREADY_HAS_A_VALUE 127 -#define STORE_R_FAILED_DELETING_ARBITRARY 132 -#define STORE_R_FAILED_DELETING_CERTIFICATE 100 -#define STORE_R_FAILED_DELETING_KEY 101 -#define STORE_R_FAILED_DELETING_NUMBER 102 -#define STORE_R_FAILED_GENERATING_CRL 103 -#define STORE_R_FAILED_GENERATING_KEY 104 -#define STORE_R_FAILED_GETTING_ARBITRARY 133 -#define STORE_R_FAILED_GETTING_CERTIFICATE 105 -#define STORE_R_FAILED_GETTING_KEY 106 -#define STORE_R_FAILED_GETTING_NUMBER 107 -#define STORE_R_FAILED_LISTING_CERTIFICATES 108 -#define STORE_R_FAILED_LISTING_KEYS 109 -#define STORE_R_FAILED_MODIFYING_ARBITRARY 138 -#define STORE_R_FAILED_MODIFYING_CERTIFICATE 139 -#define STORE_R_FAILED_MODIFYING_CRL 140 -#define STORE_R_FAILED_MODIFYING_NUMBER 141 -#define STORE_R_FAILED_MODIFYING_PRIVATE_KEY 142 -#define STORE_R_FAILED_MODIFYING_PUBLIC_KEY 143 -#define STORE_R_FAILED_REVOKING_CERTIFICATE 110 -#define STORE_R_FAILED_REVOKING_KEY 111 -#define STORE_R_FAILED_STORING_ARBITRARY 134 -#define STORE_R_FAILED_STORING_CERTIFICATE 112 -#define STORE_R_FAILED_STORING_KEY 113 -#define STORE_R_FAILED_STORING_NUMBER 114 -#define STORE_R_NOT_IMPLEMENTED 128 -#define STORE_R_NO_CONTROL_FUNCTION 144 -#define STORE_R_NO_DELETE_ARBITRARY_FUNCTION 135 -#define STORE_R_NO_DELETE_NUMBER_FUNCTION 115 -#define STORE_R_NO_DELETE_OBJECT_FUNCTION 116 -#define STORE_R_NO_GENERATE_CRL_FUNCTION 117 -#define STORE_R_NO_GENERATE_OBJECT_FUNCTION 118 -#define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION 136 -#define STORE_R_NO_GET_OBJECT_FUNCTION 119 -#define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION 120 -#define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION 131 -#define STORE_R_NO_LIST_OBJECT_END_FUNCTION 121 -#define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION 122 -#define STORE_R_NO_LIST_OBJECT_START_FUNCTION 123 -#define STORE_R_NO_MODIFY_OBJECT_FUNCTION 145 -#define STORE_R_NO_REVOKE_OBJECT_FUNCTION 124 -#define STORE_R_NO_STORE 129 -#define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION 137 -#define STORE_R_NO_STORE_OBJECT_FUNCTION 125 -#define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION 126 -#define STORE_R_NO_VALUE 130 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/crypto/openssl/crypto/store/str_err.c b/crypto/openssl/crypto/store/str_err.c deleted file mode 100644 index 6fee649822..0000000000 --- a/crypto/openssl/crypto/store/str_err.c +++ /dev/null @@ -1,211 +0,0 @@ -/* crypto/store/str_err.c */ -/* ==================================================================== - * Copyright (c) 1999-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). - * - */ - -/* NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include -#include - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -#define ERR_FUNC(func) ERR_PACK(ERR_LIB_STORE,func,0) -#define ERR_REASON(reason) ERR_PACK(ERR_LIB_STORE,0,reason) - -static ERR_STRING_DATA STORE_str_functs[]= - { -{ERR_FUNC(STORE_F_MEM_DELETE), "MEM_DELETE"}, -{ERR_FUNC(STORE_F_MEM_GENERATE), "MEM_GENERATE"}, -{ERR_FUNC(STORE_F_MEM_LIST_END), "MEM_LIST_END"}, -{ERR_FUNC(STORE_F_MEM_LIST_NEXT), "MEM_LIST_NEXT"}, -{ERR_FUNC(STORE_F_MEM_LIST_START), "MEM_LIST_START"}, -{ERR_FUNC(STORE_F_MEM_MODIFY), "MEM_MODIFY"}, -{ERR_FUNC(STORE_F_MEM_STORE), "MEM_STORE"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_CSTR), "STORE_ATTR_INFO_get0_cstr"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_DN), "STORE_ATTR_INFO_get0_dn"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_NUMBER), "STORE_ATTR_INFO_get0_number"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR), "STORE_ATTR_INFO_get0_sha1str"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR), "STORE_ATTR_INFO_modify_cstr"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_DN), "STORE_ATTR_INFO_modify_dn"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER), "STORE_ATTR_INFO_modify_number"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR), "STORE_ATTR_INFO_modify_sha1str"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_CSTR), "STORE_ATTR_INFO_set_cstr"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_DN), "STORE_ATTR_INFO_set_dn"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_NUMBER), "STORE_ATTR_INFO_set_number"}, -{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_SHA1STR), "STORE_ATTR_INFO_set_sha1str"}, -{ERR_FUNC(STORE_F_STORE_CERTIFICATE), "STORE_CERTIFICATE"}, -{ERR_FUNC(STORE_F_STORE_CTRL), "STORE_ctrl"}, -{ERR_FUNC(STORE_F_STORE_DELETE_ARBITRARY), "STORE_delete_arbitrary"}, -{ERR_FUNC(STORE_F_STORE_DELETE_CERTIFICATE), "STORE_delete_certificate"}, -{ERR_FUNC(STORE_F_STORE_DELETE_CRL), "STORE_delete_crl"}, -{ERR_FUNC(STORE_F_STORE_DELETE_NUMBER), "STORE_delete_number"}, -{ERR_FUNC(STORE_F_STORE_DELETE_PRIVATE_KEY), "STORE_delete_private_key"}, -{ERR_FUNC(STORE_F_STORE_DELETE_PUBLIC_KEY), "STORE_delete_public_key"}, -{ERR_FUNC(STORE_F_STORE_GENERATE_CRL), "STORE_generate_crl"}, -{ERR_FUNC(STORE_F_STORE_GENERATE_KEY), "STORE_generate_key"}, -{ERR_FUNC(STORE_F_STORE_GET_ARBITRARY), "STORE_get_arbitrary"}, -{ERR_FUNC(STORE_F_STORE_GET_CERTIFICATE), "STORE_get_certificate"}, -{ERR_FUNC(STORE_F_STORE_GET_CRL), "STORE_get_crl"}, -{ERR_FUNC(STORE_F_STORE_GET_NUMBER), "STORE_get_number"}, -{ERR_FUNC(STORE_F_STORE_GET_PRIVATE_KEY), "STORE_get_private_key"}, -{ERR_FUNC(STORE_F_STORE_GET_PUBLIC_KEY), "STORE_get_public_key"}, -{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_END), "STORE_list_certificate_end"}, -{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_ENDP), "STORE_list_certificate_endp"}, -{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_NEXT), "STORE_list_certificate_next"}, -{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_START), "STORE_list_certificate_start"}, -{ERR_FUNC(STORE_F_STORE_LIST_CRL_END), "STORE_list_crl_end"}, -{ERR_FUNC(STORE_F_STORE_LIST_CRL_ENDP), "STORE_list_crl_endp"}, -{ERR_FUNC(STORE_F_STORE_LIST_CRL_NEXT), "STORE_list_crl_next"}, -{ERR_FUNC(STORE_F_STORE_LIST_CRL_START), "STORE_list_crl_start"}, -{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_END), "STORE_list_private_key_end"}, -{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP), "STORE_list_private_key_endp"}, -{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT), "STORE_list_private_key_next"}, -{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_START), "STORE_list_private_key_start"}, -{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_END), "STORE_list_public_key_end"}, -{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP), "STORE_list_public_key_endp"}, -{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT), "STORE_list_public_key_next"}, -{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_START), "STORE_list_public_key_start"}, -{ERR_FUNC(STORE_F_STORE_MODIFY_ARBITRARY), "STORE_modify_arbitrary"}, -{ERR_FUNC(STORE_F_STORE_MODIFY_CERTIFICATE), "STORE_modify_certificate"}, -{ERR_FUNC(STORE_F_STORE_MODIFY_CRL), "STORE_modify_crl"}, -{ERR_FUNC(STORE_F_STORE_MODIFY_NUMBER), "STORE_modify_number"}, -{ERR_FUNC(STORE_F_STORE_MODIFY_PRIVATE_KEY), "STORE_modify_private_key"}, -{ERR_FUNC(STORE_F_STORE_MODIFY_PUBLIC_KEY), "STORE_modify_public_key"}, -{ERR_FUNC(STORE_F_STORE_NEW_ENGINE), "STORE_new_engine"}, -{ERR_FUNC(STORE_F_STORE_NEW_METHOD), "STORE_new_method"}, -{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_END), "STORE_parse_attrs_end"}, -{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_ENDP), "STORE_parse_attrs_endp"}, -{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_NEXT), "STORE_parse_attrs_next"}, -{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_START), "STORE_parse_attrs_start"}, -{ERR_FUNC(STORE_F_STORE_REVOKE_CERTIFICATE), "STORE_revoke_certificate"}, -{ERR_FUNC(STORE_F_STORE_REVOKE_PRIVATE_KEY), "STORE_revoke_private_key"}, -{ERR_FUNC(STORE_F_STORE_REVOKE_PUBLIC_KEY), "STORE_revoke_public_key"}, -{ERR_FUNC(STORE_F_STORE_STORE_ARBITRARY), "STORE_store_arbitrary"}, -{ERR_FUNC(STORE_F_STORE_STORE_CERTIFICATE), "STORE_store_certificate"}, -{ERR_FUNC(STORE_F_STORE_STORE_CRL), "STORE_store_crl"}, -{ERR_FUNC(STORE_F_STORE_STORE_NUMBER), "STORE_store_number"}, -{ERR_FUNC(STORE_F_STORE_STORE_PRIVATE_KEY), "STORE_store_private_key"}, -{ERR_FUNC(STORE_F_STORE_STORE_PUBLIC_KEY), "STORE_store_public_key"}, -{0,NULL} - }; - -static ERR_STRING_DATA STORE_str_reasons[]= - { -{ERR_REASON(STORE_R_ALREADY_HAS_A_VALUE) ,"already has a value"}, -{ERR_REASON(STORE_R_FAILED_DELETING_ARBITRARY),"failed deleting arbitrary"}, -{ERR_REASON(STORE_R_FAILED_DELETING_CERTIFICATE),"failed deleting certificate"}, -{ERR_REASON(STORE_R_FAILED_DELETING_KEY) ,"failed deleting key"}, -{ERR_REASON(STORE_R_FAILED_DELETING_NUMBER),"failed deleting number"}, -{ERR_REASON(STORE_R_FAILED_GENERATING_CRL),"failed generating crl"}, -{ERR_REASON(STORE_R_FAILED_GENERATING_KEY),"failed generating key"}, -{ERR_REASON(STORE_R_FAILED_GETTING_ARBITRARY),"failed getting arbitrary"}, -{ERR_REASON(STORE_R_FAILED_GETTING_CERTIFICATE),"failed getting certificate"}, -{ERR_REASON(STORE_R_FAILED_GETTING_KEY) ,"failed getting key"}, -{ERR_REASON(STORE_R_FAILED_GETTING_NUMBER),"failed getting number"}, -{ERR_REASON(STORE_R_FAILED_LISTING_CERTIFICATES),"failed listing certificates"}, -{ERR_REASON(STORE_R_FAILED_LISTING_KEYS) ,"failed listing keys"}, -{ERR_REASON(STORE_R_FAILED_MODIFYING_ARBITRARY),"failed modifying arbitrary"}, -{ERR_REASON(STORE_R_FAILED_MODIFYING_CERTIFICATE),"failed modifying certificate"}, -{ERR_REASON(STORE_R_FAILED_MODIFYING_CRL),"failed modifying crl"}, -{ERR_REASON(STORE_R_FAILED_MODIFYING_NUMBER),"failed modifying number"}, -{ERR_REASON(STORE_R_FAILED_MODIFYING_PRIVATE_KEY),"failed modifying private key"}, -{ERR_REASON(STORE_R_FAILED_MODIFYING_PUBLIC_KEY),"failed modifying public key"}, -{ERR_REASON(STORE_R_FAILED_REVOKING_CERTIFICATE),"failed revoking certificate"}, -{ERR_REASON(STORE_R_FAILED_REVOKING_KEY) ,"failed revoking key"}, -{ERR_REASON(STORE_R_FAILED_STORING_ARBITRARY),"failed storing arbitrary"}, -{ERR_REASON(STORE_R_FAILED_STORING_CERTIFICATE),"failed storing certificate"}, -{ERR_REASON(STORE_R_FAILED_STORING_KEY) ,"failed storing key"}, -{ERR_REASON(STORE_R_FAILED_STORING_NUMBER),"failed storing number"}, -{ERR_REASON(STORE_R_NOT_IMPLEMENTED) ,"not implemented"}, -{ERR_REASON(STORE_R_NO_CONTROL_FUNCTION) ,"no control function"}, -{ERR_REASON(STORE_R_NO_DELETE_ARBITRARY_FUNCTION),"no delete arbitrary function"}, -{ERR_REASON(STORE_R_NO_DELETE_NUMBER_FUNCTION),"no delete number function"}, -{ERR_REASON(STORE_R_NO_DELETE_OBJECT_FUNCTION),"no delete object function"}, -{ERR_REASON(STORE_R_NO_GENERATE_CRL_FUNCTION),"no generate crl function"}, -{ERR_REASON(STORE_R_NO_GENERATE_OBJECT_FUNCTION),"no generate object function"}, -{ERR_REASON(STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION),"no get object arbitrary function"}, -{ERR_REASON(STORE_R_NO_GET_OBJECT_FUNCTION),"no get object function"}, -{ERR_REASON(STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION),"no get object number function"}, -{ERR_REASON(STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION),"no list object endp function"}, -{ERR_REASON(STORE_R_NO_LIST_OBJECT_END_FUNCTION),"no list object end function"}, -{ERR_REASON(STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION),"no list object next function"}, -{ERR_REASON(STORE_R_NO_LIST_OBJECT_START_FUNCTION),"no list object start function"}, -{ERR_REASON(STORE_R_NO_MODIFY_OBJECT_FUNCTION),"no modify object function"}, -{ERR_REASON(STORE_R_NO_REVOKE_OBJECT_FUNCTION),"no revoke object function"}, -{ERR_REASON(STORE_R_NO_STORE) ,"no store"}, -{ERR_REASON(STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION),"no store object arbitrary function"}, -{ERR_REASON(STORE_R_NO_STORE_OBJECT_FUNCTION),"no store object function"}, -{ERR_REASON(STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION),"no store object number function"}, -{ERR_REASON(STORE_R_NO_VALUE) ,"no value"}, -{0,NULL} - }; - -#endif - -void ERR_load_STORE_strings(void) - { -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(STORE_str_functs[0].error) == NULL) - { - ERR_load_strings(0,STORE_str_functs); - ERR_load_strings(0,STORE_str_reasons); - } -#endif - } diff --git a/crypto/openssl/crypto/store/str_lib.c b/crypto/openssl/crypto/store/str_lib.c deleted file mode 100644 index 32ae5bd395..0000000000 --- a/crypto/openssl/crypto/store/str_lib.c +++ /dev/null @@ -1,1824 +0,0 @@ -/* crypto/store/str_lib.c -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 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 -#include -#include -#ifndef OPENSSL_NO_ENGINE -#include -#endif -#include -#include -#include "str_locl.h" - -const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1] = - { - 0, - "X.509 Certificate", - "X.509 CRL", - "Private Key", - "Public Key", - "Number", - "Arbitrary Data" - }; - -const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1] = - { - 0, - sizeof(int), /* EVP_TYPE */ - sizeof(size_t), /* BITS */ - -1, /* KEY_PARAMETERS */ - 0 /* KEY_NO_PARAMETERS */ - }; - -const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1] = - { - 0, - -1, /* FRIENDLYNAME: C string */ - SHA_DIGEST_LENGTH, /* KEYID: SHA1 digest, 160 bits */ - SHA_DIGEST_LENGTH, /* ISSUERKEYID: SHA1 digest, 160 bits */ - SHA_DIGEST_LENGTH, /* SUBJECTKEYID: SHA1 digest, 160 bits */ - SHA_DIGEST_LENGTH, /* ISSUERSERIALHASH: SHA1 digest, 160 bits */ - sizeof(X509_NAME *), /* ISSUER: X509_NAME * */ - sizeof(BIGNUM *), /* SERIAL: BIGNUM * */ - sizeof(X509_NAME *), /* SUBJECT: X509_NAME * */ - SHA_DIGEST_LENGTH, /* CERTHASH: SHA1 digest, 160 bits */ - -1, /* EMAIL: C string */ - -1, /* FILENAME: C string */ - }; - -STORE *STORE_new_method(const STORE_METHOD *method) - { - STORE *ret; - - if (method == NULL) - { - STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - ret=(STORE *)OPENSSL_malloc(sizeof(STORE)); - if (ret == NULL) - { - STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->meth=method; - - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data); - if (ret->meth->init && !ret->meth->init(ret)) - { - STORE_free(ret); - ret = NULL; - } - return ret; - } - -STORE *STORE_new_engine(ENGINE *engine) - { - STORE *ret = NULL; - ENGINE *e = engine; - const STORE_METHOD *meth = 0; - -#ifdef OPENSSL_NO_ENGINE - e = NULL; -#else - if (engine) - { - if (!ENGINE_init(engine)) - { - STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB); - return NULL; - } - e = engine; - } - else - { - STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if(e) - { - meth = ENGINE_get_STORE(e); - if(!meth) - { - STOREerr(STORE_F_STORE_NEW_ENGINE, - ERR_R_ENGINE_LIB); - ENGINE_finish(e); - return NULL; - } - } -#endif - - ret = STORE_new_method(meth); - if (ret == NULL) - { - STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_STORE_LIB); - return NULL; - } - - ret->engine = e; - - return(ret); - } - -void STORE_free(STORE *store) - { - if (store == NULL) - return; - if (store->meth->clean) - store->meth->clean(store); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data); - OPENSSL_free(store); - } - -int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void)) - { - if (store == NULL) - { - STOREerr(STORE_F_STORE_CTRL,ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (store->meth->ctrl) - return store->meth->ctrl(store, cmd, i, p, f); - STOREerr(STORE_F_STORE_CTRL,STORE_R_NO_CONTROL_FUNCTION); - return 0; - } - - -int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) - { - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp, - new_func, dup_func, free_func); - } - -int STORE_set_ex_data(STORE *r, int idx, void *arg) - { - return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); - } - -void *STORE_get_ex_data(STORE *r, int idx) - { - return(CRYPTO_get_ex_data(&r->ex_data,idx)); - } - -const STORE_METHOD *STORE_get_method(STORE *store) - { - return store->meth; - } - -const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth) - { - store->meth=meth; - return store->meth; - } - - -/* API helpers */ - -#define check_store(s,fncode,fnname,fnerrcode) \ - do \ - { \ - if ((s) == NULL || (s)->meth == NULL) \ - { \ - STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \ - return 0; \ - } \ - if ((s)->meth->fnname == NULL) \ - { \ - STOREerr((fncode), (fnerrcode)); \ - return 0; \ - } \ - } \ - while(0) - -/* API functions */ - -X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - X509 *x; - - check_store(s,STORE_F_STORE_GET_CERTIFICATE, - get_object,STORE_R_NO_GET_OBJECT_FUNCTION); - - object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, - attributes, parameters); - if (!object || !object->data.x509.certificate) - { - STOREerr(STORE_F_STORE_GET_CERTIFICATE, - STORE_R_FAILED_GETTING_CERTIFICATE); - return 0; - } - CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509); -#ifdef REF_PRINT - REF_PRINT("X509",data); -#endif - x = object->data.x509.certificate; - STORE_OBJECT_free(object); - return x; - } - -int STORE_store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - int i; - - check_store(s,STORE_F_STORE_CERTIFICATE, - store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); - - object = STORE_OBJECT_new(); - if (!object) - { - STOREerr(STORE_F_STORE_STORE_CERTIFICATE, - ERR_R_MALLOC_FAILURE); - return 0; - } - - CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509); -#ifdef REF_PRINT - REF_PRINT("X509",data); -#endif - object->data.x509.certificate = data; - - i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, - object, attributes, parameters); - - STORE_OBJECT_free(object); - - if (!i) - { - STOREerr(STORE_F_STORE_STORE_CERTIFICATE, - STORE_R_FAILED_STORING_CERTIFICATE); - return 0; - } - return 1; - } - -int STORE_modify_certificate(STORE *s, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_MODIFY_CERTIFICATE, - modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); - - if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, - search_attributes, add_attributes, modify_attributes, - delete_attributes, parameters)) - { - STOREerr(STORE_F_STORE_MODIFY_CERTIFICATE, - STORE_R_FAILED_MODIFYING_CERTIFICATE); - return 0; - } - return 1; - } - -int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_REVOKE_CERTIFICATE, - revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION); - - if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, - attributes, parameters)) - { - STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE, - STORE_R_FAILED_REVOKING_CERTIFICATE); - return 0; - } - return 1; - } - -int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_DELETE_CERTIFICATE, - delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); - - if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, - attributes, parameters)) - { - STOREerr(STORE_F_STORE_DELETE_CERTIFICATE, - STORE_R_FAILED_DELETING_CERTIFICATE); - return 0; - } - return 1; - } - -void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - void *handle; - - check_store(s,STORE_F_STORE_LIST_CERTIFICATE_START, - list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); - - handle = s->meth->list_object_start(s, - STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes, parameters); - if (!handle) - { - STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START, - STORE_R_FAILED_LISTING_CERTIFICATES); - return 0; - } - return handle; - } - -X509 *STORE_list_certificate_next(STORE *s, void *handle) - { - STORE_OBJECT *object; - X509 *x; - - check_store(s,STORE_F_STORE_LIST_CERTIFICATE_NEXT, - list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); - - object = s->meth->list_object_next(s, handle); - if (!object || !object->data.x509.certificate) - { - STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT, - STORE_R_FAILED_LISTING_CERTIFICATES); - return 0; - } - CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509); -#ifdef REF_PRINT - REF_PRINT("X509",data); -#endif - x = object->data.x509.certificate; - STORE_OBJECT_free(object); - return x; - } - -int STORE_list_certificate_end(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_CERTIFICATE_END, - list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); - - if (!s->meth->list_object_end(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END, - STORE_R_FAILED_LISTING_CERTIFICATES); - return 0; - } - return 1; - } - -int STORE_list_certificate_endp(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_CERTIFICATE_ENDP, - list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); - - if (!s->meth->list_object_endp(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP, - STORE_R_FAILED_LISTING_CERTIFICATES); - return 0; - } - return 1; - } - -EVP_PKEY *STORE_generate_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - EVP_PKEY *pkey; - - check_store(s,STORE_F_STORE_GENERATE_KEY, - generate_object,STORE_R_NO_GENERATE_OBJECT_FUNCTION); - - object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, - attributes, parameters); - if (!object || !object->data.key) - { - STOREerr(STORE_F_STORE_GENERATE_KEY, - STORE_R_FAILED_GENERATING_KEY); - return 0; - } - CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - pkey = object->data.key; - STORE_OBJECT_free(object); - return pkey; - } - -EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - EVP_PKEY *pkey; - - check_store(s,STORE_F_STORE_GET_PRIVATE_KEY, - get_object,STORE_R_NO_GET_OBJECT_FUNCTION); - - object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, - attributes, parameters); - if (!object || !object->data.key || !object->data.key) - { - STOREerr(STORE_F_STORE_GET_PRIVATE_KEY, - STORE_R_FAILED_GETTING_KEY); - return 0; - } - CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - pkey = object->data.key; - STORE_OBJECT_free(object); - return pkey; - } - -int STORE_store_private_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - int i; - - check_store(s,STORE_F_STORE_STORE_PRIVATE_KEY, - store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); - - object = STORE_OBJECT_new(); - if (!object) - { - STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, - ERR_R_MALLOC_FAILURE); - return 0; - } - object->data.key = EVP_PKEY_new(); - if (!object->data.key) - { - STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, - ERR_R_MALLOC_FAILURE); - return 0; - } - - CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - object->data.key = data; - - i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object, - attributes, parameters); - - STORE_OBJECT_free(object); - - if (!i) - { - STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, - STORE_R_FAILED_STORING_KEY); - return 0; - } - return i; - } - -int STORE_modify_private_key(STORE *s, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_MODIFY_PRIVATE_KEY, - modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); - - if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, - search_attributes, add_attributes, modify_attributes, - delete_attributes, parameters)) - { - STOREerr(STORE_F_STORE_MODIFY_PRIVATE_KEY, - STORE_R_FAILED_MODIFYING_PRIVATE_KEY); - return 0; - } - return 1; - } - -int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - int i; - - check_store(s,STORE_F_STORE_REVOKE_PRIVATE_KEY, - revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION); - - i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, - attributes, parameters); - - if (!i) - { - STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY, - STORE_R_FAILED_REVOKING_KEY); - return 0; - } - return i; - } - -int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_DELETE_PRIVATE_KEY, - delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); - - if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, - attributes, parameters)) - { - STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY, - STORE_R_FAILED_DELETING_KEY); - return 0; - } - return 1; - } - -void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - void *handle; - - check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_START, - list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); - - handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY, - attributes, parameters); - if (!handle) - { - STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return handle; - } - -EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle) - { - STORE_OBJECT *object; - EVP_PKEY *pkey; - - check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_NEXT, - list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); - - object = s->meth->list_object_next(s, handle); - if (!object || !object->data.key || !object->data.key) - { - STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - pkey = object->data.key; - STORE_OBJECT_free(object); - return pkey; - } - -int STORE_list_private_key_end(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_END, - list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); - - if (!s->meth->list_object_end(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return 1; - } - -int STORE_list_private_key_endp(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_ENDP, - list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); - - if (!s->meth->list_object_endp(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return 1; - } - -EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - EVP_PKEY *pkey; - - check_store(s,STORE_F_STORE_GET_PUBLIC_KEY, - get_object,STORE_R_NO_GET_OBJECT_FUNCTION); - - object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, - attributes, parameters); - if (!object || !object->data.key || !object->data.key) - { - STOREerr(STORE_F_STORE_GET_PUBLIC_KEY, - STORE_R_FAILED_GETTING_KEY); - return 0; - } - CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - pkey = object->data.key; - STORE_OBJECT_free(object); - return pkey; - } - -int STORE_store_public_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - int i; - - check_store(s,STORE_F_STORE_STORE_PUBLIC_KEY, - store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); - - object = STORE_OBJECT_new(); - if (!object) - { - STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, - ERR_R_MALLOC_FAILURE); - return 0; - } - object->data.key = EVP_PKEY_new(); - if (!object->data.key) - { - STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, - ERR_R_MALLOC_FAILURE); - return 0; - } - - CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - object->data.key = data; - - i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object, - attributes, parameters); - - STORE_OBJECT_free(object); - - if (!i) - { - STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, - STORE_R_FAILED_STORING_KEY); - return 0; - } - return i; - } - -int STORE_modify_public_key(STORE *s, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_MODIFY_PUBLIC_KEY, - modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); - - if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, - search_attributes, add_attributes, modify_attributes, - delete_attributes, parameters)) - { - STOREerr(STORE_F_STORE_MODIFY_PUBLIC_KEY, - STORE_R_FAILED_MODIFYING_PUBLIC_KEY); - return 0; - } - return 1; - } - -int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - int i; - - check_store(s,STORE_F_STORE_REVOKE_PUBLIC_KEY, - revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION); - - i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, - attributes, parameters); - - if (!i) - { - STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY, - STORE_R_FAILED_REVOKING_KEY); - return 0; - } - return i; - } - -int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_DELETE_PUBLIC_KEY, - delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); - - if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, - attributes, parameters)) - { - STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY, - STORE_R_FAILED_DELETING_KEY); - return 0; - } - return 1; - } - -void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - void *handle; - - check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_START, - list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); - - handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY, - attributes, parameters); - if (!handle) - { - STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return handle; - } - -EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle) - { - STORE_OBJECT *object; - EVP_PKEY *pkey; - - check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_NEXT, - list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); - - object = s->meth->list_object_next(s, handle); - if (!object || !object->data.key || !object->data.key) - { - STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY",data); -#endif - pkey = object->data.key; - STORE_OBJECT_free(object); - return pkey; - } - -int STORE_list_public_key_end(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_END, - list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); - - if (!s->meth->list_object_end(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return 1; - } - -int STORE_list_public_key_endp(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_ENDP, - list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); - - if (!s->meth->list_object_endp(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return 1; - } - -X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - X509_CRL *crl; - - check_store(s,STORE_F_STORE_GENERATE_CRL, - generate_object,STORE_R_NO_GENERATE_CRL_FUNCTION); - - object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL, - attributes, parameters); - if (!object || !object->data.crl) - { - STOREerr(STORE_F_STORE_GENERATE_CRL, - STORE_R_FAILED_GENERATING_CRL); - return 0; - } - CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL); -#ifdef REF_PRINT - REF_PRINT("X509_CRL",data); -#endif - crl = object->data.crl; - STORE_OBJECT_free(object); - return crl; - } - -X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - X509_CRL *crl; - - check_store(s,STORE_F_STORE_GET_CRL, - get_object,STORE_R_NO_GET_OBJECT_FUNCTION); - - object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL, - attributes, parameters); - if (!object || !object->data.crl) - { - STOREerr(STORE_F_STORE_GET_CRL, - STORE_R_FAILED_GETTING_KEY); - return 0; - } - CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL); -#ifdef REF_PRINT - REF_PRINT("X509_CRL",data); -#endif - crl = object->data.crl; - STORE_OBJECT_free(object); - return crl; - } - -int STORE_store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - int i; - - check_store(s,STORE_F_STORE_STORE_CRL, - store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); - - object = STORE_OBJECT_new(); - if (!object) - { - STOREerr(STORE_F_STORE_STORE_CRL, - ERR_R_MALLOC_FAILURE); - return 0; - } - - CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509_CRL); -#ifdef REF_PRINT - REF_PRINT("X509_CRL",data); -#endif - object->data.crl = data; - - i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object, - attributes, parameters); - - STORE_OBJECT_free(object); - - if (!i) - { - STOREerr(STORE_F_STORE_STORE_CRL, - STORE_R_FAILED_STORING_KEY); - return 0; - } - return i; - } - -int STORE_modify_crl(STORE *s, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_MODIFY_CRL, - modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); - - if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CRL, - search_attributes, add_attributes, modify_attributes, - delete_attributes, parameters)) - { - STOREerr(STORE_F_STORE_MODIFY_CRL, - STORE_R_FAILED_MODIFYING_CRL); - return 0; - } - return 1; - } - -int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_DELETE_CRL, - delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); - - if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL, - attributes, parameters)) - { - STOREerr(STORE_F_STORE_DELETE_CRL, - STORE_R_FAILED_DELETING_KEY); - return 0; - } - return 1; - } - -void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - void *handle; - - check_store(s,STORE_F_STORE_LIST_CRL_START, - list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); - - handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL, - attributes, parameters); - if (!handle) - { - STOREerr(STORE_F_STORE_LIST_CRL_START, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return handle; - } - -X509_CRL *STORE_list_crl_next(STORE *s, void *handle) - { - STORE_OBJECT *object; - X509_CRL *crl; - - check_store(s,STORE_F_STORE_LIST_CRL_NEXT, - list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); - - object = s->meth->list_object_next(s, handle); - if (!object || !object->data.crl) - { - STOREerr(STORE_F_STORE_LIST_CRL_NEXT, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL); -#ifdef REF_PRINT - REF_PRINT("X509_CRL",data); -#endif - crl = object->data.crl; - STORE_OBJECT_free(object); - return crl; - } - -int STORE_list_crl_end(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_CRL_END, - list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); - - if (!s->meth->list_object_end(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_CRL_END, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return 1; - } - -int STORE_list_crl_endp(STORE *s, void *handle) - { - check_store(s,STORE_F_STORE_LIST_CRL_ENDP, - list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); - - if (!s->meth->list_object_endp(s, handle)) - { - STOREerr(STORE_F_STORE_LIST_CRL_ENDP, - STORE_R_FAILED_LISTING_KEYS); - return 0; - } - return 1; - } - -int STORE_store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - int i; - - check_store(s,STORE_F_STORE_STORE_NUMBER, - store_object,STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION); - - object = STORE_OBJECT_new(); - if (!object) - { - STOREerr(STORE_F_STORE_STORE_NUMBER, - ERR_R_MALLOC_FAILURE); - return 0; - } - - object->data.number = data; - - i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object, - attributes, parameters); - - STORE_OBJECT_free(object); - - if (!i) - { - STOREerr(STORE_F_STORE_STORE_NUMBER, - STORE_R_FAILED_STORING_NUMBER); - return 0; - } - return 1; - } - -int STORE_modify_number(STORE *s, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_MODIFY_NUMBER, - modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); - - if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_NUMBER, - search_attributes, add_attributes, modify_attributes, - delete_attributes, parameters)) - { - STOREerr(STORE_F_STORE_MODIFY_NUMBER, - STORE_R_FAILED_MODIFYING_NUMBER); - return 0; - } - return 1; - } - -BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - BIGNUM *n; - - check_store(s,STORE_F_STORE_GET_NUMBER, - get_object,STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION); - - object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes, - parameters); - if (!object || !object->data.number) - { - STOREerr(STORE_F_STORE_GET_NUMBER, - STORE_R_FAILED_GETTING_NUMBER); - return 0; - } - n = object->data.number; - object->data.number = NULL; - STORE_OBJECT_free(object); - return n; - } - -int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_DELETE_NUMBER, - delete_object,STORE_R_NO_DELETE_NUMBER_FUNCTION); - - if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes, - parameters)) - { - STOREerr(STORE_F_STORE_DELETE_NUMBER, - STORE_R_FAILED_DELETING_NUMBER); - return 0; - } - return 1; - } - -int STORE_store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - int i; - - check_store(s,STORE_F_STORE_STORE_ARBITRARY, - store_object,STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION); - - object = STORE_OBJECT_new(); - if (!object) - { - STOREerr(STORE_F_STORE_STORE_ARBITRARY, - ERR_R_MALLOC_FAILURE); - return 0; - } - - object->data.arbitrary = data; - - i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object, - attributes, parameters); - - STORE_OBJECT_free(object); - - if (!i) - { - STOREerr(STORE_F_STORE_STORE_ARBITRARY, - STORE_R_FAILED_STORING_ARBITRARY); - return 0; - } - return 1; - } - -int STORE_modify_arbitrary(STORE *s, OPENSSL_ITEM search_attributes[], - OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], - OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_MODIFY_ARBITRARY, - modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); - - if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_ARBITRARY, - search_attributes, add_attributes, modify_attributes, - delete_attributes, parameters)) - { - STOREerr(STORE_F_STORE_MODIFY_ARBITRARY, - STORE_R_FAILED_MODIFYING_ARBITRARY); - return 0; - } - return 1; - } - -BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STORE_OBJECT *object; - BUF_MEM *b; - - check_store(s,STORE_F_STORE_GET_ARBITRARY, - get_object,STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION); - - object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY, - attributes, parameters); - if (!object || !object->data.arbitrary) - { - STOREerr(STORE_F_STORE_GET_ARBITRARY, - STORE_R_FAILED_GETTING_ARBITRARY); - return 0; - } - b = object->data.arbitrary; - object->data.arbitrary = NULL; - STORE_OBJECT_free(object); - return b; - } - -int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - check_store(s,STORE_F_STORE_DELETE_ARBITRARY, - delete_object,STORE_R_NO_DELETE_ARBITRARY_FUNCTION); - - if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes, - parameters)) - { - STOREerr(STORE_F_STORE_DELETE_ARBITRARY, - STORE_R_FAILED_DELETING_ARBITRARY); - return 0; - } - return 1; - } - -STORE_OBJECT *STORE_OBJECT_new(void) - { - STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT)); - if (object) memset(object, 0, sizeof(STORE_OBJECT)); - return object; - } -void STORE_OBJECT_free(STORE_OBJECT *data) - { - if (!data) return; - switch (data->type) - { - case STORE_OBJECT_TYPE_X509_CERTIFICATE: - X509_free(data->data.x509.certificate); - break; - case STORE_OBJECT_TYPE_X509_CRL: - X509_CRL_free(data->data.crl); - break; - case STORE_OBJECT_TYPE_PRIVATE_KEY: - case STORE_OBJECT_TYPE_PUBLIC_KEY: - EVP_PKEY_free(data->data.key); - break; - case STORE_OBJECT_TYPE_NUMBER: - BN_free(data->data.number); - break; - case STORE_OBJECT_TYPE_ARBITRARY: - BUF_MEM_free(data->data.arbitrary); - break; - } - OPENSSL_free(data); - } - -IMPLEMENT_STACK_OF(STORE_OBJECT*) - - -struct STORE_attr_info_st - { - unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8]; - union - { - char *cstring; - unsigned char *sha1string; - X509_NAME *dn; - BIGNUM *number; - void *any; - } values[STORE_ATTR_TYPE_NUM+1]; - size_t value_sizes[STORE_ATTR_TYPE_NUM+1]; - }; - -#define ATTR_IS_SET(a,i) ((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \ - && ((a)->set[(i) / 8] & (1 << ((i) % 8)))) -#define SET_ATTRBIT(a,i) ((a)->set[(i) / 8] |= (1 << ((i) % 8))) -#define CLEAR_ATTRBIT(a,i) ((a)->set[(i) / 8] &= ~(1 << ((i) % 8))) - -STORE_ATTR_INFO *STORE_ATTR_INFO_new(void) - { - return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO)); - } -static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs, - STORE_ATTR_TYPES code) - { - if (ATTR_IS_SET(attrs,code)) - { - switch(code) - { - case STORE_ATTR_FRIENDLYNAME: - case STORE_ATTR_EMAIL: - case STORE_ATTR_FILENAME: - STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0); - break; - case STORE_ATTR_KEYID: - case STORE_ATTR_ISSUERKEYID: - case STORE_ATTR_SUBJECTKEYID: - case STORE_ATTR_ISSUERSERIALHASH: - case STORE_ATTR_CERTHASH: - STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0); - break; - case STORE_ATTR_ISSUER: - case STORE_ATTR_SUBJECT: - STORE_ATTR_INFO_modify_dn(attrs, code, NULL); - break; - case STORE_ATTR_SERIAL: - STORE_ATTR_INFO_modify_number(attrs, code, NULL); - break; - default: - break; - } - } - } -int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs) - { - if (attrs) - { - STORE_ATTR_TYPES i; - for(i = 0; i++ < STORE_ATTR_TYPE_NUM;) - STORE_ATTR_INFO_attr_free(attrs, i); - OPENSSL_free(attrs); - } - return 1; - } -char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR, - ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (ATTR_IS_SET(attrs,code)) - return attrs->values[code].cstring; - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR, - STORE_R_NO_VALUE); - return NULL; - } -unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs, - STORE_ATTR_TYPES code) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR, - ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (ATTR_IS_SET(attrs,code)) - return attrs->values[code].sha1string; - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR, - STORE_R_NO_VALUE); - return NULL; - } -X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN, - ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (ATTR_IS_SET(attrs,code)) - return attrs->values[code].dn; - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN, - STORE_R_NO_VALUE); - return NULL; - } -BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER, - ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (ATTR_IS_SET(attrs,code)) - return attrs->values[code].number; - STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER, - STORE_R_NO_VALUE); - return NULL; - } -int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - char *cstr, size_t cstr_size) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (!ATTR_IS_SET(attrs,code)) - { - if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size))) - return 1; - STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, - ERR_R_MALLOC_FAILURE); - return 0; - } - STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE); - return 0; - } -int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - unsigned char *sha1str, size_t sha1str_size) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (!ATTR_IS_SET(attrs,code)) - { - if ((attrs->values[code].sha1string = - (unsigned char *)BUF_memdup(sha1str, - sha1str_size))) - return 1; - STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, - ERR_R_MALLOC_FAILURE); - return 0; - } - STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE); - return 0; - } -int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - X509_NAME *dn) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (!ATTR_IS_SET(attrs,code)) - { - if ((attrs->values[code].dn = X509_NAME_dup(dn))) - return 1; - STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, - ERR_R_MALLOC_FAILURE); - return 0; - } - STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE); - return 0; - } -int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - BIGNUM *number) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (!ATTR_IS_SET(attrs,code)) - { - if ((attrs->values[code].number = BN_dup(number))) - return 1; - STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, - ERR_R_MALLOC_FAILURE); - return 0; - } - STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE); - return 0; - } -int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - char *cstr, size_t cstr_size) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (ATTR_IS_SET(attrs,code)) - { - OPENSSL_free(attrs->values[code].cstring); - attrs->values[code].cstring = NULL; - CLEAR_ATTRBIT(attrs, code); - } - return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size); - } -int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - unsigned char *sha1str, size_t sha1str_size) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (ATTR_IS_SET(attrs,code)) - { - OPENSSL_free(attrs->values[code].sha1string); - attrs->values[code].sha1string = NULL; - CLEAR_ATTRBIT(attrs, code); - } - return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size); - } -int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - X509_NAME *dn) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (ATTR_IS_SET(attrs,code)) - { - OPENSSL_free(attrs->values[code].dn); - attrs->values[code].dn = NULL; - CLEAR_ATTRBIT(attrs, code); - } - return STORE_ATTR_INFO_set_dn(attrs, code, dn); - } -int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, - BIGNUM *number) - { - if (!attrs) - { - STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (ATTR_IS_SET(attrs,code)) - { - OPENSSL_free(attrs->values[code].number); - attrs->values[code].number = NULL; - CLEAR_ATTRBIT(attrs, code); - } - return STORE_ATTR_INFO_set_number(attrs, code, number); - } - -struct attr_list_ctx_st - { - OPENSSL_ITEM *attributes; - }; -void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes) - { - if (attributes) - { - struct attr_list_ctx_st *context = - (struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st)); - if (context) - context->attributes = attributes; - else - STOREerr(STORE_F_STORE_PARSE_ATTRS_START, - ERR_R_MALLOC_FAILURE); - return context; - } - STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } -STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle) - { - struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; - - if (context && context->attributes) - { - STORE_ATTR_INFO *attrs = NULL; - - while(context->attributes - && context->attributes->code != STORE_ATTR_OR - && context->attributes->code != STORE_ATTR_END) - { - switch(context->attributes->code) - { - case STORE_ATTR_FRIENDLYNAME: - case STORE_ATTR_EMAIL: - case STORE_ATTR_FILENAME: - if (!attrs) attrs = STORE_ATTR_INFO_new(); - if (attrs == NULL) - { - STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, - ERR_R_MALLOC_FAILURE); - goto err; - } - STORE_ATTR_INFO_set_cstr(attrs, - context->attributes->code, - context->attributes->value, - context->attributes->value_size); - break; - case STORE_ATTR_KEYID: - case STORE_ATTR_ISSUERKEYID: - case STORE_ATTR_SUBJECTKEYID: - case STORE_ATTR_ISSUERSERIALHASH: - case STORE_ATTR_CERTHASH: - if (!attrs) attrs = STORE_ATTR_INFO_new(); - if (attrs == NULL) - { - STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, - ERR_R_MALLOC_FAILURE); - goto err; - } - STORE_ATTR_INFO_set_sha1str(attrs, - context->attributes->code, - context->attributes->value, - context->attributes->value_size); - break; - case STORE_ATTR_ISSUER: - case STORE_ATTR_SUBJECT: - if (!attrs) attrs = STORE_ATTR_INFO_new(); - if (attrs == NULL) - { - STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, - ERR_R_MALLOC_FAILURE); - goto err; - } - STORE_ATTR_INFO_modify_dn(attrs, - context->attributes->code, - context->attributes->value); - break; - case STORE_ATTR_SERIAL: - if (!attrs) attrs = STORE_ATTR_INFO_new(); - if (attrs == NULL) - { - STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, - ERR_R_MALLOC_FAILURE); - goto err; - } - STORE_ATTR_INFO_modify_number(attrs, - context->attributes->code, - context->attributes->value); - break; - } - context->attributes++; - } - if (context->attributes->code == STORE_ATTR_OR) - context->attributes++; - return attrs; - err: - while(context->attributes - && context->attributes->code != STORE_ATTR_OR - && context->attributes->code != STORE_ATTR_END) - context->attributes++; - if (context->attributes->code == STORE_ATTR_OR) - context->attributes++; - return NULL; - } - STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } -int STORE_parse_attrs_end(void *handle) - { - struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; - - if (context && context->attributes) - { -#if 0 - OPENSSL_ITEM *attributes = context->attributes; -#endif - OPENSSL_free(context); - return 1; - } - STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - -int STORE_parse_attrs_endp(void *handle) - { - struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; - - if (context && context->attributes) - { - return context->attributes->code == STORE_ATTR_END; - } - STOREerr(STORE_F_STORE_PARSE_ATTRS_ENDP, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - -static int attr_info_compare_compute_range( - unsigned char *abits, unsigned char *bbits, - unsigned int *alowp, unsigned int *ahighp, - unsigned int *blowp, unsigned int *bhighp) - { - unsigned int alow = (unsigned int)-1, ahigh = 0; - unsigned int blow = (unsigned int)-1, bhigh = 0; - int i, res = 0; - - for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++) - { - if (res == 0) - { - if (*abits < *bbits) res = -1; - if (*abits > *bbits) res = 1; - } - if (*abits) - { - if (alow == (unsigned int)-1) - { - alow = i * 8; - if (!(*abits & 0x01)) alow++; - if (!(*abits & 0x02)) alow++; - if (!(*abits & 0x04)) alow++; - if (!(*abits & 0x08)) alow++; - if (!(*abits & 0x10)) alow++; - if (!(*abits & 0x20)) alow++; - if (!(*abits & 0x40)) alow++; - } - ahigh = i * 8 + 7; - if (!(*abits & 0x80)) ahigh++; - if (!(*abits & 0x40)) ahigh++; - if (!(*abits & 0x20)) ahigh++; - if (!(*abits & 0x10)) ahigh++; - if (!(*abits & 0x08)) ahigh++; - if (!(*abits & 0x04)) ahigh++; - if (!(*abits & 0x02)) ahigh++; - } - if (*bbits) - { - if (blow == (unsigned int)-1) - { - blow = i * 8; - if (!(*bbits & 0x01)) blow++; - if (!(*bbits & 0x02)) blow++; - if (!(*bbits & 0x04)) blow++; - if (!(*bbits & 0x08)) blow++; - if (!(*bbits & 0x10)) blow++; - if (!(*bbits & 0x20)) blow++; - if (!(*bbits & 0x40)) blow++; - } - bhigh = i * 8 + 7; - if (!(*bbits & 0x80)) bhigh++; - if (!(*bbits & 0x40)) bhigh++; - if (!(*bbits & 0x20)) bhigh++; - if (!(*bbits & 0x10)) bhigh++; - if (!(*bbits & 0x08)) bhigh++; - if (!(*bbits & 0x04)) bhigh++; - if (!(*bbits & 0x02)) bhigh++; - } - } - if (ahigh + alow < bhigh + blow) res = -1; - if (ahigh + alow > bhigh + blow) res = 1; - if (alowp) *alowp = alow; - if (ahighp) *ahighp = ahigh; - if (blowp) *blowp = blow; - if (bhighp) *bhighp = bhigh; - return res; - } - -int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) - { - if (a == b) return 0; - if (!a) return -1; - if (!b) return 1; - return attr_info_compare_compute_range(a->set, b->set, 0, 0, 0, 0); - } -int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) - { - unsigned int alow, ahigh, blow, bhigh; - - if (a == b) return 1; - if (!a) return 0; - if (!b) return 0; - attr_info_compare_compute_range(a->set, b->set, - &alow, &ahigh, &blow, &bhigh); - if (alow >= blow && ahigh <= bhigh) - return 1; - return 0; - } -int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) - { - unsigned char *abits, *bbits; - int i; - - if (a == b) return 1; - if (!a) return 0; - if (!b) return 0; - abits = a->set; - bbits = b->set; - for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++) - { - if (*abits && (*bbits & *abits) != *abits) - return 0; - } - return 1; - } -int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) - { - STORE_ATTR_TYPES i; - - if (a == b) return 1; - if (!STORE_ATTR_INFO_in(a, b)) return 0; - for (i = 1; i < STORE_ATTR_TYPE_NUM; i++) - if (ATTR_IS_SET(a, i)) - { - switch(i) - { - case STORE_ATTR_FRIENDLYNAME: - case STORE_ATTR_EMAIL: - case STORE_ATTR_FILENAME: - if (strcmp(a->values[i].cstring, - b->values[i].cstring)) - return 0; - break; - case STORE_ATTR_KEYID: - case STORE_ATTR_ISSUERKEYID: - case STORE_ATTR_SUBJECTKEYID: - case STORE_ATTR_ISSUERSERIALHASH: - case STORE_ATTR_CERTHASH: - if (memcmp(a->values[i].sha1string, - b->values[i].sha1string, - a->value_sizes[i])) - return 0; - break; - case STORE_ATTR_ISSUER: - case STORE_ATTR_SUBJECT: - if (X509_NAME_cmp(a->values[i].dn, - b->values[i].dn)) - return 0; - break; - case STORE_ATTR_SERIAL: - if (BN_cmp(a->values[i].number, - b->values[i].number)) - return 0; - break; - default: - break; - } - } - - return 1; - } diff --git a/crypto/openssl/crypto/store/str_locl.h b/crypto/openssl/crypto/store/str_locl.h deleted file mode 100644 index 3f8cb75619..0000000000 --- a/crypto/openssl/crypto/store/str_locl.h +++ /dev/null @@ -1,124 +0,0 @@ -/* crypto/store/str_locl.h -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 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). - * - */ - -#ifndef HEADER_STORE_LOCL_H -#define HEADER_STORE_LOCL_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct store_method_st - { - char *name; - - /* All the functions return a positive integer or non-NULL for success - and 0, a negative integer or NULL for failure */ - - /* Initialise the STORE with private data */ - STORE_INITIALISE_FUNC_PTR init; - /* Initialise the STORE with private data */ - STORE_CLEANUP_FUNC_PTR clean; - /* Generate an object of a given type */ - STORE_GENERATE_OBJECT_FUNC_PTR generate_object; - /* Get an object of a given type. This function isn't really very - useful since the listing functions (below) can be used for the - same purpose and are much more general. */ - STORE_GET_OBJECT_FUNC_PTR get_object; - /* Store an object of a given type. */ - STORE_STORE_OBJECT_FUNC_PTR store_object; - /* Modify the attributes bound to an object of a given type. */ - STORE_MODIFY_OBJECT_FUNC_PTR modify_object; - /* Revoke an object of a given type. */ - STORE_HANDLE_OBJECT_FUNC_PTR revoke_object; - /* Delete an object of a given type. */ - STORE_HANDLE_OBJECT_FUNC_PTR delete_object; - /* List a bunch of objects of a given type and with the associated - attributes. */ - STORE_START_OBJECT_FUNC_PTR list_object_start; - STORE_NEXT_OBJECT_FUNC_PTR list_object_next; - STORE_END_OBJECT_FUNC_PTR list_object_end; - STORE_END_OBJECT_FUNC_PTR list_object_endp; - /* Store-level function to make any necessary update operations. */ - STORE_GENERIC_FUNC_PTR update_store; - /* Store-level function to get exclusive access to the store. */ - STORE_GENERIC_FUNC_PTR lock_store; - /* Store-level function to release exclusive access to the store. */ - STORE_GENERIC_FUNC_PTR unlock_store; - - /* Generic control function */ - STORE_CTRL_FUNC_PTR ctrl; - }; - -struct store_st - { - const STORE_METHOD *meth; - /* functional reference if 'meth' is ENGINE-provided */ - ENGINE *engine; - - CRYPTO_EX_DATA ex_data; - int references; - }; -#ifdef __cplusplus -} -#endif - -#endif diff --git a/crypto/openssl/crypto/store/str_mem.c b/crypto/openssl/crypto/store/str_mem.c deleted file mode 100644 index 527757ae09..0000000000 --- a/crypto/openssl/crypto/store/str_mem.c +++ /dev/null @@ -1,357 +0,0 @@ -/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 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 -#include -#include "str_locl.h" - -/* The memory store is currently highly experimental. It's meant to become - a base store used by other stores for internal caching (for full caching - support, aging needs to be added). - - The database use is meant to support as much attribute association as - possible, while providing for as small search ranges as possible. - This is currently provided for by sorting the entries by numbers that - are composed of bits set at the positions indicated by attribute type - codes. This provides for ranges determined by the highest attribute - type code value. A better idea might be to sort by values computed - from the range of attributes associated with the object (basically, - the difference between the highest and lowest attribute type code) - and it's distance from a base (basically, the lowest associated - attribute type code). -*/ - -struct mem_object_data_st - { - STORE_OBJECT *object; - STORE_ATTR_INFO *attr_info; - int references; - }; - -struct mem_data_st - { - STACK *data; /* A stack of mem_object_data_st, - sorted with STORE_ATTR_INFO_compare(). */ - unsigned int compute_components : 1; /* Currently unused, but can - be used to add attributes - from parts of the data. */ - }; - -struct mem_ctx_st - { - int type; /* The type we're searching for */ - STACK *search_attributes; /* Sets of attributes to search for. - Each element is a STORE_ATTR_INFO. */ - int search_index; /* which of the search attributes we found a match - for, -1 when we still haven't found any */ - int index; /* -1 as long as we're searching for the first */ - }; - -static int mem_init(STORE *s); -static void mem_clean(STORE *s); -static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -static int mem_store(STORE *s, STORE_OBJECT_TYPES type, - STORE_OBJECT *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -static int mem_modify(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], - OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], - OPENSSL_ITEM parameters[]); -static int mem_delete(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); -static STORE_OBJECT *mem_list_next(STORE *s, void *handle); -static int mem_list_end(STORE *s, void *handle); -static int mem_list_endp(STORE *s, void *handle); -static int mem_lock(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]); -static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void)); - -static STORE_METHOD store_memory = - { - "OpenSSL memory store interface", - mem_init, - mem_clean, - mem_generate, - mem_get, - mem_store, - mem_modify, - NULL, /* revoke */ - mem_delete, - mem_list_start, - mem_list_next, - mem_list_end, - mem_list_endp, - NULL, /* update */ - mem_lock, - mem_unlock, - mem_ctrl - }; - -const STORE_METHOD *STORE_Memory(void) - { - return &store_memory; - } - -static int mem_init(STORE *s) - { - return 1; - } - -static void mem_clean(STORE *s) - { - return; - } - -static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) - { - STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); - return 0; - } -static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) - { - void *context = mem_list_start(s, type, attributes, parameters); - - if (context) - { - STORE_OBJECT *object = mem_list_next(s, context); - - if (mem_list_end(s, context)) - return object; - } - return NULL; - } -static int mem_store(STORE *s, STORE_OBJECT_TYPES type, - STORE_OBJECT *data, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); - return 0; - } -static int mem_modify(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], - OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], - OPENSSL_ITEM parameters[]) - { - STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); - return 0; - } -static int mem_delete(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) - { - STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); - return 0; - } - -/* The list functions may be the hardest to understand. Basically, - mem_list_start compiles a stack of attribute info elements, and - puts that stack into the context to be returned. mem_list_next - will then find the first matching element in the store, and then - walk all the way to the end of the store (since any combination - of attribute bits above the starting point may match the searched - for bit pattern...). */ -static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, - OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) - { - struct mem_ctx_st *context = - (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); - void *attribute_context = NULL; - STORE_ATTR_INFO *attrs = NULL; - - if (!context) - { - STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); - return 0; - } - memset(context, 0, sizeof(struct mem_ctx_st)); - - attribute_context = STORE_parse_attrs_start(attributes); - if (!attribute_context) - { - STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); - goto err; - } - - while((attrs = STORE_parse_attrs_next(attribute_context))) - { - if (context->search_attributes == NULL) - { - context->search_attributes = - sk_new((int (*)(const char * const *, const char * const *))STORE_ATTR_INFO_compare); - if (!context->search_attributes) - { - STOREerr(STORE_F_MEM_LIST_START, - ERR_R_MALLOC_FAILURE); - goto err; - } - } - sk_push(context->search_attributes,(char *)attrs); - } - if (!STORE_parse_attrs_endp(attribute_context)) - goto err; - STORE_parse_attrs_end(attribute_context); - context->search_index = -1; - context->index = -1; - return context; - err: - if (attribute_context) STORE_parse_attrs_end(attribute_context); - mem_list_end(s, context); - return NULL; - } -static STORE_OBJECT *mem_list_next(STORE *s, void *handle) - { - int i; - struct mem_ctx_st *context = (struct mem_ctx_st *)handle; - struct mem_object_data_st key = { 0, 0, 1 }; - struct mem_data_st *store = - (struct mem_data_st *)STORE_get_ex_data(s, 1); - int srch; - int cres = 0; - - if (!context) - { - STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (!store) - { - STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); - return NULL; - } - - if (context->search_index == -1) - { - for (i = 0; i < sk_num(context->search_attributes); i++) - { - key.attr_info = - (STORE_ATTR_INFO *)sk_value(context->search_attributes, i); - srch = sk_find_ex(store->data, (char *)&key); - - if (srch >= 0) - { - context->search_index = srch; - break; - } - } - } - if (context->search_index < 0) - return NULL; - - key.attr_info = - (STORE_ATTR_INFO *)sk_value(context->search_attributes, - context->search_index); - for(srch = context->search_index; - srch < sk_num(store->data) - && STORE_ATTR_INFO_in_range(key.attr_info, - (STORE_ATTR_INFO *)sk_value(store->data, srch)) - && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info, - (STORE_ATTR_INFO *)sk_value(store->data, srch))); - srch++) - ; - - context->search_index = srch; - if (cres) - return ((struct mem_object_data_st *)sk_value(store->data, - srch))->object; - return NULL; - } -static int mem_list_end(STORE *s, void *handle) - { - struct mem_ctx_st *context = (struct mem_ctx_st *)handle; - - if (!context) - { - STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (context && context->search_attributes) - sk_free(context->search_attributes); - if (context) OPENSSL_free(context); - return 1; - } -static int mem_list_endp(STORE *s, void *handle) - { - struct mem_ctx_st *context = (struct mem_ctx_st *)handle; - - if (!context - || context->search_index == sk_num(context->search_attributes)) - return 1; - return 0; - } -static int mem_lock(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - return 1; - } -static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], - OPENSSL_ITEM parameters[]) - { - return 1; - } -static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void)) - { - return 1; - } diff --git a/crypto/openssl/crypto/store/str_meth.c b/crypto/openssl/crypto/store/str_meth.c deleted file mode 100644 index a46de03a26..0000000000 --- a/crypto/openssl/crypto/store/str_meth.c +++ /dev/null @@ -1,250 +0,0 @@ -/* crypto/store/str_meth.c -*- mode:C; c-file-style: "eay" -*- */ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 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 -#include -#include "str_locl.h" - -STORE_METHOD *STORE_create_method(char *name) - { - STORE_METHOD *store_method = (STORE_METHOD *)OPENSSL_malloc(sizeof(STORE_METHOD)); - - if (store_method) - { - memset(store_method, 0, sizeof(*store_method)); - store_method->name = BUF_strdup(name); - } - return store_method; - } - -/* BIG FSCKING WARNING!!!! If you use this on a statically allocated method - (that is, it hasn't been allocated using STORE_create_method(), you deserve - anything Murphy can throw at you and more! You have been warned. */ -void STORE_destroy_method(STORE_METHOD *store_method) - { - if (!store_method) return; - OPENSSL_free(store_method->name); - store_method->name = NULL; - OPENSSL_free(store_method); - } - -int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f) - { - sm->init = init_f; - return 1; - } - -int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f) - { - sm->clean = clean_f; - return 1; - } - -int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f) - { - sm->generate_object = generate_f; - return 1; - } - -int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f) - { - sm->get_object = get_f; - return 1; - } - -int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f) - { - sm->store_object = store_f; - return 1; - } - -int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR modify_f) - { - sm->modify_object = modify_f; - return 1; - } - -int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f) - { - sm->revoke_object = revoke_f; - return 1; - } - -int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f) - { - sm->delete_object = delete_f; - return 1; - } - -int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f) - { - sm->list_object_start = list_start_f; - return 1; - } - -int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f) - { - sm->list_object_next = list_next_f; - return 1; - } - -int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f) - { - sm->list_object_end = list_end_f; - return 1; - } - -int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR update_f) - { - sm->update_store = update_f; - return 1; - } - -int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR lock_f) - { - sm->lock_store = lock_f; - return 1; - } - -int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR unlock_f) - { - sm->unlock_store = unlock_f; - return 1; - } - -int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f) - { - sm->ctrl = ctrl_f; - return 1; - } - -STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm) - { - return sm->init; - } - -STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm) - { - return sm->clean; - } - -STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm) - { - return sm->generate_object; - } - -STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm) - { - return sm->get_object; - } - -STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm) - { - return sm->store_object; - } - -STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm) - { - return sm->modify_object; - } - -STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm) - { - return sm->revoke_object; - } - -STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm) - { - return sm->delete_object; - } - -STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm) - { - return sm->list_object_start; - } - -STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm) - { - return sm->list_object_next; - } - -STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm) - { - return sm->list_object_end; - } - -STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm) - { - return sm->update_store; - } - -STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm) - { - return sm->lock_store; - } - -STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm) - { - return sm->unlock_store; - } - -STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm) - { - return sm->ctrl; - } - diff --git a/crypto/openssl/crypto/symhacks.h b/crypto/openssl/crypto/symhacks.h index 0114093c1e..3fd4a81692 100644 --- a/crypto/openssl/crypto/symhacks.h +++ b/crypto/openssl/crypto/symhacks.h @@ -67,10 +67,6 @@ incompatibilities. */ #ifdef OPENSSL_SYS_VMS -/* Hack a long name in crypto/cryptlib.c */ -#undef int_CRYPTO_set_do_dynlock_callback -#define int_CRYPTO_set_do_dynlock_callback int_CRYPTO_set_do_dynlock_cb - /* Hack a long name in crypto/ex_data.c */ #undef CRYPTO_get_ex_data_implementation #define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl @@ -151,9 +147,9 @@ #undef CRYPTO_set_dynlock_create_callback #define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb #undef CRYPTO_set_dynlock_lock_callback -#define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb +#define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb #undef CRYPTO_get_dynlock_lock_callback -#define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb +#define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb #undef CRYPTO_get_dynlock_destroy_callback #define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb #undef CRYPTO_get_dynlock_create_callback @@ -165,7 +161,7 @@ /* Hack some long SSL names */ #undef SSL_CTX_set_default_verify_paths -#define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths +#define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths #undef SSL_get_ex_data_X509_STORE_CTX_idx #define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx #undef SSL_add_file_cert_subjects_to_stack @@ -175,7 +171,7 @@ #undef SSL_CTX_use_certificate_chain_file #define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file #undef SSL_CTX_set_cert_verify_callback -#define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb +#define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb #undef SSL_CTX_set_default_passwd_cb_userdata #define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud #undef SSL_COMP_get_compression_methods @@ -196,9 +192,17 @@ #undef ENGINE_set_default_BN_mod_exp_crt #define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt #undef ENGINE_set_load_privkey_function -#define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn +#define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn #undef ENGINE_get_load_privkey_function -#define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn +#define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn +#undef ENGINE_unregister_pkey_asn1_meths +#define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths +#undef ENGINE_register_all_pkey_asn1_meths +#define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths +#undef ENGINE_set_default_pkey_asn1_meths +#define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths +#undef ENGINE_get_pkey_asn1_meth_engine +#define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng #undef ENGINE_set_load_ssl_client_cert_function #define ENGINE_set_load_ssl_client_cert_function \ ENGINE_set_ld_ssl_clnt_cert_fn @@ -207,7 +211,7 @@ /* Hack some long OCSP names */ #undef OCSP_REQUEST_get_ext_by_critical -#define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit +#define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit #undef OCSP_BASICRESP_get_ext_by_critical #define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit #undef OCSP_SINGLERESP_get_ext_by_critical @@ -224,6 +228,8 @@ #define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf #undef OPENSSL_add_all_algorithms_conf #define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf +#undef EVP_PKEY_meth_set_verify_recover +#define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover /* Hack some long EC names */ #undef EC_GROUP_set_point_conversion_form @@ -252,15 +258,15 @@ #define EC_POINT_set_compressed_coordinates_GF2m \ EC_POINT_set_compr_coords_GF2m #undef ec_GF2m_simple_group_clear_finish -#define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish +#define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish #undef ec_GF2m_simple_group_check_discriminant #define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim #undef ec_GF2m_simple_point_clear_finish -#define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish +#define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish #undef ec_GF2m_simple_point_set_to_infinity -#define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf +#define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf #undef ec_GF2m_simple_points_make_affine -#define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine +#define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine #undef ec_GF2m_simple_point_set_affine_coordinates #define ec_GF2m_simple_point_set_affine_coordinates \ ec_GF2m_smp_pt_set_af_coords @@ -275,19 +281,19 @@ #undef ec_GFp_simple_group_get_curve_GFp #define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp #undef ec_GFp_simple_group_clear_finish -#define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish +#define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish #undef ec_GFp_simple_group_set_generator #define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator #undef ec_GFp_simple_group_get0_generator #define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator #undef ec_GFp_simple_group_get_cofactor -#define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor +#define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor #undef ec_GFp_simple_point_clear_finish -#define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish +#define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish #undef ec_GFp_simple_point_set_to_infinity #define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf #undef ec_GFp_simple_points_make_affine -#define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine +#define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine #undef ec_GFp_simple_group_get_curve_GFp #define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp #undef ec_GFp_simple_set_Jprojective_coordinates_GFp @@ -367,6 +373,14 @@ #undef STORE_method_get_unlock_store_function #define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn +/* Hack some long TS names */ +#undef TS_RESP_CTX_set_status_info_cond +#define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond +#undef TS_RESP_CTX_set_clock_precision_digits +#define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits +#undef TS_CONF_set_clock_precision_digits +#define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits + /* Hack some long CMS names */ #undef CMS_RecipientInfo_ktri_get0_algs #define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs @@ -385,24 +399,30 @@ #undef dtls1_retransmit_buffered_messages #define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs +/* Hack some long UI names */ +#undef UI_method_get_prompt_constructor +#define UI_method_get_prompt_constructor UI_method_get_prompt_constructr +#undef UI_method_set_prompt_constructor +#define UI_method_set_prompt_constructor UI_method_set_prompt_constructr + #endif /* defined OPENSSL_SYS_VMS */ -/* Case insensiteve linking causes problems.... */ -#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) +/* Case insensitive linking causes problems.... */ +#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) #undef ERR_load_CRYPTO_strings #define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings #undef OCSP_crlID_new -#define OCSP_crlID_new OCSP_crlID2_new +#define OCSP_crlID_new OCSP_crlID2_new #undef d2i_ECPARAMETERS -#define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +#define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS #undef i2d_ECPARAMETERS -#define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +#define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS #undef d2i_ECPKPARAMETERS -#define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +#define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS #undef i2d_ECPKPARAMETERS -#define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS +#define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS /* These functions do not seem to exist! However, I'm paranoid... Original command in x509v3.h: @@ -411,19 +431,19 @@ hide them a little, by giving them an extra 'o' at the beginning of the name... */ #undef X509v3_cleanup_extensions -#define X509v3_cleanup_extensions oX509v3_cleanup_extensions +#define X509v3_cleanup_extensions oX509v3_cleanup_extensions #undef X509v3_add_extension -#define X509v3_add_extension oX509v3_add_extension +#define X509v3_add_extension oX509v3_add_extension #undef X509v3_add_netscape_extensions -#define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions +#define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions #undef X509v3_add_standard_extensions -#define X509v3_add_standard_extensions oX509v3_add_standard_extensions +#define X509v3_add_standard_extensions oX509v3_add_standard_extensions +/* This one clashes with CMS_data_create */ +#undef cms_Data_create +#define cms_Data_create priv_cms_Data_create #endif #endif /* ! defined HEADER_VMS_IDHACKS_H */ -/* This one clashes with CMS_data_create */ -#undef cms_Data_create -#define cms_Data_create priv_cms_Data_create diff --git a/crypto/openssl/crypto/tmdiff.c b/crypto/openssl/crypto/tmdiff.c deleted file mode 100644 index 1c6e052ac9..0000000000 --- a/crypto/openssl/crypto/tmdiff.c +++ /dev/null @@ -1,260 +0,0 @@ -/* crypto/tmdiff.c */ -/* 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 -#include -#include "cryptlib.h" -#include -#if !defined(OPENSSL_SYS_MSDOS) -#include OPENSSL_UNISTD -#endif - -#ifdef TIMEB -#undef OPENSSL_SYS_WIN32 -#undef TIMES -#endif - -#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) && !(defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX_RHAPSODY) && !defined(OPENSSL_SYS_VXWORKS) -# define TIMES -#endif - -#ifdef OPENSSL_SYS_NETWARE -#undef TIMES -#endif - -#if !defined(_IRIX) || defined (OPENSSL_SYS_NETWARE) -# include -#endif -#ifdef TIMES -# include -# include -#endif - -/* Depending on the VMS version, the tms structure is perhaps defined. - The __TMS macro will show if it was. If it wasn't defined, we should - undefine TIMES, since that tells the rest of the program how things - should be handled. -- Richard Levitte */ -#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) -#undef TIMES -#endif - -#if defined(sun) || defined(__ultrix) -#define _POSIX_SOURCE -#include -#include -#endif - -#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE) -#include -#endif - -#ifdef OPENSSL_SYS_WIN32 -#include -#endif - -/* The following if from times(3) man page. It may need to be changed */ -#ifndef HZ -# if defined(_SC_CLK_TCK) \ - && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000) -/* # define HZ ((double)sysconf(_SC_CLK_TCK)) */ -# define HZ sysconf(_SC_CLK_TCK) -# else -# ifndef CLK_TCK -# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ -# define HZ 100.0 -# else /* _BSD_CLK_TCK_ */ -# define HZ ((double)_BSD_CLK_TCK_) -# endif -# else /* CLK_TCK */ -# define HZ ((double)CLK_TCK) -# endif -# endif -#endif - -struct ms_tm - { -#ifdef TIMES - struct tms ms_tms; -#else -# ifdef OPENSSL_SYS_WIN32 - HANDLE thread_id; - FILETIME ms_win32; -# elif defined (OPENSSL_SYS_NETWARE) - clock_t ms_clock; -# else -# ifdef OPENSSL_SYS_VXWORKS - unsigned long ticks; -# else - struct timeb ms_timeb; -# endif -# endif -#endif - }; - -MS_TM *ms_time_new(void) - { - MS_TM *ret; - - ret=(MS_TM *)OPENSSL_malloc(sizeof(MS_TM)); - if (ret == NULL) - return(NULL); - memset(ret,0,sizeof(MS_TM)); -#ifdef OPENSSL_SYS_WIN32 - ret->thread_id=GetCurrentThread(); -#endif - return ret; - } - -void ms_time_free(MS_TM *a) - { - if (a != NULL) - OPENSSL_free(a); - } - -void ms_time_get(MS_TM *tm) - { -#ifdef OPENSSL_SYS_WIN32 - FILETIME tmpa,tmpb,tmpc; -#endif - -#ifdef TIMES - times(&tm->ms_tms); -#else -# ifdef OPENSSL_SYS_WIN32 - GetThreadTimes(tm->thread_id,&tmpa,&tmpb,&tmpc,&(tm->ms_win32)); -# elif defined (OPENSSL_SYS_NETWARE) - tm->ms_clock = clock(); -# else -# ifdef OPENSSL_SYS_VXWORKS - tm->ticks = tickGet(); -# else - ftime(&tm->ms_timeb); -# endif -# endif -#endif - } - -double ms_time_diff(MS_TM *a, MS_TM *b) - { - double ret; - -#ifdef TIMES - ret = HZ; - ret = (b->ms_tms.tms_utime-a->ms_tms.tms_utime) / ret; -#else -# ifdef OPENSSL_SYS_WIN32 - { -#ifdef __GNUC__ - signed long long la,lb; -#else - signed _int64 la,lb; -#endif - la=a->ms_win32.dwHighDateTime; - lb=b->ms_win32.dwHighDateTime; - la<<=32; - lb<<=32; - la+=a->ms_win32.dwLowDateTime; - lb+=b->ms_win32.dwLowDateTime; - ret=((double)(lb-la))/1e7; - } -# elif defined (OPENSSL_SYS_NETWARE) - ret= (double)(b->ms_clock - a->ms_clock); -# else -# ifdef OPENSSL_SYS_VXWORKS - ret = (double)(b->ticks - a->ticks) / (double)sysClkRateGet(); -# else - ret= (double)(b->ms_timeb.time-a->ms_timeb.time)+ - (((double)b->ms_timeb.millitm)- - ((double)a->ms_timeb.millitm))/1000.0; -# endif -# endif -#endif - return((ret < 0.0000001)?0.0000001:ret); - } - -int ms_time_cmp(const MS_TM *a, const MS_TM *b) - { - double d; - int ret; - -#ifdef TIMES - d = HZ; - d = (b->ms_tms.tms_utime-a->ms_tms.tms_utime) / d; -#else -# ifdef OPENSSL_SYS_WIN32 - d =(b->ms_win32.dwHighDateTime&0x000fffff)*10+b->ms_win32.dwLowDateTime/1e7; - d-=(a->ms_win32.dwHighDateTime&0x000fffff)*10+a->ms_win32.dwLowDateTime/1e7; -# elif defined (OPENSSL_SYS_NETWARE) - d= (double)(b->ms_clock - a->ms_clock); -# else -# ifdef OPENSSL_SYS_VXWORKS - d = (b->ticks - a->ticks); -# else - d= (double)(b->ms_timeb.time-a->ms_timeb.time)+ - (((double)b->ms_timeb.millitm)-(double)a->ms_timeb.millitm)/1000.0; -# endif -# endif -#endif - if (d == 0.0) - ret=0; - else if (d < 0) - ret= -1; - else - ret=1; - return(ret); - } - diff --git a/crypto/openssl/crypto/tmdiff.h b/crypto/openssl/crypto/tmdiff.h deleted file mode 100644 index af5c41c649..0000000000 --- a/crypto/openssl/crypto/tmdiff.h +++ /dev/null @@ -1,93 +0,0 @@ -/* crypto/tmdiff.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.] - */ - -/* Header for dynamic hash table routines - * Author - Eric Young - */ -/* ... erm yeah, "dynamic hash tables" you say? - * - * And what would dynamic hash tables have to do with any of this code *now*? - * AFAICS, this code is only referenced by crypto/bn/exp.c which is an unused - * file that I doubt compiles any more. speed.c is the only thing that could - * use this (and it has nothing to do with hash tables), yet it instead has its - * own duplication of all this stuff and looks, if anything, more complete. See - * the corresponding note in apps/speed.c. - * The Bemused - Geoff - */ - -#ifndef HEADER_TMDIFF_H -#define HEADER_TMDIFF_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ms_tm MS_TM; - -MS_TM *ms_time_new(void ); -void ms_time_free(MS_TM *a); -void ms_time_get(MS_TM *a); -double ms_time_diff(MS_TM *start, MS_TM *end); -int ms_time_cmp(const MS_TM *ap, const MS_TM *bp); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/crypto/openssl/crypto/ts/ts.h b/crypto/openssl/crypto/ts/ts.h new file mode 100644 index 0000000000..190e8a1bf2 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts.h @@ -0,0 +1,861 @@ +/* crypto/ts/ts.h */ +/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL + * project 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 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). + * + */ + +#ifndef HEADER_TS_H +#define HEADER_TS_H + +#include +#include +#ifndef OPENSSL_NO_BUFFER +#include +#endif +#ifndef OPENSSL_NO_EVP +#include +#endif +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#ifndef OPENSSL_NO_DSA +#include +#endif + +#ifndef OPENSSL_NO_DH +#include +#endif + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +/* Under Win32 this is defined in wincrypt.h */ +#undef X509_NAME +#endif + +#include +#include + +/* +MessageImprint ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + hashedMessage OCTET STRING } +*/ + +typedef struct TS_msg_imprint_st + { + X509_ALGOR *hash_algo; + ASN1_OCTET_STRING *hashed_msg; + } TS_MSG_IMPRINT; + +/* +TimeStampReq ::= SEQUENCE { + version INTEGER { v1(1) }, + messageImprint MessageImprint, + --a hash algorithm OID and the hash value of the data to be + --time-stamped + reqPolicy TSAPolicyId OPTIONAL, + nonce INTEGER OPTIONAL, + certReq BOOLEAN DEFAULT FALSE, + extensions [0] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_req_st + { + ASN1_INTEGER *version; + TS_MSG_IMPRINT *msg_imprint; + ASN1_OBJECT *policy_id; /* OPTIONAL */ + ASN1_INTEGER *nonce; /* OPTIONAL */ + ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ + } TS_REQ; + +/* +Accuracy ::= SEQUENCE { + seconds INTEGER OPTIONAL, + millis [0] INTEGER (1..999) OPTIONAL, + micros [1] INTEGER (1..999) OPTIONAL } +*/ + +typedef struct TS_accuracy_st + { + ASN1_INTEGER *seconds; + ASN1_INTEGER *millis; + ASN1_INTEGER *micros; + } TS_ACCURACY; + +/* +TSTInfo ::= SEQUENCE { + version INTEGER { v1(1) }, + policy TSAPolicyId, + messageImprint MessageImprint, + -- MUST have the same value as the similar field in + -- TimeStampReq + serialNumber INTEGER, + -- Time-Stamping users MUST be ready to accommodate integers + -- up to 160 bits. + genTime GeneralizedTime, + accuracy Accuracy OPTIONAL, + ordering BOOLEAN DEFAULT FALSE, + nonce INTEGER OPTIONAL, + -- MUST be present if the similar field was present + -- in TimeStampReq. In that case it MUST have the same value. + tsa [0] GeneralName OPTIONAL, + extensions [1] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_tst_info_st + { + ASN1_INTEGER *version; + ASN1_OBJECT *policy_id; + TS_MSG_IMPRINT *msg_imprint; + ASN1_INTEGER *serial; + ASN1_GENERALIZEDTIME *time; + TS_ACCURACY *accuracy; + ASN1_BOOLEAN ordering; + ASN1_INTEGER *nonce; + GENERAL_NAME *tsa; + STACK_OF(X509_EXTENSION) *extensions; + } TS_TST_INFO; + +/* +PKIStatusInfo ::= SEQUENCE { + status PKIStatus, + statusString PKIFreeText OPTIONAL, + failInfo PKIFailureInfo OPTIONAL } + +From RFC 1510 - section 3.1.1: +PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + -- text encoded as UTF-8 String (note: each UTF8String SHOULD + -- include an RFC 1766 language tag to indicate the language + -- of the contained text) +*/ + +/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ + +#define TS_STATUS_GRANTED 0 +#define TS_STATUS_GRANTED_WITH_MODS 1 +#define TS_STATUS_REJECTION 2 +#define TS_STATUS_WAITING 3 +#define TS_STATUS_REVOCATION_WARNING 4 +#define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */ + +#define TS_INFO_BAD_ALG 0 +#define TS_INFO_BAD_REQUEST 2 +#define TS_INFO_BAD_DATA_FORMAT 5 +#define TS_INFO_TIME_NOT_AVAILABLE 14 +#define TS_INFO_UNACCEPTED_POLICY 15 +#define TS_INFO_UNACCEPTED_EXTENSION 16 +#define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +#define TS_INFO_SYSTEM_FAILURE 25 + +typedef struct TS_status_info_st + { + ASN1_INTEGER *status; + STACK_OF(ASN1_UTF8STRING) *text; + ASN1_BIT_STRING *failure_info; + } TS_STATUS_INFO; + +DECLARE_STACK_OF(ASN1_UTF8STRING) +DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) + +/* +TimeStampResp ::= SEQUENCE { + status PKIStatusInfo, + timeStampToken TimeStampToken OPTIONAL } +*/ + +typedef struct TS_resp_st + { + TS_STATUS_INFO *status_info; + PKCS7 *token; + TS_TST_INFO *tst_info; + } TS_RESP; + +/* The structure below would belong to the ESS component. */ + +/* +IssuerSerial ::= SEQUENCE { + issuer GeneralNames, + serialNumber CertificateSerialNumber + } +*/ + +typedef struct ESS_issuer_serial + { + STACK_OF(GENERAL_NAME) *issuer; + ASN1_INTEGER *serial; + } ESS_ISSUER_SERIAL; + +/* +ESSCertID ::= SEQUENCE { + certHash Hash, + issuerSerial IssuerSerial OPTIONAL +} +*/ + +typedef struct ESS_cert_id + { + ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ + ESS_ISSUER_SERIAL *issuer_serial; + } ESS_CERT_ID; + +DECLARE_STACK_OF(ESS_CERT_ID) +DECLARE_ASN1_SET_OF(ESS_CERT_ID) + +/* +SigningCertificate ::= SEQUENCE { + certs SEQUENCE OF ESSCertID, + policies SEQUENCE OF PolicyInformation OPTIONAL +} +*/ + +typedef struct ESS_signing_cert + { + STACK_OF(ESS_CERT_ID) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; + } ESS_SIGNING_CERT; + + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, + unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, + unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +void ERR_load_TS_strings(void); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +#define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +#define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +#define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *); + +/* This must return the seconds and microseconds since Jan 1, 1970 in + the sec and usec variables allocated by the caller. + Return non-zero for success and zero for failure. */ +typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec); + +/* This must process the given extension. + * It can modify the TS_TST_INFO object of the context. + * Return values: !0 (processed), 0 (error, it must set the + * status info/failure info of the response). + */ +typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +typedef struct TS_resp_ctx + { + X509 *signer_cert; + EVP_PKEY *signer_key; + STACK_OF(X509) *certs; /* Certs to include in signed data. */ + STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ + ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ + STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ + ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ + unsigned clock_precision_digits; /* fraction of seconds in + time stamp token. */ + unsigned flags; /* Optional info, see values above. */ + + /* Callback functions. */ + TS_serial_cb serial_cb; + void *serial_cb_data; /* User data for serial_cb. */ + + TS_time_cb time_cb; + void *time_cb_data; /* User data for time_cb. */ + + TS_extension_cb extension_cb; + void *extension_cb_data; /* User data for extension_cb. */ + + /* These members are used only while creating the response. */ + TS_REQ *request; + TS_RESP *response; + TS_TST_INFO *tst_info; + } TS_RESP_CTX; + +DECLARE_STACK_OF(EVP_MD) +DECLARE_ASN1_SET_OF(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* Adds a new acceptable policy, only the default policy + is accepted by default. */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); + +/* Adds a new acceptable message digest. Note that no message digests + are accepted by default. The md argument is shared with the caller. */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* Clock precision digits, i.e. the number of decimal digits: + '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +#define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +#define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +#define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +#define TS_VFY_POLICY (1u << 2) +/* Verify the message imprint provided by the user. This flag should not be + specified with TS_VFY_DATA. */ +#define TS_VFY_IMPRINT (1u << 3) +/* Verify the message imprint computed by the verify method from the user + provided data and the MD algorithm of the response. This flag should not be + specified with TS_VFY_IMPRINT. */ +#define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +#define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +#define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +#define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +#define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +#define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx + { + /* Set this to the union of TS_VFY_... flags you want to carry out. */ + unsigned flags; + + /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ + X509_STORE *store; + STACK_OF(X509) *certs; + + /* Must be set only with TS_VFY_POLICY. */ + ASN1_OBJECT *policy; + + /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, + the algorithm from the response is used. */ + X509_ALGOR *md_alg; + unsigned char *imprint; + unsigned imprint_len; + + /* Must be set only with TS_VFY_DATA. */ + BIO *data; + + /* Must be set only with TS_VFY_TSA_NAME. */ + ASN1_INTEGER *nonce; + + /* Must be set only with TS_VFY_TSA_NAME. */ + GENERAL_NAME *tsa_name; + } TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + * they are defined in ts/ts_verify_ctx.c. + */ + +/* Set all fields to zero. */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); + +/* + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* Function declarations for handling configuration options, + defined in ts/ts_conf.c */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +/* -------------------------------------------------- */ +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_TS_strings(void); + +/* Error codes for the TS functions. */ + +/* Function codes. */ +#define TS_F_D2I_TS_RESP 147 +#define TS_F_DEF_SERIAL_CB 110 +#define TS_F_DEF_TIME_CB 111 +#define TS_F_ESS_ADD_SIGNING_CERT 112 +#define TS_F_ESS_CERT_ID_NEW_INIT 113 +#define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +#define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +#define TS_F_PKCS7_TO_TS_TST_INFO 148 +#define TS_F_TS_ACCURACY_SET_MICROS 115 +#define TS_F_TS_ACCURACY_SET_MILLIS 116 +#define TS_F_TS_ACCURACY_SET_SECONDS 117 +#define TS_F_TS_CHECK_IMPRINTS 100 +#define TS_F_TS_CHECK_NONCES 101 +#define TS_F_TS_CHECK_POLICY 102 +#define TS_F_TS_CHECK_SIGNING_CERTS 103 +#define TS_F_TS_CHECK_STATUS_INFO 104 +#define TS_F_TS_COMPUTE_IMPRINT 145 +#define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +#define TS_F_TS_GET_STATUS_TEXT 105 +#define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +#define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +#define TS_F_TS_REQ_SET_NONCE 120 +#define TS_F_TS_REQ_SET_POLICY_ID 121 +#define TS_F_TS_RESP_CREATE_RESPONSE 122 +#define TS_F_TS_RESP_CREATE_TST_INFO 123 +#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +#define TS_F_TS_RESP_CTX_ADD_MD 125 +#define TS_F_TS_RESP_CTX_ADD_POLICY 126 +#define TS_F_TS_RESP_CTX_NEW 127 +#define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +#define TS_F_TS_RESP_CTX_SET_CERTS 129 +#define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +#define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +#define TS_F_TS_RESP_GET_POLICY 133 +#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +#define TS_F_TS_RESP_SET_STATUS_INFO 135 +#define TS_F_TS_RESP_SET_TST_INFO 150 +#define TS_F_TS_RESP_SIGN 136 +#define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +#define TS_F_TS_RESP_VERIFY_TOKEN 107 +#define TS_F_TS_TST_INFO_SET_ACCURACY 137 +#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +#define TS_F_TS_TST_INFO_SET_NONCE 139 +#define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +#define TS_F_TS_TST_INFO_SET_SERIAL 141 +#define TS_F_TS_TST_INFO_SET_TIME 142 +#define TS_F_TS_TST_INFO_SET_TSA 143 +#define TS_F_TS_VERIFY 108 +#define TS_F_TS_VERIFY_CERT 109 +#define TS_F_TS_VERIFY_CTX_NEW 144 + +/* Reason codes. */ +#define TS_R_BAD_PKCS7_TYPE 132 +#define TS_R_BAD_TYPE 133 +#define TS_R_CERTIFICATE_VERIFY_ERROR 100 +#define TS_R_COULD_NOT_SET_ENGINE 127 +#define TS_R_COULD_NOT_SET_TIME 115 +#define TS_R_D2I_TS_RESP_INT_FAILED 128 +#define TS_R_DETACHED_CONTENT 134 +#define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +#define TS_R_INVALID_NULL_POINTER 102 +#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +#define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +#define TS_R_NONCE_MISMATCH 104 +#define TS_R_NONCE_NOT_RETURNED 105 +#define TS_R_NO_CONTENT 106 +#define TS_R_NO_TIME_STAMP_TOKEN 107 +#define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +#define TS_R_POLICY_MISMATCH 108 +#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +#define TS_R_RESPONSE_SETUP_ERROR 121 +#define TS_R_SIGNATURE_FAILURE 109 +#define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +#define TS_R_TIME_SYSCALL_ERROR 122 +#define TS_R_TOKEN_NOT_PRESENT 130 +#define TS_R_TOKEN_PRESENT 131 +#define TS_R_TSA_NAME_MISMATCH 111 +#define TS_R_TSA_UNTRUSTED 112 +#define TS_R_TST_INFO_SETUP_ERROR 123 +#define TS_R_TS_DATASIGN 124 +#define TS_R_UNACCEPTABLE_POLICY 125 +#define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +#define TS_R_UNSUPPORTED_VERSION 113 +#define TS_R_WRONG_CONTENT_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/openssl/crypto/ts/ts_asn1.c b/crypto/openssl/crypto/ts/ts_asn1.c new file mode 100644 index 0000000000..40b730c5e2 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_asn1.c @@ -0,0 +1,322 @@ +/* crypto/ts/ts_asn1.c */ +/* Written by Nils Larsch for the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include +#include + +ASN1_SEQUENCE(TS_MSG_IMPRINT) = { + ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR), + ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(TS_MSG_IMPRINT) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT) +#ifndef OPENSSL_NO_BIO +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) + { + return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, bp, a); + } + +int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) +{ + return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) + { + return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, fp, a); + } + +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) + { + return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); + } +#endif + +ASN1_SEQUENCE(TS_REQ) = { + ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER), + ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT), + ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT), + ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER), + ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN), + ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END(TS_REQ) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ) +#ifndef OPENSSL_NO_BIO +TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) + { + return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a); + } + +int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) + { + return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a); + } +#endif +#ifndef OPENSSL_NO_FP_API +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) + { + return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a); + } + +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) + { + return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a); + } +#endif + +ASN1_SEQUENCE(TS_ACCURACY) = { + ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER), + ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0), + ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END(TS_ACCURACY) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY) + +ASN1_SEQUENCE(TS_TST_INFO) = { + ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT), + ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT), + ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER), + ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME), + ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY), + ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN), + ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER), + ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0), + ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(TS_TST_INFO) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO) +#ifndef OPENSSL_NO_BIO +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) + { + return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, a); + } + +int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) + { + return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); + } +#endif +#ifndef OPENSSL_NO_FP_API +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) + { + return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, a); + } + +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) + { + return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); + } +#endif + +ASN1_SEQUENCE(TS_STATUS_INFO) = { + ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER), + ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING), + ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(TS_STATUS_INFO) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO) + +static int ts_resp_set_tst_info(TS_RESP *a) +{ + long status; + + status = ASN1_INTEGER_get(a->status_info->status); + + if (a->token) { + if (status != 0 && status != 1) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT); + return 0; + } + if (a->tst_info != NULL) + TS_TST_INFO_free(a->tst_info); + a->tst_info = PKCS7_to_TS_TST_INFO(a->token); + if (!a->tst_info) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_PKCS7_TO_TS_TST_INFO_FAILED); + return 0; + } + } else if (status == 0 || status == 1) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT); + return 0; + } + + return 1; +} + +static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + TS_RESP *ts_resp = (TS_RESP *)*pval; + if (op == ASN1_OP_NEW_POST) { + ts_resp->tst_info = NULL; + } else if (op == ASN1_OP_FREE_POST) { + if (ts_resp->tst_info != NULL) + TS_TST_INFO_free(ts_resp->tst_info); + } else if (op == ASN1_OP_D2I_POST) { + if (ts_resp_set_tst_info(ts_resp) == 0) + return 0; + } + return 1; +} + +ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = { + ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO), + ASN1_OPT(TS_RESP, token, PKCS7), +} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP) +#ifndef OPENSSL_NO_BIO +TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) + { + return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a); + } + +int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) + { + return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a); + } +#endif +#ifndef OPENSSL_NO_FP_API +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) + { + return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a); + } + +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) + { + return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a); + } +#endif + +ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { + ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), + ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) + +ASN1_SEQUENCE(ESS_CERT_ID) = { + ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), + ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) +} ASN1_SEQUENCE_END(ESS_CERT_ID) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) + +ASN1_SEQUENCE(ESS_SIGNING_CERT) = { + ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), + ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) +} ASN1_SEQUENCE_END(ESS_SIGNING_CERT) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) + +/* Getting encapsulated TS_TST_INFO object from PKCS7. */ +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) +{ + PKCS7_SIGNED *pkcs7_signed; + PKCS7 *enveloped; + ASN1_TYPE *tst_info_wrapper; + ASN1_OCTET_STRING *tst_info_der; + const unsigned char *p; + + if (!PKCS7_type_is_signed(token)) + { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* Content must be present. */ + if (PKCS7_get_detached(token)) + { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT); + return NULL; + } + + /* We have a signed data with content. */ + pkcs7_signed = token->d.sign; + enveloped = pkcs7_signed->contents; + if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) + { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* We have a DER encoded TST_INFO as the signed data. */ + tst_info_wrapper = enveloped->d.other; + if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) + { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE); + return NULL; + } + + /* We have the correct ASN1_OCTET_STRING type. */ + tst_info_der = tst_info_wrapper->value.octet_string; + /* At last, decode the TST_INFO. */ + p = tst_info_der->data; + return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length); +} diff --git a/crypto/openssl/crypto/ts/ts_conf.c b/crypto/openssl/crypto/ts/ts_conf.c new file mode 100644 index 0000000000..c39be76f28 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_conf.c @@ -0,0 +1,507 @@ +/* crypto/ts/ts_conf.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 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 + +#include +#include "cryptlib.h" +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include + +/* Macro definitions for the configuration file. */ + +#define BASE_SECTION "tsa" +#define ENV_DEFAULT_TSA "default_tsa" +#define ENV_SERIAL "serial" +#define ENV_CRYPTO_DEVICE "crypto_device" +#define ENV_SIGNER_CERT "signer_cert" +#define ENV_CERTS "certs" +#define ENV_SIGNER_KEY "signer_key" +#define ENV_DEFAULT_POLICY "default_policy" +#define ENV_OTHER_POLICIES "other_policies" +#define ENV_DIGESTS "digests" +#define ENV_ACCURACY "accuracy" +#define ENV_ORDERING "ordering" +#define ENV_TSA_NAME "tsa_name" +#define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain" +#define ENV_VALUE_SECS "secs" +#define ENV_VALUE_MILLISECS "millisecs" +#define ENV_VALUE_MICROSECS "microsecs" +#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits" +#define ENV_VALUE_YES "yes" +#define ENV_VALUE_NO "no" + +/* Function definitions for certificate and key loading. */ + +X509 *TS_CONF_load_cert(const char *file) + { + BIO *cert = NULL; + X509 *x = NULL; + + if ((cert = BIO_new_file(file, "r")) == NULL) goto end; + x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); +end: + if (x == NULL) + fprintf(stderr, "unable to load certificate: %s\n", file); + BIO_free(cert); + return x; + } + +STACK_OF(X509) *TS_CONF_load_certs(const char *file) + { + BIO *certs = NULL; + STACK_OF(X509) *othercerts = NULL; + STACK_OF(X509_INFO) *allcerts = NULL; + int i; + + if (!(certs = BIO_new_file(file, "r"))) goto end; + + if (!(othercerts = sk_X509_new_null())) goto end; + allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); + for(i = 0; i < sk_X509_INFO_num(allcerts); i++) + { + X509_INFO *xi = sk_X509_INFO_value(allcerts, i); + if (xi->x509) + { + sk_X509_push(othercerts, xi->x509); + xi->x509 = NULL; + } + } +end: + if (othercerts == NULL) + fprintf(stderr, "unable to load certificates: %s\n", file); + sk_X509_INFO_pop_free(allcerts, X509_INFO_free); + BIO_free(certs); + return othercerts; + } + +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) + { + BIO *key = NULL; + EVP_PKEY *pkey = NULL; + + if (!(key = BIO_new_file(file, "r"))) goto end; + pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass); + end: + if (pkey == NULL) + fprintf(stderr, "unable to load private key: %s\n", file); + BIO_free(key); + return pkey; + } + +/* Function definitions for handling configuration options. */ + +static void TS_CONF_lookup_fail(const char *name, const char *tag) + { + fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); + } + +static void TS_CONF_invalid(const char *name, const char *tag) + { + fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); + } + +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) + { + if (!section) + { + section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA); + if (!section) + TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA); + } + return section; + } + +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx) + { + int ret = 0; + char *serial = NCONF_get_string(conf, section, ENV_SERIAL); + if (!serial) + { + TS_CONF_lookup_fail(section, ENV_SERIAL); + goto err; + } + TS_RESP_CTX_set_serial_cb(ctx, cb, serial); + + ret = 1; + err: + return ret; + } + +#ifndef OPENSSL_NO_ENGINE + +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device) + { + int ret = 0; + + if (!device) + device = NCONF_get_string(conf, section, + ENV_CRYPTO_DEVICE); + + if (device && !TS_CONF_set_default_engine(device)) + { + TS_CONF_invalid(section, ENV_CRYPTO_DEVICE); + goto err; + } + ret = 1; + err: + return ret; + } + +int TS_CONF_set_default_engine(const char *name) + { + ENGINE *e = NULL; + int ret = 0; + + /* Leave the default if builtin specified. */ + if (strcmp(name, "builtin") == 0) return 1; + + if (!(e = ENGINE_by_id(name))) goto err; + /* Enable the use of the NCipher HSM for forked children. */ + if (strcmp(name, "chil") == 0) + ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0); + /* All the operations are going to be carried out by the engine. */ + if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err; + ret = 1; + err: + if (!ret) + { + TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, + TS_R_COULD_NOT_SET_ENGINE); + ERR_add_error_data(2, "engine:", name); + } + if (e) ENGINE_free(e); + return ret; + } + +#endif + +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx) + { + int ret = 0; + X509 *cert_obj = NULL; + if (!cert) + cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT); + if (!cert) + { + TS_CONF_lookup_fail(section, ENV_SIGNER_CERT); + goto err; + } + if (!(cert_obj = TS_CONF_load_cert(cert))) + goto err; + if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj)) + goto err; + + ret = 1; + err: + X509_free(cert_obj); + return ret; + } + +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx) + { + int ret = 0; + STACK_OF(X509) *certs_obj = NULL; + if (!certs) + certs = NCONF_get_string(conf, section, ENV_CERTS); + /* Certificate chain is optional. */ + if (!certs) goto end; + if (!(certs_obj = TS_CONF_load_certs(certs))) goto err; + if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err; + end: + ret = 1; + err: + sk_X509_pop_free(certs_obj, X509_free); + return ret; + } + +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx) + { + int ret = 0; + EVP_PKEY *key_obj = NULL; + if (!key) + key = NCONF_get_string(conf, section, ENV_SIGNER_KEY); + if (!key) + { + TS_CONF_lookup_fail(section, ENV_SIGNER_KEY); + goto err; + } + if (!(key_obj = TS_CONF_load_key(key, pass))) goto err; + if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err; + + ret = 1; + err: + EVP_PKEY_free(key_obj); + return ret; + } + +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx) + { + int ret = 0; + ASN1_OBJECT *policy_obj = NULL; + if (!policy) + policy = NCONF_get_string(conf, section, + ENV_DEFAULT_POLICY); + if (!policy) + { + TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!(policy_obj = OBJ_txt2obj(policy, 0))) + { + TS_CONF_invalid(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) + goto err; + + ret = 1; + err: + ASN1_OBJECT_free(policy_obj); + return ret; + } + +int TS_CONF_set_policies(CONF *conf, const char *section, + TS_RESP_CTX *ctx) + { + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *policies = NCONF_get_string(conf, section, + ENV_OTHER_POLICIES); + /* If no other policy is specified, that's fine. */ + if (policies && !(list = X509V3_parse_list(policies))) + { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) + { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_txt2obj(extval, 0))) + { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + if (!TS_RESP_CTX_add_policy(ctx, objtmp)) + goto err; + ASN1_OBJECT_free(objtmp); + } + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; + } + +int TS_CONF_set_digests(CONF *conf, const char *section, + TS_RESP_CTX *ctx) + { + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); + if (!digests) + { + TS_CONF_lookup_fail(section, ENV_DIGESTS); + goto err; + } + if (!(list = X509V3_parse_list(digests))) + { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (sk_CONF_VALUE_num(list) == 0) + { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) + { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(extval))) + { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (!TS_RESP_CTX_add_md(ctx, md)) + goto err; + } + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; + } + +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) + { + int ret = 0; + int i; + int secs = 0, millis = 0, micros = 0; + STACK_OF(CONF_VALUE) *list = NULL; + char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); + + if (accuracy && !(list = X509V3_parse_list(accuracy))) + { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) + { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + if (strcmp(val->name, ENV_VALUE_SECS) == 0) + { + if (val->value) secs = atoi(val->value); + } + else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) + { + if (val->value) millis = atoi(val->value); + } + else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) + { + if (val->value) micros = atoi(val->value); + } + else + { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + } + if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) + goto err; + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; + } + +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx) + { + int ret = 0; + long digits = 0; + + /* If not specified, set the default value to 0, i.e. sec precision */ + if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, + &digits)) + digits = 0; + if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) + { + TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); + goto err; + } + + if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits)) + goto err; + + return 1; + err: + return ret; + } + +static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field, + int flag, TS_RESP_CTX *ctx) + { + /* Default is false. */ + const char *value = NCONF_get_string(conf, section, field); + if (value) + { + if (strcmp(value, ENV_VALUE_YES) == 0) + TS_RESP_CTX_add_flags(ctx, flag); + else if (strcmp(value, ENV_VALUE_NO) != 0) + { + TS_CONF_invalid(section, field); + return 0; + } + } + + return 1; + } + +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx) + { + return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx); + } + +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx) + { + return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx); + } + +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx) + { + return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, + TS_ESS_CERT_ID_CHAIN, ctx); + } diff --git a/crypto/openssl/crypto/ts/ts_err.c b/crypto/openssl/crypto/ts/ts_err.c new file mode 100644 index 0000000000..a08b0ffa23 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_err.c @@ -0,0 +1,179 @@ +/* crypto/ts/ts_err.c */ +/* ==================================================================== + * Copyright (c) 1999-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). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason) + +static ERR_STRING_DATA TS_str_functs[]= + { +{ERR_FUNC(TS_F_D2I_TS_RESP), "d2i_TS_RESP"}, +{ERR_FUNC(TS_F_DEF_SERIAL_CB), "DEF_SERIAL_CB"}, +{ERR_FUNC(TS_F_DEF_TIME_CB), "DEF_TIME_CB"}, +{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_ADD_SIGNING_CERT"}, +{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ESS_CERT_ID_NEW_INIT"}, +{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ESS_SIGNING_CERT_NEW_INIT"}, +{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "INT_TS_RESP_VERIFY_TOKEN"}, +{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"}, +{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"}, +{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"}, +{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"}, +{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "TS_CHECK_IMPRINTS"}, +{ERR_FUNC(TS_F_TS_CHECK_NONCES), "TS_CHECK_NONCES"}, +{ERR_FUNC(TS_F_TS_CHECK_POLICY), "TS_CHECK_POLICY"}, +{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"}, +{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"}, +{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"}, +{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"}, +{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"}, +{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"}, +{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"}, +{ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"}, +{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"}, +{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"}, +{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "TS_RESP_CREATE_TST_INFO"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO), "TS_RESP_CTX_add_failure_info"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT), "TS_RESP_CTX_set_signer_cert"}, +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO), "TS_RESP_CTX_set_status_info"}, +{ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "TS_RESP_GET_POLICY"}, +{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION), "TS_RESP_SET_GENTIME_WITH_PRECISION"}, +{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"}, +{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"}, +{ERR_FUNC(TS_F_TS_RESP_SIGN), "TS_RESP_SIGN"}, +{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"}, +{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN), "TS_RESP_verify_token"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT), "TS_TST_INFO_set_msg_imprint"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"}, +{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"}, +{ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"}, +{ERR_FUNC(TS_F_TS_VERIFY_CERT), "TS_VERIFY_CERT"}, +{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"}, +{0,NULL} + }; + +static ERR_STRING_DATA TS_str_reasons[]= + { +{ERR_REASON(TS_R_BAD_PKCS7_TYPE) ,"bad pkcs7 type"}, +{ERR_REASON(TS_R_BAD_TYPE) ,"bad type"}, +{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"}, +{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE) ,"could not set engine"}, +{ERR_REASON(TS_R_COULD_NOT_SET_TIME) ,"could not set time"}, +{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"}, +{ERR_REASON(TS_R_DETACHED_CONTENT) ,"detached content"}, +{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"}, +{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"}, +{ERR_REASON(TS_R_INVALID_NULL_POINTER) ,"invalid null pointer"}, +{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"}, +{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"}, +{ERR_REASON(TS_R_NONCE_MISMATCH) ,"nonce mismatch"}, +{ERR_REASON(TS_R_NONCE_NOT_RETURNED) ,"nonce not returned"}, +{ERR_REASON(TS_R_NO_CONTENT) ,"no content"}, +{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN) ,"no time stamp token"}, +{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"}, +{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"}, +{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"}, +{ERR_REASON(TS_R_POLICY_MISMATCH) ,"policy mismatch"}, +{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"}, +{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR) ,"response setup error"}, +{ERR_REASON(TS_R_SIGNATURE_FAILURE) ,"signature failure"}, +{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"}, +{ERR_REASON(TS_R_TIME_SYSCALL_ERROR) ,"time syscall error"}, +{ERR_REASON(TS_R_TOKEN_NOT_PRESENT) ,"token not present"}, +{ERR_REASON(TS_R_TOKEN_PRESENT) ,"token present"}, +{ERR_REASON(TS_R_TSA_NAME_MISMATCH) ,"tsa name mismatch"}, +{ERR_REASON(TS_R_TSA_UNTRUSTED) ,"tsa untrusted"}, +{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR) ,"tst info setup error"}, +{ERR_REASON(TS_R_TS_DATASIGN) ,"ts datasign"}, +{ERR_REASON(TS_R_UNACCEPTABLE_POLICY) ,"unacceptable policy"}, +{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"}, +{ERR_REASON(TS_R_UNSUPPORTED_VERSION) ,"unsupported version"}, +{ERR_REASON(TS_R_WRONG_CONTENT_TYPE) ,"wrong content type"}, +{0,NULL} + }; + +#endif + +void ERR_load_TS_strings(void) + { +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(TS_str_functs[0].error) == NULL) + { + ERR_load_strings(0,TS_str_functs); + ERR_load_strings(0,TS_str_reasons); + } +#endif + } diff --git a/crypto/openssl/crypto/evp/evp_cnf.c b/crypto/openssl/crypto/ts/ts_lib.c similarity index 57% rename from crypto/openssl/crypto/evp/evp_cnf.c rename to crypto/openssl/crypto/ts/ts_lib.c index 2e4db30235..e8608dbf71 100644 --- a/crypto/openssl/crypto/evp/evp_cnf.c +++ b/crypto/openssl/crypto/ts/ts_lib.c @@ -1,9 +1,9 @@ -/* evp_cnf.c */ -/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL - * project 2007. +/* crypto/ts/ts_lib.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. */ /* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -57,69 +57,89 @@ */ #include -#include -#include #include "cryptlib.h" -#include -#include -#include +#include +#include #include -#ifdef OPENSSL_FIPS -#include -#endif +#include "ts.h" +/* Local function declarations. */ -/* Algorithm configuration module. */ +/* Function definitions. */ -static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) { - int i; - const char *oid_section; - STACK_OF(CONF_VALUE) *sktmp; - CONF_VALUE *oval; - oid_section = CONF_imodule_get_value(md); - if(!(sktmp = NCONF_get_section(cnf, oid_section))) + BIGNUM num_bn; + int result = 0; + char *hex; + + BN_init(&num_bn); + ASN1_INTEGER_to_BN(num, &num_bn); + if ((hex = BN_bn2hex(&num_bn))) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); - return 0; + result = BIO_write(bio, "0x", 2) > 0; + result = result && BIO_write(bio, hex, strlen(hex)) > 0; + OPENSSL_free(hex); } - for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) + BN_free(&num_bn); + + return result; + } + +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) + { + char obj_txt[128]; + + int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); + BIO_write(bio, obj_txt, len); + BIO_write(bio, "\n", 1); + + return 1; + } + +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions) + { + int i, critical, n; + X509_EXTENSION *ex; + ASN1_OBJECT *obj; + + BIO_printf(bio, "Extensions:\n"); + n = X509v3_get_ext_count(extensions); + for (i = 0; i < n; i++) { - oval = sk_CONF_VALUE_value(sktmp, i); - if (!strcmp(oval->name, "fips_mode")) - { - int m; - if (!X509V3_get_value_bool(oval, &m)) - { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); - return 0; - } - if (m > 0) - { -#ifdef OPENSSL_FIPS - if (!FIPS_mode() && !FIPS_mode_set(1)) - { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE); - return 0; - } -#else - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); - return 0; -#endif - } - } - else + ex = X509v3_get_ext(extensions, i); + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + critical = X509_EXTENSION_get_critical(ex); + BIO_printf(bio, ": %s\n", critical ? "critical" : ""); + if (!X509V3_EXT_print(bio, ex, 0, 4)) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); - ERR_add_error_data(4, "name=", oval->name, - ", value=", oval->value); + BIO_printf(bio, "%4s", ""); + M_ASN1_OCTET_STRING_print(bio, ex->value); } - + BIO_write(bio, "\n", 1); } + return 1; } -void EVP_add_alg_module(void) +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg) { - CONF_module_add("alg_section", alg_module_init, 0); + int i = OBJ_obj2nid(alg->algorithm); + return BIO_printf(bio, "Hash Algorithm: %s\n", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); + } + +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) + { + const ASN1_OCTET_STRING *msg; + + TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a)); + + BIO_printf(bio, "Message data:\n"); + msg = TS_MSG_IMPRINT_get_msg(a); + BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), + M_ASN1_STRING_length(msg), 4); + + return 1; } diff --git a/crypto/openssl/crypto/dh/dh_asn1.c b/crypto/openssl/crypto/ts/ts_req_print.c similarity index 72% copy from crypto/openssl/crypto/dh/dh_asn1.c copy to crypto/openssl/crypto/ts/ts_req_print.c index 76740af2bd..eba12c3824 100644 --- a/crypto/openssl/crypto/dh/dh_asn1.c +++ b/crypto/openssl/crypto/ts/ts_req_print.c @@ -1,9 +1,9 @@ -/* dh_asn1.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2000. +/* crypto/ts/ts_req_print.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -58,30 +58,45 @@ #include #include "cryptlib.h" -#include -#include #include -#include +#include +#include +#include -/* Override the default free and new methods */ -static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - if(operation == ASN1_OP_NEW_PRE) { - *pval = (ASN1_VALUE *)DH_new(); - if(*pval) return 2; - return 0; - } else if(operation == ASN1_OP_FREE_PRE) { - DH_free((DH *)*pval); - *pval = NULL; - return 2; - } - return 1; -} +/* Function definitions. */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a) + { + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *nonce; + + if (a == NULL) return 0; + + v = TS_REQ_get_version(a); + BIO_printf(bio, "Version: %d\n", v); -ASN1_SEQUENCE_cb(DHparams, dh_cb) = { - ASN1_SIMPLE(DH, p, BIGNUM), - ASN1_SIMPLE(DH, g, BIGNUM), - ASN1_OPT(DH, length, ZLONG), -} ASN1_SEQUENCE_END_cb(DH, DHparams) + TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a)); -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) + BIO_printf(bio, "Policy OID: "); + policy_id = TS_REQ_get_policy_id(a); + if (policy_id == NULL) + BIO_printf(bio, "unspecified\n"); + else + TS_OBJ_print_bio(bio, policy_id); + + BIO_printf(bio, "Nonce: "); + nonce = TS_REQ_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + BIO_printf(bio, "Certificate required: %s\n", + TS_REQ_get_cert_req(a) ? "yes" : "no"); + + TS_ext_print_bio(bio, TS_REQ_get_exts(a)); + + return 1; + } diff --git a/crypto/openssl/crypto/ts/ts_req_utils.c b/crypto/openssl/crypto/ts/ts_req_utils.c new file mode 100644 index 0000000000..43280c1587 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_req_utils.c @@ -0,0 +1,234 @@ +/* crypto/ts/ts_req_utils.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include + +int TS_REQ_set_version(TS_REQ *a, long version) + { + return ASN1_INTEGER_set(a->version, version); + } + +long TS_REQ_get_version(const TS_REQ *a) + { + return ASN1_INTEGER_get(a->version); + } + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) + { + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) + { + TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; + } + +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a) + { + return a->msg_imprint; + } + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) + { + X509_ALGOR *new_alg; + + if (a->hash_algo == alg) + return 1; + new_alg = X509_ALGOR_dup(alg); + if (new_alg == NULL) + { + TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE); + return 0; + } + X509_ALGOR_free(a->hash_algo); + a->hash_algo = new_alg; + return 1; + } + +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a) + { + return a->hash_algo; + } + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len) + { + return ASN1_OCTET_STRING_set(a->hashed_msg, d, len); + } + +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a) + { + return a->hashed_msg; + } + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy) + { + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) + { + TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; + } + +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a) + { + return a->policy_id; + } + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) + { + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) + { + TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; + } + +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a) + { + return a->nonce; + } + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req) + { + a->cert_req = cert_req ? 0xFF : 0x00; + return 1; + } + +int TS_REQ_get_cert_req(const TS_REQ *a) + { + return a->cert_req ? 1 : 0; + } + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a) + { + return a->extensions; + } + +void TS_REQ_ext_free(TS_REQ *a) + { + if (!a) return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; + } + +int TS_REQ_get_ext_count(TS_REQ *a) + { + return X509v3_get_ext_count(a->extensions); + } + +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos) + { + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); + } + +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos) + { + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); + } + +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos) + { + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); + } + +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc) + { + return X509v3_get_ext(a->extensions,loc); + } + +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc) + { + return X509v3_delete_ext(a->extensions,loc); + } + +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc) + { + return X509v3_add_ext(&a->extensions,ex,loc) != NULL; + } + +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx) + { + return X509V3_get_d2i(a->extensions, nid, crit, idx); + } diff --git a/crypto/openssl/crypto/ts/ts_rsp_print.c b/crypto/openssl/crypto/ts/ts_rsp_print.c new file mode 100644 index 0000000000..21062517ba --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_rsp_print.c @@ -0,0 +1,287 @@ +/* crypto/ts/ts_resp_print.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include +#include "ts.h" + +struct status_map_st + { + int bit; + const char *text; + }; + +/* Local function declarations. */ + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v); +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy); + +/* Function definitions. */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a) + { + TS_TST_INFO *tst_info; + + BIO_printf(bio, "Status info:\n"); + TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a)); + + BIO_printf(bio, "\nTST info:\n"); + tst_info = TS_RESP_get_tst_info(a); + if (tst_info != NULL) + TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a)); + else + BIO_printf(bio, "Not included.\n"); + + return 1; + } + +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a) + { + static const char *status_map[] = + { + "Granted.", + "Granted with modifications.", + "Rejected.", + "Waiting.", + "Revocation warning.", + "Revoked." + }; + static struct status_map_st failure_map[] = + { + { TS_INFO_BAD_ALG, + "unrecognized or unsupported algorithm identifier" }, + { TS_INFO_BAD_REQUEST, + "transaction not permitted or supported" }, + { TS_INFO_BAD_DATA_FORMAT, + "the data submitted has the wrong format" }, + { TS_INFO_TIME_NOT_AVAILABLE, + "the TSA's time source is not available" }, + { TS_INFO_UNACCEPTED_POLICY, + "the requested TSA policy is not supported by the TSA" }, + { TS_INFO_UNACCEPTED_EXTENSION, + "the requested extension is not supported by the TSA" }, + { TS_INFO_ADD_INFO_NOT_AVAILABLE, + "the additional information requested could not be understood " + "or is not available" }, + { TS_INFO_SYSTEM_FAILURE, + "the request cannot be handled due to system failure" }, + { -1, NULL } + }; + long status; + int i, lines = 0; + + /* Printing status code. */ + BIO_printf(bio, "Status: "); + status = ASN1_INTEGER_get(a->status); + if (0 <= status && status < (long)(sizeof(status_map)/sizeof(status_map[0]))) + BIO_printf(bio, "%s\n", status_map[status]); + else + BIO_printf(bio, "out of bounds\n"); + + /* Printing status description. */ + BIO_printf(bio, "Status description: "); + for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) + { + if (i > 0) + BIO_puts(bio, "\t"); + ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), + 0); + BIO_puts(bio, "\n"); + } + if (i == 0) + BIO_printf(bio, "unspecified\n"); + + /* Printing failure information. */ + BIO_printf(bio, "Failure info: "); + if (a->failure_info != NULL) + lines = TS_status_map_print(bio, failure_map, + a->failure_info); + if (lines == 0) + BIO_printf(bio, "unspecified"); + BIO_printf(bio, "\n"); + + return 1; + } + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v) + { + int lines = 0; + + for (; a->bit >= 0; ++a) + { + if (ASN1_BIT_STRING_get_bit(v, a->bit)) + { + if (++lines > 1) + BIO_printf(bio, ", "); + BIO_printf(bio, "%s", a->text); + } + } + + return lines; + } + +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a) + { + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *serial; + const ASN1_GENERALIZEDTIME *gtime; + TS_ACCURACY *accuracy; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name; + + if (a == NULL) return 0; + + /* Print version. */ + v = TS_TST_INFO_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + /* Print policy id. */ + BIO_printf(bio, "Policy OID: "); + policy_id = TS_TST_INFO_get_policy_id(a); + TS_OBJ_print_bio(bio, policy_id); + + /* Print message imprint. */ + TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a)); + + /* Print serial number. */ + BIO_printf(bio, "Serial number: "); + serial = TS_TST_INFO_get_serial(a); + if (serial == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, serial); + BIO_write(bio, "\n", 1); + + /* Print time stamp. */ + BIO_printf(bio, "Time stamp: "); + gtime = TS_TST_INFO_get_time(a); + ASN1_GENERALIZEDTIME_print(bio, gtime); + BIO_write(bio, "\n", 1); + + /* Print accuracy. */ + BIO_printf(bio, "Accuracy: "); + accuracy = TS_TST_INFO_get_accuracy(a); + if (accuracy == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ACCURACY_print_bio(bio, accuracy); + BIO_write(bio, "\n", 1); + + /* Print ordering. */ + BIO_printf(bio, "Ordering: %s\n", + TS_TST_INFO_get_ordering(a) ? "yes" : "no"); + + /* Print nonce. */ + BIO_printf(bio, "Nonce: "); + nonce = TS_TST_INFO_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + /* Print TSA name. */ + BIO_printf(bio, "TSA: "); + tsa_name = TS_TST_INFO_get_tsa(a); + if (tsa_name == NULL) + BIO_printf(bio, "unspecified"); + else + { + STACK_OF(CONF_VALUE) *nval; + if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL))) + X509V3_EXT_val_prn(bio, nval, 0, 0); + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + } + BIO_write(bio, "\n", 1); + + /* Print extensions. */ + TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a)); + + return 1; + } + +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy) + { + const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy); + const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy); + const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy); + + if (seconds != NULL) + TS_ASN1_INTEGER_print_bio(bio, seconds); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " seconds, "); + if (millis != NULL) + TS_ASN1_INTEGER_print_bio(bio, millis); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " millis, "); + if (micros != NULL) + TS_ASN1_INTEGER_print_bio(bio, micros); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " micros"); + + return 1; + } diff --git a/crypto/openssl/crypto/ts/ts_rsp_sign.c b/crypto/openssl/crypto/ts/ts_rsp_sign.c new file mode 100644 index 0000000000..b0f023c9d2 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_rsp_sign.c @@ -0,0 +1,1020 @@ +/* crypto/ts/ts_resp_sign.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 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 "cryptlib.h" + +#if defined(OPENSSL_SYS_UNIX) +#include +#endif + +#include +#include +#include + +/* Private function declarations. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); +static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); +static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx); +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx); +static int TS_RESP_check_request(TS_RESP_CTX *ctx); +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx); +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy); +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); +static int TS_RESP_sign(TS_RESP_CTX *ctx); + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs); +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); +static int TS_TST_INFO_content_new(PKCS7 *p7); +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); + +static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( + ASN1_GENERALIZEDTIME *, long, long, unsigned); + +/* Default callbacks for response generation. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) + { + ASN1_INTEGER *serial = ASN1_INTEGER_new(); + if (!serial) goto err; + if (!ASN1_INTEGER_set(serial, 1)) goto err; + return serial; + err: + TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Error during serial number generation."); + return NULL; + } + +#if defined(OPENSSL_SYS_UNIX) + +/* Use the gettimeofday function call. */ +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, + long *sec, long *usec) + { + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) + { + TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller. */ + *sec = tv.tv_sec; + *usec = tv.tv_usec; + + return 1; + } + +#else + +/* Use the time function call that provides only seconds precision. */ +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, + long *sec, long *usec) + { + time_t t; + if (time(&t) == (time_t) -1) + { + TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller, only second precision. */ + *sec = (long) t; + *usec = 0; + + return 1; + } + +#endif + +static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, + void *data) + { + /* No extensions are processed here. */ + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Unsupported extension."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); + return 0; + } + +/* TS_RESP_CTX management functions. */ + +TS_RESP_CTX *TS_RESP_CTX_new() + { + TS_RESP_CTX *ctx; + + if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX)))) + { + TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ctx, 0, sizeof(TS_RESP_CTX)); + + /* Setting default callbacks. */ + ctx->serial_cb = def_serial_cb; + ctx->time_cb = def_time_cb; + ctx->extension_cb = def_extension_cb; + + return ctx; + } + +void TS_RESP_CTX_free(TS_RESP_CTX *ctx) + { + if (!ctx) return; + + X509_free(ctx->signer_cert); + EVP_PKEY_free(ctx->signer_key); + sk_X509_pop_free(ctx->certs, X509_free); + sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); + ASN1_OBJECT_free(ctx->default_policy); + sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ + ASN1_INTEGER_free(ctx->seconds); + ASN1_INTEGER_free(ctx->millis); + ASN1_INTEGER_free(ctx->micros); + OPENSSL_free(ctx); + } + +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) + { + if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) + { + TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, + TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); + return 0; + } + if (ctx->signer_cert) X509_free(ctx->signer_cert); + ctx->signer_cert = signer; + CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); + return 1; + } + +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) + { + if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key); + ctx->signer_key = key; + CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); + + return 1; + } + +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy) + { + if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy); + if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err; + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); + return 0; + } + +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) + { + int i; + + if (ctx->certs) + { + sk_X509_pop_free(ctx->certs, X509_free); + ctx->certs = NULL; + } + if (!certs) return 1; + if (!(ctx->certs = sk_X509_dup(certs))) + { + TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < sk_X509_num(ctx->certs); ++i) + { + X509 *cert = sk_X509_value(ctx->certs, i); + CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509); + } + + return 1; + } + +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) + { + ASN1_OBJECT *copy = NULL; + + /* Create new policy stack if necessary. */ + if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) + goto err; + if (!(copy = OBJ_dup(policy))) goto err; + if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err; + + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(copy); + return 0; + } + +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) + { + /* Create new md stack if necessary. */ + if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) + goto err; + /* Add the shared md, no copy needed. */ + if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err; + + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); + return 0; + } + +#define TS_RESP_CTX_accuracy_free(ctx) \ + ASN1_INTEGER_free(ctx->seconds); \ + ctx->seconds = NULL; \ + ASN1_INTEGER_free(ctx->millis); \ + ctx->millis = NULL; \ + ASN1_INTEGER_free(ctx->micros); \ + ctx->micros = NULL; + +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros) + { + + TS_RESP_CTX_accuracy_free(ctx); + if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->seconds, secs))) + goto err; + if (millis && (!(ctx->millis = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->millis, millis))) + goto err; + if (micros && (!(ctx->micros = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->micros, micros))) + goto err; + + return 1; + err: + TS_RESP_CTX_accuracy_free(ctx); + TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + return 0; + } + +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) + { + ctx->flags |= flags; + } + +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) + { + ctx->serial_cb = cb; + ctx->serial_cb_data = data; + } + +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) + { + ctx->time_cb = cb; + ctx->time_cb_data = data; + } + +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data) + { + ctx->extension_cb = cb; + ctx->extension_cb_data = data; + } + +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text) + { + TS_STATUS_INFO *si = NULL; + ASN1_UTF8STRING *utf8_text = NULL; + int ret = 0; + + if (!(si = TS_STATUS_INFO_new())) goto err; + if (!ASN1_INTEGER_set(si->status, status)) goto err; + if (text) + { + if (!(utf8_text = ASN1_UTF8STRING_new()) + || !ASN1_STRING_set(utf8_text, text, strlen(text))) + goto err; + if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) + goto err; + if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err; + utf8_text = NULL; /* Ownership is lost. */ + } + if (!TS_RESP_set_status_info(ctx->response, si)) goto err; + ret = 1; + err: + if (!ret) + TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + TS_STATUS_INFO_free(si); + ASN1_UTF8STRING_free(utf8_text); + return ret; + } + +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text) + { + int ret = 1; + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + + if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) + { + /* Status has not been set, set it now. */ + ret = TS_RESP_CTX_set_status_info(ctx, status, text); + } + return ret; + } + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) + { + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) + goto err; + if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) + goto err; + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); + return 0; + } + +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) + { + return ctx->request; + } + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) + { + return ctx->tst_info; + } + +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision) + { + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + return 0; + ctx->clock_precision_digits = precision; + return 1; + } + +/* Main entry method of the response generation. */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) + { + ASN1_OBJECT *policy; + TS_RESP *response; + int result = 0; + + TS_RESP_CTX_init(ctx); + + /* Creating the response object. */ + if (!(ctx->response = TS_RESP_new())) + { + TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* Parsing DER request. */ + if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) + { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request format or " + "system error."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + goto end; + } + + /* Setting default status info. */ + if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) + goto end; + + /* Checking the request format. */ + if (!TS_RESP_check_request(ctx)) goto end; + + /* Checking acceptable policies. */ + if (!(policy = TS_RESP_get_policy(ctx))) goto end; + + /* Creating the TS_TST_INFO object. */ + if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) + goto end; + + /* Processing extensions. */ + if (!TS_RESP_process_extensions(ctx)) goto end; + + /* Generating the signature. */ + if (!TS_RESP_sign(ctx)) goto end; + + /* Everything was successful. */ + result = 1; + end: + if (!result) + { + TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); + if (ctx->response != NULL) + { + if (TS_RESP_CTX_set_status_info_cond(ctx, + TS_STATUS_REJECTION, "Error during response " + "generation.") == 0) + { + TS_RESP_free(ctx->response); + ctx->response = NULL; + } + } + } + response = ctx->response; + ctx->response = NULL; /* Ownership will be returned to caller. */ + TS_RESP_CTX_cleanup(ctx); + return response; + } + +/* Initializes the variable part of the context. */ +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) + { + ctx->request = NULL; + ctx->response = NULL; + ctx->tst_info = NULL; + } + +/* Cleans up the variable part of the context. */ +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) + { + TS_REQ_free(ctx->request); + ctx->request = NULL; + TS_RESP_free(ctx->response); + ctx->response = NULL; + TS_TST_INFO_free(ctx->tst_info); + ctx->tst_info = NULL; + } + +/* Checks the format and content of the request. */ +static int TS_RESP_check_request(TS_RESP_CTX *ctx) + { + TS_REQ *request = ctx->request; + TS_MSG_IMPRINT *msg_imprint; + X509_ALGOR *md_alg; + int md_alg_id; + const ASN1_OCTET_STRING *digest; + EVP_MD *md = NULL; + int i; + + /* Checking request version. */ + if (TS_REQ_get_version(request) != 1) + { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request version."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); + return 0; + } + + /* Checking message digest algorithm. */ + msg_imprint = TS_REQ_get_msg_imprint(request); + md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); + md_alg_id = OBJ_obj2nid(md_alg->algorithm); + for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) + { + EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); + if (md_alg_id == EVP_MD_type(current_md)) + md = current_md; + } + if (!md) + { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Message digest algorithm is " + "not supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + + /* No message digest takes parameter. */ + if (md_alg->parameter + && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) + { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Superfluous message digest " + "parameter."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + /* Checking message digest size. */ + digest = TS_MSG_IMPRINT_get_msg(msg_imprint); + if (digest->length != EVP_MD_size(md)) + { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad message digest."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + return 0; + } + + return 1; + } + +/* Returns the TSA policy based on the requested and acceptable policies. */ +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) + { + ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); + ASN1_OBJECT *policy = NULL; + int i; + + if (ctx->default_policy == NULL) + { + TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); + return NULL; + } + /* Return the default policy if none is requested or the default is + requested. */ + if (!requested || !OBJ_cmp(requested, ctx->default_policy)) + policy = ctx->default_policy; + + /* Check if the policy is acceptable. */ + for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) + { + ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); + if (!OBJ_cmp(requested, current)) + policy = current; + } + if (!policy) + { + TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Requested policy is not " + "supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); + } + return policy; + } + +/* Creates the TS_TST_INFO object based on the settings of the context. */ +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy) + { + int result = 0; + TS_TST_INFO *tst_info = NULL; + ASN1_INTEGER *serial = NULL; + ASN1_GENERALIZEDTIME *asn1_time = NULL; + long sec, usec; + TS_ACCURACY *accuracy = NULL; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name = NULL; + + if (!(tst_info = TS_TST_INFO_new())) goto end; + if (!TS_TST_INFO_set_version(tst_info, 1)) goto end; + if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end; + if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) + goto end; + if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data)) + || !TS_TST_INFO_set_serial(tst_info, serial)) + goto end; + if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec) + || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, + sec, usec, + ctx->clock_precision_digits)) + || !TS_TST_INFO_set_time(tst_info, asn1_time)) + goto end; + + /* Setting accuracy if needed. */ + if ((ctx->seconds || ctx->millis || ctx->micros) + && !(accuracy = TS_ACCURACY_new())) + goto end; + + if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) + goto end; + if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) + goto end; + if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros)) + goto end; + if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) + goto end; + + /* Setting ordering. */ + if ((ctx->flags & TS_ORDERING) + && !TS_TST_INFO_set_ordering(tst_info, 1)) + goto end; + + /* Setting nonce if needed. */ + if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL + && !TS_TST_INFO_set_nonce(tst_info, nonce)) + goto end; + + /* Setting TSA name to subject of signer certificate. */ + if (ctx->flags & TS_TSA_NAME) + { + if (!(tsa_name = GENERAL_NAME_new())) goto end; + tsa_name->type = GEN_DIRNAME; + tsa_name->d.dirn = + X509_NAME_dup(ctx->signer_cert->cert_info->subject); + if (!tsa_name->d.dirn) goto end; + if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end; + } + + result = 1; + end: + if (!result) + { + TS_TST_INFO_free(tst_info); + tst_info = NULL; + TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during TSTInfo " + "generation."); + } + GENERAL_NAME_free(tsa_name); + TS_ACCURACY_free(accuracy); + ASN1_GENERALIZEDTIME_free(asn1_time); + ASN1_INTEGER_free(serial); + + return tst_info; + } + +/* Processing the extensions of the request. */ +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) + { + STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); + int i; + int ok = 1; + + for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) + { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + /* XXXXX The last argument was previously + (void *)ctx->extension_cb, but ISO C doesn't permit + converting a function pointer to void *. For lack of + better information, I'm placing a NULL there instead. + The callback can pick its own address out from the ctx + anyway... + */ + ok = (*ctx->extension_cb)(ctx, ext, NULL); + } + + return ok; + } + +/* Functions for signing the TS_TST_INFO structure of the context. */ +static int TS_RESP_sign(TS_RESP_CTX *ctx) + { + int ret = 0; + PKCS7 *p7 = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *certs; /* Certificates to include in sc. */ + ESS_SIGNING_CERT *sc = NULL; + ASN1_OBJECT *oid; + BIO *p7bio = NULL; + int i; + + /* Check if signcert and pkey match. */ + if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { + TSerr(TS_F_TS_RESP_SIGN, + TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + /* Create a new PKCS7 signed object. */ + if (!(p7 = PKCS7_new())) { + TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err; + + /* Force SignedData version to be 3 instead of the default 1. */ + if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err; + + /* Add signer certificate and optional certificate chain. */ + if (TS_REQ_get_cert_req(ctx->request)) + { + PKCS7_add_certificate(p7, ctx->signer_cert); + if (ctx->certs) + { + for(i = 0; i < sk_X509_num(ctx->certs); ++i) + { + X509 *cert = sk_X509_value(ctx->certs, i); + PKCS7_add_certificate(p7, cert); + } + } + } + + /* Add a new signer info. */ + if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, + ctx->signer_key, EVP_sha1()))) + { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); + goto err; + } + + /* Add content type signed attribute to the signer info. */ + oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, oid)) + { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); + goto err; + } + + /* Create the ESS SigningCertificate attribute which contains + the signer certificate id and optionally the certificate chain. */ + certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; + if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) + goto err; + + /* Add SigningCertificate signed attribute to the signer info. */ + if (!ESS_add_signing_cert(si, sc)) + { + TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); + goto err; + } + + /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ + if (!TS_TST_INFO_content_new(p7)) goto err; + + /* Add the DER encoded tst_info to the PKCS7 structure. */ + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Convert tst_info to DER. */ + if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) + { + TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + goto err; + } + + /* Create the signature and add it to the signer info. */ + if (!PKCS7_dataFinal(p7, p7bio)) + { + TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + goto err; + } + + /* Set new PKCS7 and TST_INFO objects. */ + TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); + p7 = NULL; /* Ownership is lost. */ + ctx->tst_info = NULL; /* Ownership is lost. */ + + ret = 1; + err: + if (!ret) + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during signature " + "generation."); + BIO_free_all(p7bio); + ESS_SIGNING_CERT_free(sc); + PKCS7_free(p7); + return ret; + } + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs) + { + ESS_CERT_ID *cid; + ESS_SIGNING_CERT *sc = NULL; + int i; + + /* Creating the ESS_CERT_ID stack. */ + if (!(sc = ESS_SIGNING_CERT_new())) goto err; + if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) + goto err; + + /* Adding the signing certificate id. */ + if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + /* Adding the certificate chain ids. */ + for (i = 0; i < sk_X509_num(certs); ++i) + { + X509 *cert = sk_X509_value(certs, i); + if (!(cid = ESS_CERT_ID_new_init(cert, 1)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + } + + return sc; +err: + ESS_SIGNING_CERT_free(sc); + TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) + { + ESS_CERT_ID *cid = NULL; + GENERAL_NAME *name = NULL; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + if (!(cid = ESS_CERT_ID_new())) goto err; + if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, + sizeof(cert->sha1_hash))) + goto err; + + /* Setting the issuer/serial if requested. */ + if (issuer_needed) + { + /* Creating issuer/serial structure. */ + if (!cid->issuer_serial + && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) + goto err; + /* Creating general name from the certificate issuer. */ + if (!(name = GENERAL_NAME_new())) goto err; + name->type = GEN_DIRNAME; + if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) + goto err; + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + goto err; + name = NULL; /* Ownership is lost. */ + /* Setting the serial number. */ + ASN1_INTEGER_free(cid->issuer_serial->serial); + if (!(cid->issuer_serial->serial = + ASN1_INTEGER_dup(cert->cert_info->serialNumber))) + goto err; + } + + return cid; +err: + GENERAL_NAME_free(name); + ESS_CERT_ID_free(cid); + TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + +static int TS_TST_INFO_content_new(PKCS7 *p7) + { + PKCS7 *ret = NULL; + ASN1_OCTET_STRING *octet_string = NULL; + + /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ + if (!(ret = PKCS7_new())) goto err; + if (!(ret->d.other = ASN1_TYPE_new())) goto err; + ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!(octet_string = ASN1_OCTET_STRING_new())) goto err; + ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); + octet_string = NULL; + + /* Add encapsulated content to signed PKCS7 structure. */ + if (!PKCS7_set_content(p7, ret)) goto err; + + return 1; + err: + ASN1_OCTET_STRING_free(octet_string); + PKCS7_free(ret); + return 0; + } + +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) + { + ASN1_STRING *seq = NULL; + unsigned char *p, *pp = NULL; + int len; + + len = i2d_ESS_SIGNING_CERT(sc, NULL); + if (!(pp = (unsigned char *) OPENSSL_malloc(len))) + { + TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) + { + TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_free(pp); pp = NULL; + return PKCS7_add_signed_attribute(si, + NID_id_smime_aa_signingCertificate, + V_ASN1_SEQUENCE, seq); + err: + ASN1_STRING_free(seq); + OPENSSL_free(pp); + + return 0; + } + + +static ASN1_GENERALIZEDTIME * +TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, + long sec, long usec, unsigned precision) + { + time_t time_sec = (time_t) sec; + struct tm *tm = NULL; + char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; + char *p = genTime_str; + char *p_end = genTime_str + sizeof(genTime_str); + + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + goto err; + + + if (!(tm = gmtime(&time_sec))) + goto err; + + /* + * Put "genTime_str" in GeneralizedTime format. We work around the + * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST + * NOT include fractional seconds") and OpenSSL related functions to + * meet the rfc3161 requirement: "GeneralizedTime syntax can include + * fraction-of-second details". + */ + p += BIO_snprintf(p, p_end - p, + "%04d%02d%02d%02d%02d%02d", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + if (precision > 0) + { + /* Add fraction of seconds (leave space for dot and null). */ + BIO_snprintf(p, 2 + precision, ".%ld", usec); + /* We cannot use the snprintf return value, + because it might have been truncated. */ + p += strlen(p); + + /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides + the following restrictions for a DER-encoding, which OpenSSL + (specifically ASN1_GENERALIZEDTIME_check() function) doesn't + support: + "The encoding MUST terminate with a "Z" (which means "Zulu" + time). The decimal point element, if present, MUST be the + point option ".". The fractional-seconds elements, + if present, MUST omit all trailing 0's; + if the elements correspond to 0, they MUST be wholly + omitted, and the decimal point element also MUST be + omitted." */ + /* Remove trailing zeros. The dot guarantees the exit + condition of this loop even if all the digits are zero. */ + while (*--p == '0') + /* empty */; + /* p points to either the dot or the last non-zero digit. */ + if (*p != '.') ++p; + } + /* Add the trailing Z and the terminating null. */ + *p++ = 'Z'; + *p++ = '\0'; + + /* Now call OpenSSL to check and set our genTime value */ + if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new())) + goto err; + if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) + { + ASN1_GENERALIZEDTIME_free(asn1_time); + goto err; + } + + return asn1_time; + err: + TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); + return NULL; + } diff --git a/crypto/openssl/crypto/ts/ts_rsp_utils.c b/crypto/openssl/crypto/ts/ts_rsp_utils.c new file mode 100644 index 0000000000..401c1fdc51 --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_rsp_utils.c @@ -0,0 +1,409 @@ +/* crypto/ts/ts_resp_utils.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include + +/* Function definitions. */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) + { + TS_STATUS_INFO *new_status_info; + + if (a->status_info == status_info) + return 1; + new_status_info = TS_STATUS_INFO_dup(status_info); + if (new_status_info == NULL) + { + TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_STATUS_INFO_free(a->status_info); + a->status_info = new_status_info; + + return 1; + } + +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a) + { + return a->status_info; + } + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info) + { + /* Set new PKCS7 and TST_INFO objects. */ + PKCS7_free(a->token); + a->token = p7; + TS_TST_INFO_free(a->tst_info); + a->tst_info = tst_info; + } + +PKCS7 *TS_RESP_get_token(TS_RESP *a) + { + return a->token; + } + +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a) + { + return a->tst_info; + } + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version) + { + return ASN1_INTEGER_set(a->version, version); + } + +long TS_TST_INFO_get_version(const TS_TST_INFO *a) + { + return ASN1_INTEGER_get(a->version); + } + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) + { + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; + } + +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a) + { + return a->policy_id; + } + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) + { + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; + } + +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a) + { + return a->msg_imprint; + } + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) + { + ASN1_INTEGER *new_serial; + + if (a->serial == serial) + return 1; + new_serial = ASN1_INTEGER_dup(serial); + if (new_serial == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->serial); + a->serial = new_serial; + return 1; + } + +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a) + { + return a->serial; + } + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) + { + ASN1_GENERALIZEDTIME *new_time; + + if (a->time == gtime) + return 1; + new_time = M_ASN1_GENERALIZEDTIME_dup(gtime); + if (new_time == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_GENERALIZEDTIME_free(a->time); + a->time = new_time; + return 1; + } + +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a) + { + return a->time; + } + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) + { + TS_ACCURACY *new_accuracy; + + if (a->accuracy == accuracy) + return 1; + new_accuracy = TS_ACCURACY_dup(accuracy); + if (new_accuracy == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_ACCURACY_free(a->accuracy); + a->accuracy = new_accuracy; + return 1; + } + +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a) + { + return a->accuracy; + } + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) + { + ASN1_INTEGER *new_seconds; + + if (a->seconds == seconds) + return 1; + new_seconds = ASN1_INTEGER_dup(seconds); + if (new_seconds == NULL) + { + TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->seconds); + a->seconds = new_seconds; + return 1; + } + +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a) + { + return a->seconds; + } + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) + { + ASN1_INTEGER *new_millis = NULL; + + if (a->millis == millis) + return 1; + if (millis != NULL) + { + new_millis = ASN1_INTEGER_dup(millis); + if (new_millis == NULL) + { + TSerr(TS_F_TS_ACCURACY_SET_MILLIS, + ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->millis); + a->millis = new_millis; + return 1; + } + +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a) + { + return a->millis; + } + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) + { + ASN1_INTEGER *new_micros = NULL; + + if (a->micros == micros) + return 1; + if (micros != NULL) + { + new_micros = ASN1_INTEGER_dup(micros); + if (new_micros == NULL) + { + TSerr(TS_F_TS_ACCURACY_SET_MICROS, + ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->micros); + a->micros = new_micros; + return 1; + } + +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a) + { + return a->micros; + } + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering) + { + a->ordering = ordering ? 0xFF : 0x00; + return 1; + } + +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a) + { + return a->ordering ? 1 : 0; + } + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) + { + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; + } + +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a) + { + return a->nonce; + } + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) + { + GENERAL_NAME *new_tsa; + + if (a->tsa == tsa) + return 1; + new_tsa = GENERAL_NAME_dup(tsa); + if (new_tsa == NULL) + { + TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE); + return 0; + } + GENERAL_NAME_free(a->tsa); + a->tsa = new_tsa; + return 1; + } + +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a) + { + return a->tsa; + } + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a) + { + return a->extensions; + } + +void TS_TST_INFO_ext_free(TS_TST_INFO *a) + { + if (!a) return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; + } + +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a) + { + return X509v3_get_ext_count(a->extensions); + } + +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos) + { + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); + } + +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos) + { + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); + } + +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos) + { + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); + } + +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc) + { + return X509v3_get_ext(a->extensions,loc); + } + +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc) + { + return X509v3_delete_ext(a->extensions,loc); + } + +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc) + { + return X509v3_add_ext(&a->extensions,ex,loc) != NULL; + } + +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx) + { + return X509V3_get_d2i(a->extensions, nid, crit, idx); + } diff --git a/crypto/openssl/crypto/ts/ts_rsp_verify.c b/crypto/openssl/crypto/ts/ts_rsp_verify.c new file mode 100644 index 0000000000..e1f3b534af --- /dev/null +++ b/crypto/openssl/crypto/ts/ts_rsp_verify.c @@ -0,0 +1,725 @@ +/* crypto/ts/ts_resp_verify.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 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 +#include "cryptlib.h" +#include +#include +#include + +/* Private function declarations. */ + +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain); +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info); +static int TS_check_status_info(TS_RESP *response); +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len); +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info); +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); + +/* + * Local mapping between response codes and descriptions. + * Don't forget to change TS_STATUS_BUF_SIZE when modifying + * the elements of this array. + */ +static const char *TS_status_text[] = + { "granted", + "grantedWithMods", + "rejection", + "waiting", + "revocationWarning", + "revocationNotification" }; + +#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) + +/* + * This must be greater or equal to the sum of the strings in TS_status_text + * plus the number of its elements. + */ +#define TS_STATUS_BUF_SIZE 256 + +static struct + { + int code; + const char *text; + } TS_failure_info[] = + { { TS_INFO_BAD_ALG, "badAlg" }, + { TS_INFO_BAD_REQUEST, "badRequest" }, + { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" }, + { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" }, + { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" }, + { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" }, + { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" }, + { TS_INFO_SYSTEM_FAILURE, "systemFailure" } }; + +#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ + sizeof(*TS_failure_info)) + +/* Functions for verifying a signed TS_TST_INFO structure. */ + +/* + * This function carries out the following tasks: + * - Checks if there is one and only one signer. + * - Search for the signing certificate in 'certs' and in the response. + * - Check the extended key usage and key usage fields of the signer + * certificate (done by the path validation). + * - Build and validate the certificate path. + * - Check if the certificate path meets the requirements of the + * SigningCertificate ESS signed attribute. + * - Verify the signature value. + * - Returns the signer certificate in 'signer', if 'signer' is not NULL. + */ +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out) + { + STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *signers = NULL; + X509 *signer; + STACK_OF(X509) *chain = NULL; + char buf[4096]; + int i, j = 0, ret = 0; + BIO *p7bio = NULL; + + /* Some sanity checks first. */ + if (!token) + { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); + goto err; + } + + /* Check for the correct content type */ + if(!PKCS7_type_is_signed(token)) + { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); + goto err; + } + + /* Check if there is one and only one signer. */ + sinfos = PKCS7_get_signer_info(token); + if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) + { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, + TS_R_THERE_MUST_BE_ONE_SIGNER); + goto err; + } + si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); + + /* Check for no content: no data to verify signature. */ + if (PKCS7_get_detached(token)) + { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); + goto err; + } + + /* Get hold of the signer certificate, search only internal + certificates if it was requested. */ + signers = PKCS7_get0_signers(token, certs, 0); + if (!signers || sk_X509_num(signers) != 1) goto err; + signer = sk_X509_value(signers, 0); + + /* Now verify the certificate. */ + if (!TS_verify_cert(store, certs, signer, &chain)) goto err; + + /* Check if the signer certificate is consistent with the + ESS extension. */ + if (!TS_check_signing_certs(si, chain)) goto err; + + /* Creating the message digest. */ + p7bio = PKCS7_dataInit(token, NULL); + + /* We now have to 'read' from p7bio to calculate digests etc. */ + while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0); + + /* Verifying the signature. */ + j = PKCS7_signatureVerify(p7bio, token, si, signer); + if (j <= 0) + { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); + goto err; + } + + /* Return the signer certificate if needed. */ + if (signer_out) + { + *signer_out = signer; + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + } + + ret = 1; + + err: + BIO_free_all(p7bio); + sk_X509_pop_free(chain, X509_free); + sk_X509_free(signers); + + return ret; + } + +/* + * The certificate chain is returned in chain. Caller is responsible for + * freeing the vector. + */ +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain) + { + X509_STORE_CTX cert_ctx; + int i; + int ret = 1; + + /* chain is an out argument. */ + *chain = NULL; + X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted); + X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); + i = X509_verify_cert(&cert_ctx); + if (i <= 0) + { + int j = X509_STORE_CTX_get_error(&cert_ctx); + TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + ret = 0; + } + else + { + /* Get a copy of the certificate chain. */ + *chain = X509_STORE_CTX_get1_chain(&cert_ctx); + } + + X509_STORE_CTX_cleanup(&cert_ctx); + + return ret; + } + +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) + { + ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); + STACK_OF(ESS_CERT_ID) *cert_ids = NULL; + X509 *cert; + int i = 0; + int ret = 0; + + if (!ss) goto err; + cert_ids = ss->cert_ids; + /* The signer certificate must be the first in cert_ids. */ + cert = sk_X509_value(chain, 0); + if (TS_find_cert(cert_ids, cert) != 0) goto err; + + /* Check the other certificates of the chain if there are more + than one certificate ids in cert_ids. */ + if (sk_ESS_CERT_ID_num(cert_ids) > 1) + { + /* All the certificates of the chain must be in cert_ids. */ + for (i = 1; i < sk_X509_num(chain); ++i) + { + cert = sk_X509_value(chain, i); + if (TS_find_cert(cert_ids, cert) < 0) goto err; + } + } + ret = 1; + err: + if (!ret) + TSerr(TS_F_TS_CHECK_SIGNING_CERTS, + TS_R_ESS_SIGNING_CERTIFICATE_ERROR); + ESS_SIGNING_CERT_free(ss); + return ret; + } + +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) + { + ASN1_TYPE *attr; + const unsigned char *p; + attr = PKCS7_get_signed_attribute(si, + NID_id_smime_aa_signingCertificate); + if (!attr) return NULL; + p = attr->value.sequence->data; + return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); + } + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) + { + int i; + + if (!cert_ids || !cert) return -1; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) + { + ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); + + /* Check the SHA-1 hash first. */ + if (cid->hash->length == sizeof(cert->sha1_hash) + && !memcmp(cid->hash->data, cert->sha1_hash, + sizeof(cert->sha1_hash))) + { + /* Check the issuer/serial as well if specified. */ + ESS_ISSUER_SERIAL *is = cid->issuer_serial; + if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) + return i; + } + } + + return -1; + } + +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) + { + GENERAL_NAME *issuer; + + if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1; + + /* Check the issuer first. It must be a directory name. */ + issuer = sk_GENERAL_NAME_value(is->issuer, 0); + if (issuer->type != GEN_DIRNAME + || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) + return -1; + + /* Check the serial number, too. */ + if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber)) + return -1; + + return 0; + } + +/* + * Verifies whether 'response' contains a valid response with regards + * to the settings of the context: + * - Gives an error message if the TS_TST_INFO is not present. + * - Calls _TS_RESP_verify_token to verify the token content. + */ +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) + { + PKCS7 *token = TS_RESP_get_token(response); + TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); + int ret = 0; + + /* Check if we have a successful TS_TST_INFO object in place. */ + if (!TS_check_status_info(response)) goto err; + + /* Check the contents of the time stamp token. */ + if (!int_TS_RESP_verify_token(ctx, token, tst_info)) + goto err; + + ret = 1; + err: + return ret; + } + +/* + * Tries to extract a TS_TST_INFO structure from the PKCS7 token and + * calls the internal int_TS_RESP_verify_token function for verifying it. + */ +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) + { + TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); + int ret = 0; + if (tst_info) + { + ret = int_TS_RESP_verify_token(ctx, token, tst_info); + TS_TST_INFO_free(tst_info); + } + return ret; + } + +/* + * Verifies whether the 'token' contains a valid time stamp token + * with regards to the settings of the context. Only those checks are + * carried out that are specified in the context: + * - Verifies the signature of the TS_TST_INFO. + * - Checks the version number of the response. + * - Check if the requested and returned policies math. + * - Check if the message imprints are the same. + * - Check if the nonces are the same. + * - Check if the TSA name matches the signer. + * - Check if the TSA name is the expected TSA. + */ +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info) + { + X509 *signer = NULL; + GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); + X509_ALGOR *md_alg = NULL; + unsigned char *imprint = NULL; + unsigned imprint_len = 0; + int ret = 0; + + /* Verify the signature. */ + if ((ctx->flags & TS_VFY_SIGNATURE) + && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, + &signer)) + goto err; + + /* Check version number of response. */ + if ((ctx->flags & TS_VFY_VERSION) + && TS_TST_INFO_get_version(tst_info) != 1) + { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); + goto err; + } + + /* Check policies. */ + if ((ctx->flags & TS_VFY_POLICY) + && !TS_check_policy(ctx->policy, tst_info)) + goto err; + + /* Check message imprints. */ + if ((ctx->flags & TS_VFY_IMPRINT) + && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, + tst_info)) + goto err; + + /* Compute and check message imprints. */ + if ((ctx->flags & TS_VFY_DATA) + && (!TS_compute_imprint(ctx->data, tst_info, + &md_alg, &imprint, &imprint_len) + || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) + goto err; + + /* Check nonces. */ + if ((ctx->flags & TS_VFY_NONCE) + && !TS_check_nonces(ctx->nonce, tst_info)) + goto err; + + /* Check whether TSA name and signer certificate match. */ + if ((ctx->flags & TS_VFY_SIGNER) + && tsa_name && !TS_check_signer_name(tsa_name, signer)) + { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); + goto err; + } + + /* Check whether the TSA is the expected one. */ + if ((ctx->flags & TS_VFY_TSA_NAME) + && !TS_check_signer_name(ctx->tsa_name, signer)) + { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); + goto err; + } + + ret = 1; + err: + X509_free(signer); + X509_ALGOR_free(md_alg); + OPENSSL_free(imprint); + return ret; + } + +static int TS_check_status_info(TS_RESP *response) + { + TS_STATUS_INFO *info = TS_RESP_get_status_info(response); + long status = ASN1_INTEGER_get(info->status); + const char *status_text = NULL; + char *embedded_status_text = NULL; + char failure_text[TS_STATUS_BUF_SIZE] = ""; + + /* Check if everything went fine. */ + if (status == 0 || status == 1) return 1; + + /* There was an error, get the description in status_text. */ + if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) + status_text = TS_status_text[status]; + else + status_text = "unknown code"; + + /* Set the embedded_status_text to the returned description. */ + if (sk_ASN1_UTF8STRING_num(info->text) > 0 + && !(embedded_status_text = TS_get_status_text(info->text))) + return 0; + + /* Filling in failure_text with the failure information. */ + if (info->failure_info) + { + int i; + int first = 1; + for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) + { + if (ASN1_BIT_STRING_get_bit(info->failure_info, + TS_failure_info[i].code)) + { + if (!first) + strcpy(failure_text, ","); + else + first = 0; + strcat(failure_text, TS_failure_info[i].text); + } + } + } + if (failure_text[0] == '\0') + strcpy(failure_text, "unspecified"); + + /* Making up the error string. */ + TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); + ERR_add_error_data(6, + "status code: ", status_text, + ", status text: ", embedded_status_text ? + embedded_status_text : "unspecified", + ", failure codes: ", failure_text); + OPENSSL_free(embedded_status_text); + + return 0; + } + +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) + { + int i; + unsigned int length = 0; + char *result = NULL; + char *p; + + /* Determine length first. */ + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) + { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + length += ASN1_STRING_length(current); + length += 1; /* separator character */ + } + /* Allocate memory (closing '\0' included). */ + if (!(result = OPENSSL_malloc(length))) + { + TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Concatenate the descriptions. */ + for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) + { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + length = ASN1_STRING_length(current); + if (i > 0) *p++ = '/'; + strncpy(p, (const char *)ASN1_STRING_data(current), length); + p += length; + } + /* We do have space for this, too. */ + *p = '\0'; + + return result; + } + +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) + { + ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); + + if (OBJ_cmp(req_oid, resp_oid) != 0) + { + TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); + return 0; + } + + return 1; + } + +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len) + { + TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); + const EVP_MD *md; + EVP_MD_CTX md_ctx; + unsigned char buffer[4096]; + int length; + + *md_alg = NULL; + *imprint = NULL; + + /* Return the MD algorithm of the response. */ + if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err; + + /* Getting the MD object. */ + if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) + { + TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); + goto err; + } + + /* Compute message digest. */ + length = EVP_MD_size(md); + if (length < 0) + goto err; + *imprint_len = length; + if (!(*imprint = OPENSSL_malloc(*imprint_len))) + { + TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + EVP_DigestInit(&md_ctx, md); + while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) + { + EVP_DigestUpdate(&md_ctx, buffer, length); + } + EVP_DigestFinal(&md_ctx, *imprint, NULL); + + return 1; + err: + X509_ALGOR_free(*md_alg); + OPENSSL_free(*imprint); + *imprint_len = 0; + return 0; + } + +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info) + { + TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); + int ret = 0; + + /* algor_a is optional. */ + if (algor_a) + { + /* Compare algorithm OIDs. */ + if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err; + + /* The parameter must be NULL in both. */ + if ((algor_a->parameter + && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) + || (algor_b->parameter + && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) + goto err; + } + + /* Compare octet strings. */ + ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) && + memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; + err: + if (!ret) + TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); + return ret; + } + +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) + { + const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); + + /* Error if nonce is missing. */ + if (!b) + { + TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); + return 0; + } + + /* No error if a nonce is returned without being requested. */ + if (ASN1_INTEGER_cmp(a, b) != 0) + { + TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); + return 0; + } + + return 1; + } + +/* Check if the specified TSA name matches either the subject + or one of the subject alternative names of the TSA certificate. */ +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) + { + STACK_OF(GENERAL_NAME) *gen_names = NULL; + int idx = -1; + int found = 0; + + /* Check the subject name first. */ + if (tsa_name->type == GEN_DIRNAME + && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) + return 1; + + /* Check all the alternative names. */ + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, + NULL, &idx); + while (gen_names != NULL + && !(found = TS_find_name(gen_names, tsa_name) >= 0)) + { + /* Get the next subject alternative name, + although there should be no more than one. */ + GENERAL_NAMES_free(gen_names); + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, + NULL, &idx); + } + if (gen_names) GENERAL_NAMES_free(gen_names); + + return found; + } + +/* Returns 1 if name is in gen_names, 0 otherwise. */ +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) + { + int i, found; + for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); + ++i) + { + GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); + found = GENERAL_NAME_cmp(current, name) == 0; + } + return found ? i - 1 : -1; + } diff --git a/crypto/openssl/crypto/buffer/buf_str.c b/crypto/openssl/crypto/ts/ts_verify_ctx.c similarity index 52% rename from crypto/openssl/crypto/buffer/buf_str.c rename to crypto/openssl/crypto/ts/ts_verify_ctx.c index 28dd1e401e..b079b50fc3 100644 --- a/crypto/openssl/crypto/buffer/buf_str.c +++ b/crypto/openssl/crypto/ts/ts_verify_ctx.c @@ -1,6 +1,9 @@ -/* crypto/buffer/buf_str.c */ +/* crypto/ts/ts_verify_ctx.c */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2003. + */ /* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 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 @@ -53,64 +56,105 @@ * */ -#include +#include #include "cryptlib.h" -#include +#include +#include -char *BUF_strdup(const char *str) +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void) { - if (str == NULL) return(NULL); - return BUF_strndup(str, strlen(str)); + TS_VERIFY_CTX *ctx = + (TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX)); + if (ctx) + memset(ctx, 0, sizeof(TS_VERIFY_CTX)); + else + TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE); + return ctx; } -char *BUF_strndup(const char *str, size_t siz) +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx) { - char *ret; + assert(ctx != NULL); + memset(ctx, 0, sizeof(TS_VERIFY_CTX)); + } - if (str == NULL) return(NULL); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx) + { + if (!ctx) return; - ret=OPENSSL_malloc(siz+1); - if (ret == NULL) - { - BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE); - return(NULL); - } - BUF_strlcpy(ret,str,siz+1); - return(ret); + TS_VERIFY_CTX_cleanup(ctx); + OPENSSL_free(ctx); } -void *BUF_memdup(const void *data, size_t siz) +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) { - void *ret; + if (!ctx) return; - if (data == NULL) return(NULL); + X509_STORE_free(ctx->store); + sk_X509_pop_free(ctx->certs, X509_free); - ret=OPENSSL_malloc(siz); - if (ret == NULL) + ASN1_OBJECT_free(ctx->policy); + + X509_ALGOR_free(ctx->md_alg); + OPENSSL_free(ctx->imprint); + + BIO_free_all(ctx->data); + + ASN1_INTEGER_free(ctx->nonce); + + GENERAL_NAME_free(ctx->tsa_name); + + TS_VERIFY_CTX_init(ctx); + } + +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) + { + TS_VERIFY_CTX *ret = ctx; + ASN1_OBJECT *policy; + TS_MSG_IMPRINT *imprint; + X509_ALGOR *md_alg; + ASN1_OCTET_STRING *msg; + const ASN1_INTEGER *nonce; + + assert(req != NULL); + if (ret) + TS_VERIFY_CTX_cleanup(ret); + else + if (!(ret = TS_VERIFY_CTX_new())) return NULL; + + /* Setting flags. */ + ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE); + + /* Setting policy. */ + if ((policy = TS_REQ_get_policy_id(req)) != NULL) { - BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE); - return(NULL); + if (!(ret->policy = OBJ_dup(policy))) goto err; } - return memcpy(ret, data, siz); - } + else + ret->flags &= ~TS_VFY_POLICY; -size_t BUF_strlcpy(char *dst, const char *src, size_t size) - { - size_t l = 0; - for(; size > 1 && *src; size--) + /* Setting md_alg, imprint and imprint_len. */ + imprint = TS_REQ_get_msg_imprint(req); + md_alg = TS_MSG_IMPRINT_get_algo(imprint); + if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err; + msg = TS_MSG_IMPRINT_get_msg(imprint); + ret->imprint_len = ASN1_STRING_length(msg); + if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err; + memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len); + + /* Setting nonce. */ + if ((nonce = TS_REQ_get_nonce(req)) != NULL) { - *dst++ = *src++; - l++; + if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err; } - if (size) - *dst = '\0'; - return l + strlen(src); - } + else + ret->flags &= ~TS_VFY_NONCE; -size_t BUF_strlcat(char *dst, const char *src, size_t size) - { - size_t l = 0; - for(; size > 0 && *dst; size--, dst++) - l++; - return l + BUF_strlcpy(dst, src, size); + return ret; + err: + if (ctx) + TS_VERIFY_CTX_cleanup(ctx); + else + TS_VERIFY_CTX_free(ret); + return NULL; } diff --git a/crypto/openssl/crypto/txt_db/txt_db.c b/crypto/openssl/crypto/txt_db/txt_db.c index 3ed5f72ee9..6f2ce3b5a4 100644 --- a/crypto/openssl/crypto/txt_db/txt_db.c +++ b/crypto/openssl/crypto/txt_db/txt_db.c @@ -77,22 +77,23 @@ TXT_DB *TXT_DB_read(BIO *in, int num) int i,add,n; int size=BUFSIZE; int offset=0; - char *p,**pp,*f; + char *p,*f; + OPENSSL_STRING *pp; BUF_MEM *buf=NULL; if ((buf=BUF_MEM_new()) == NULL) goto err; if (!BUF_MEM_grow(buf,size)) goto err; - if ((ret=(TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL) + if ((ret=OPENSSL_malloc(sizeof(TXT_DB))) == NULL) goto err; ret->num_fields=num; ret->index=NULL; ret->qual=NULL; - if ((ret->data=sk_new_null()) == NULL) + if ((ret->data=sk_OPENSSL_PSTRING_new_null()) == NULL) goto err; - if ((ret->index=(LHASH **)OPENSSL_malloc(sizeof(LHASH *)*num)) == NULL) + if ((ret->index=OPENSSL_malloc(sizeof(*ret->index)*num)) == NULL) goto err; - if ((ret->qual=(int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **))*num)) == NULL) + if ((ret->qual=OPENSSL_malloc(sizeof(*(ret->qual))*num)) == NULL) goto err; for (i=0; idata[offset-1]='\0'; /* blat the '\n' */ - if (!(p=(char *)OPENSSL_malloc(add+offset))) goto err; + if (!(p=OPENSSL_malloc(add+offset))) goto err; offset=0; } pp=(char **)p; @@ -155,16 +156,16 @@ TXT_DB *TXT_DB_read(BIO *in, int num) *(p++)='\0'; if ((n != num) || (*f != '\0')) { -#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */ +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary fix :-( */ fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f); #endif er=2; goto err; } pp[n]=p; - if (!sk_push(ret->data,(char *)pp)) + if (!sk_OPENSSL_PSTRING_push(ret->data,pp)) { -#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */ +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary fix :-( */ fprintf(stderr,"failure in sk_push\n"); #endif er=2; @@ -181,7 +182,7 @@ err: #endif if (ret != NULL) { - if (ret->data != NULL) sk_free(ret->data); + if (ret->data != NULL) sk_OPENSSL_PSTRING_free(ret->data); if (ret->index != NULL) OPENSSL_free(ret->index); if (ret->qual != NULL) OPENSSL_free(ret->qual); if (ret != NULL) OPENSSL_free(ret); @@ -192,10 +193,10 @@ err: return(ret); } -char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value) +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value) { - char **ret; - LHASH *lh; + OPENSSL_STRING *ret; + LHASH_OF(OPENSSL_STRING) *lh; if (idx >= db->num_fields) { @@ -208,16 +209,16 @@ char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value) db->error=DB_ERROR_NO_INDEX; return(NULL); } - ret=(char **)lh_retrieve(lh,value); + ret=lh_OPENSSL_STRING_retrieve(lh,value); db->error=DB_ERROR_OK; return(ret); } -int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **), - LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) { - LHASH *idx; - char **r; + LHASH_OF(OPENSSL_STRING) *idx; + OPENSSL_STRING *r; int i,n; if (field >= db->num_fields) @@ -225,26 +226,27 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **), db->error=DB_ERROR_INDEX_OUT_OF_RANGE; return(0); } - if ((idx=lh_new(hash,cmp)) == NULL) + /* FIXME: we lose type checking at this point */ + if ((idx=(LHASH_OF(OPENSSL_STRING) *)lh_new(hash,cmp)) == NULL) { db->error=DB_ERROR_MALLOC; return(0); } - n=sk_num(db->data); + n=sk_OPENSSL_PSTRING_num(db->data); for (i=0; idata,i); + r=sk_OPENSSL_PSTRING_value(db->data,i); if ((qual != NULL) && (qual(r) == 0)) continue; - if ((r=lh_insert(idx,r)) != NULL) + if ((r=lh_OPENSSL_STRING_insert(idx,r)) != NULL) { db->error=DB_ERROR_INDEX_CLASH; - db->arg1=sk_find(db->data,(char *)r); + db->arg1=sk_OPENSSL_PSTRING_find(db->data,r); db->arg2=i; - lh_free(idx); + lh_OPENSSL_STRING_free(idx); return(0); } } - if (db->index[field] != NULL) lh_free(db->index[field]); + if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]); db->index[field]=idx; db->qual[field]=qual; return(1); @@ -259,11 +261,11 @@ long TXT_DB_write(BIO *out, TXT_DB *db) if ((buf=BUF_MEM_new()) == NULL) goto err; - n=sk_num(db->data); + n=sk_OPENSSL_PSTRING_num(db->data); nn=db->num_fields; for (i=0; idata,i); + pp=sk_OPENSSL_PSTRING_value(db->data,i); l=0; for (j=0; jnum_fields; i++) { @@ -309,7 +311,7 @@ int TXT_DB_insert(TXT_DB *db, char **row) { if ((db->qual[i] != NULL) && (db->qual[i](row) == 0)) continue; - r=(char **)lh_retrieve(db->index[i],row); + r=lh_OPENSSL_STRING_retrieve(db->index[i],row); if (r != NULL) { db->error=DB_ERROR_INDEX_CLASH; @@ -320,7 +322,7 @@ int TXT_DB_insert(TXT_DB *db, char **row) } } /* We have passed the index checks, now just append and insert */ - if (!sk_push(db->data,(char *)row)) + if (!sk_OPENSSL_PSTRING_push(db->data,row)) { db->error=DB_ERROR_MALLOC; goto err; @@ -332,7 +334,7 @@ int TXT_DB_insert(TXT_DB *db, char **row) { if ((db->qual[i] != NULL) && (db->qual[i](row) == 0)) continue; - lh_insert(db->index[i],row); + (void)lh_OPENSSL_STRING_insert(db->index[i],row); } } return(1); @@ -351,18 +353,18 @@ void TXT_DB_free(TXT_DB *db) if (db->index != NULL) { for (i=db->num_fields-1; i>=0; i--) - if (db->index[i] != NULL) lh_free(db->index[i]); + if (db->index[i] != NULL) lh_OPENSSL_STRING_free(db->index[i]); OPENSSL_free(db->index); } if (db->qual != NULL) OPENSSL_free(db->qual); if (db->data != NULL) { - for (i=sk_num(db->data)-1; i>=0; i--) + for (i=sk_OPENSSL_PSTRING_num(db->data)-1; i>=0; i--) { /* check if any 'fields' have been allocated * from outside of the initial block */ - p=(char **)sk_value(db->data,i); + p=sk_OPENSSL_PSTRING_value(db->data,i); max=p[db->num_fields]; /* last address */ if (max == NULL) /* new row */ { @@ -378,9 +380,9 @@ void TXT_DB_free(TXT_DB *db) OPENSSL_free(p[n]); } } - OPENSSL_free(sk_value(db->data,i)); + OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data,i)); } - sk_free(db->data); + sk_OPENSSL_PSTRING_free(db->data); } OPENSSL_free(db); } diff --git a/crypto/openssl/crypto/txt_db/txt_db.h b/crypto/openssl/crypto/txt_db/txt_db.h index 307e1ba23f..6abe435bc8 100644 --- a/crypto/openssl/crypto/txt_db/txt_db.h +++ b/crypto/openssl/crypto/txt_db/txt_db.h @@ -77,16 +77,19 @@ extern "C" { #endif +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + typedef struct txt_db_st { int num_fields; - STACK /* char ** */ *data; - LHASH **index; - int (**qual)(char **); + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual)(OPENSSL_STRING *); long error; long arg1; long arg2; - char **arg_row; + OPENSSL_STRING *arg_row; } TXT_DB; #ifndef OPENSSL_NO_BIO @@ -96,11 +99,11 @@ long TXT_DB_write(BIO *out, TXT_DB *db); TXT_DB *TXT_DB_read(char *in, int num); long TXT_DB_write(char *out, TXT_DB *db); #endif -int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **), - LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); +int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); void TXT_DB_free(TXT_DB *db); -char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value); -int TXT_DB_insert(TXT_DB *db,char **value); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); #ifdef __cplusplus } diff --git a/crypto/openssl/crypto/ui/ui.h b/crypto/openssl/crypto/ui/ui.h index 018296412b..2b1cfa2289 100644 --- a/crypto/openssl/crypto/ui/ui.h +++ b/crypto/openssl/crypto/ui/ui.h @@ -287,8 +287,8 @@ UI_METHOD *UI_OpenSSL(void); /* The UI_STRING type is the data structure that contains all the needed info about a string or a prompt, including test data for a verification prompt. */ -DECLARE_STACK_OF(UI_STRING) typedef struct ui_string_st UI_STRING; +DECLARE_STACK_OF(UI_STRING) /* The different types of strings that are currently supported. This is only needed by method authors. */ @@ -310,11 +310,13 @@ int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)); int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)); int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)); +int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name)); int (*UI_method_get_opener(UI_METHOD *method))(UI*); int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*); int (*UI_method_get_flusher(UI_METHOD *method))(UI*); int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*); int (*UI_method_get_closer(UI_METHOD *method))(UI*); +char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*); /* The following functions are helpers for method writers to access relevant data from a UI_STRING. */ diff --git a/crypto/openssl/crypto/ui/ui_err.c b/crypto/openssl/crypto/ui/ui_err.c index 786bd0dbc3..a6b96299a0 100644 --- a/crypto/openssl/crypto/ui/ui_err.c +++ b/crypto/openssl/crypto/ui/ui_err.c @@ -1,6 +1,6 @@ /* crypto/ui/ui_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 diff --git a/crypto/openssl/crypto/ui/ui_lib.c b/crypto/openssl/crypto/ui/ui_lib.c index ac0100808f..a8abc27064 100644 --- a/crypto/openssl/crypto/ui/ui_lib.c +++ b/crypto/openssl/crypto/ui/ui_lib.c @@ -693,6 +693,17 @@ int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)) return -1; } +int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name)) + { + if (method) + { + method->ui_construct_prompt = prompt_constructor; + return 0; + } + else + return -1; + } + int (*UI_method_get_opener(UI_METHOD *method))(UI*) { if (method) @@ -733,6 +744,14 @@ int (*UI_method_get_closer(UI_METHOD *method))(UI*) return NULL; } +char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*) + { + if (method) + return method->ui_construct_prompt; + else + return NULL; + } + enum UI_string_types UI_get_string_type(UI_STRING *uis) { if (!uis) diff --git a/crypto/openssl/crypto/ui/ui_openssl.c b/crypto/openssl/crypto/ui/ui_openssl.c index 06270f09cd..1bc25f48d5 100644 --- a/crypto/openssl/crypto/ui/ui_openssl.c +++ b/crypto/openssl/crypto/ui/ui_openssl.c @@ -122,7 +122,9 @@ * sigaction and fileno included. -pedantic would be more appropriate for * the intended purposes, but we can't prevent users from adding -ansi. */ -#define _POSIX_C_SOURCE 1 +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 2 +#endif #include #include #include @@ -476,7 +478,7 @@ static int open_console(UI *ui) CRYPTO_w_lock(CRYPTO_LOCK_UI); is_a_tty = 1; -#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) tty_in=stdin; tty_out=stderr; #else diff --git a/crypto/openssl/crypto/whrlpool/whrlpool.h b/crypto/openssl/crypto/whrlpool/whrlpool.h new file mode 100644 index 0000000000..03c91da115 --- /dev/null +++ b/crypto/openssl/crypto/whrlpool/whrlpool.h @@ -0,0 +1,38 @@ +#ifndef HEADER_WHRLPOOL_H +#define HEADER_WHRLPOOL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WHIRLPOOL_DIGEST_LENGTH (512/8) +#define WHIRLPOOL_BBLOCK 512 +#define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK/8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)]; + } WHIRLPOOL_CTX; + +#ifndef OPENSSL_NO_WHIRLPOOL +int WHIRLPOOL_Init (WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits); +int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/openssl/crypto/whrlpool/wp_block.c b/crypto/openssl/crypto/whrlpool/wp_block.c new file mode 100644 index 0000000000..221f6cc59f --- /dev/null +++ b/crypto/openssl/crypto/whrlpool/wp_block.c @@ -0,0 +1,655 @@ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + * + */ + +#include "wp_locl.h" +#include + +typedef unsigned char u8; +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32) +typedef unsigned __int64 u64; +#elif defined(__arch64__) +typedef unsigned long u64; +#else +typedef unsigned long long u64; +#endif + +#define ROUNDS 10 + +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) +/* Well, formally there're couple of other architectures, which permit + * unaligned loads, specifically those not crossing cache lines, IA-64 + * and PowerPC... */ +# undef STRICT_ALIGNMENT +#endif + +#undef SMALL_REGISTER_BANK +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define SMALL_REGISTER_BANK +# if defined(WHIRLPOOL_ASM) +# ifndef OPENSSL_SMALL_FOOTPRINT +# define OPENSSL_SMALL_FOOTPRINT /* it appears that for elder non-MMX + CPUs this is actually faster! */ +# endif +# define GO_FOR_MMX(ctx,inp,num) do { \ + extern unsigned long OPENSSL_ia32cap_P; \ + void whirlpool_block_mmx(void *,const void *,size_t); \ + if (!(OPENSSL_ia32cap_P & (1<<23))) break; \ + whirlpool_block_mmx(ctx->H.c,inp,num); return; \ + } while (0) +# endif +#endif + +#undef ROTATE +#if defined(_MSC_VER) +# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# pragma intrinsic(_rotl64) +# define ROTATE(a,n) _rotl64((a),n) +# endif +#elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# if defined(L_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# elif defined(B_ENDIAN) + /* Most will argue that x86_64 is always little-endian. Well, + * yes, but then we have stratus.com who has modified gcc to + * "emulate" big-endian on x86. Is there evidence that they + * [or somebody else] won't do same for x86_64? Naturally no. + * And this line is waiting ready for that brave soul:-) */ +# define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# endif +# elif defined(__ia64) || defined(__ia64__) +# if defined(L_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) +# elif defined(B_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(n)); ret; }) +# endif +# endif +#endif + +#if defined(OPENSSL_SMALL_FOOTPRINT) +# if !defined(ROTATE) +# if defined(L_ENDIAN) /* little-endians have to rotate left */ +# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) +# elif defined(B_ENDIAN) /* big-endians have to rotate right */ +# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) +# endif +# endif +# if defined(ROTATE) && !defined(STRICT_ALIGNMENT) +# define STRICT_ALIGNMENT /* ensure smallest table size */ +# endif +#endif + +/* + * Table size depends on STRICT_ALIGNMENT and whether or not endian- + * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not + * defined, which is normally the case on x86[_64] CPUs, the table is + * 4KB large unconditionally. Otherwise if ROTATE is defined, the + * table is 2KB large, and otherwise - 16KB. 2KB table requires a + * whole bunch of additional rotations, but I'm willing to "trade," + * because 16KB table certainly trashes L1 cache. I wish all CPUs + * could handle unaligned load as 4KB table doesn't trash the cache, + * nor does it require additional rotations. + */ +/* + * Note that every Cn macro expands as two loads: one byte load and + * one quadword load. One can argue that that many single-byte loads + * is too excessive, as one could load a quadword and "milk" it for + * eight 8-bit values instead. Well, yes, but in order to do so *and* + * avoid excessive loads you have to accomodate a handful of 64-bit + * values in the register bank and issue a bunch of shifts and mask. + * It's a tradeoff: loads vs. shift and mask in big register bank[!]. + * On most CPUs eight single-byte loads are faster and I let other + * ones to depend on smart compiler to fold byte loads if beneficial. + * Hand-coded assembler would be another alternative:-) + */ +#ifdef STRICT_ALIGNMENT +# if defined(ROTATE) +# define N 1 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) +# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) +# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) +# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) +# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) +# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) +# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) +# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) +# else +# define N 8 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c7,c0,c1,c2,c3,c4,c5,c6, \ + c6,c7,c0,c1,c2,c3,c4,c5, \ + c5,c6,c7,c0,c1,c2,c3,c4, \ + c4,c5,c6,c7,c0,c1,c2,c3, \ + c3,c4,c5,c6,c7,c0,c1,c2, \ + c2,c3,c4,c5,c6,c7,c0,c1, \ + c1,c2,c3,c4,c5,c6,c7,c0 +# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) +# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) +# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) +# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) +# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) +# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) +# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) +# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) +# endif +#else +# define N 2 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) +# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) +# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) +# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) +# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) +# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) +# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) +# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) +#endif + +static const +union { + u8 c[(256*N+ROUNDS)*sizeof(u64)]; + u64 q[(256*N+ROUNDS)]; + } Cx = { { + /* Note endian-neutral representation:-) */ + LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8), + LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26), + LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8), + LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb), + LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb), + LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11), + LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09), + LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d), + LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b), + LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff), + LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c), + LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e), + LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96), + LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30), + LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d), + LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8), + LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47), + LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35), + LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37), + LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a), + LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2), + LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c), + LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84), + LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80), + LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5), + LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3), + LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21), + LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c), + LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43), + LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29), + LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d), + LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5), + LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd), + LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8), + LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92), + LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e), + LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13), + LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23), + LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20), + LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44), + LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2), + LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf), + LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c), + LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a), + LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50), + LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9), + LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14), + LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9), + LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c), + LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f), + LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90), + LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07), + LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd), + LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3), + LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d), + LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78), + LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97), + LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02), + LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73), + LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7), + LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6), + LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2), + LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49), + LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56), + LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70), + LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd), + LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb), + LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71), + LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b), + LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf), + LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45), + LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a), + LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4), + LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58), + LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e), + LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f), + LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac), + LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0), + LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef), + LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6), + LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c), + LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12), + LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93), + LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde), + LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6), + LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1), + LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b), + LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f), + LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31), + LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8), + LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9), + LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc), + LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e), + LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b), + LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf), + LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59), + LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2), + LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77), + LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33), + LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4), + LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27), + LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb), + LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89), + LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32), + LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54), + LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d), + LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64), + LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d), + LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d), + LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f), + LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca), + LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7), + LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d), + LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce), + LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f), + LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f), + LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63), + LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a), + LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc), + LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82), + LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a), + LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48), + LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95), + LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf), + LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d), + LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0), + LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91), + LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8), + LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b), + LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00), + LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9), + LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e), + LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1), + LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6), + LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28), + LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3), + LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74), + LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe), + LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d), + LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea), + LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57), + LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38), + LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad), + LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4), + LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda), + LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7), + LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb), + LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9), + LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a), + LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03), + LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a), + LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e), + LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60), + LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc), + LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46), + LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f), + LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76), + LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa), + LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36), + LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae), + LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b), + LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85), + LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e), + LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7), + LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55), + LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a), + LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81), + LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52), + LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62), + LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3), + LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10), + LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab), + LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0), + LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5), + LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec), + LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16), + LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94), + LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f), + LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5), + LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98), + LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17), + LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4), + LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1), + LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e), + LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42), + LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34), + LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08), + LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee), + LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61), + LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1), + LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f), + LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24), + LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3), + LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25), + LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22), + LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65), + LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79), + LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69), + LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9), + LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19), + LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe), + LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a), + LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0), + LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99), + LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83), + LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04), + LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66), + LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0), + LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1), + LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd), + LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40), + LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c), + LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18), + LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b), + LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51), + LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05), + LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c), + LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39), + LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa), + LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b), + LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc), + LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e), + LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0), + LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88), + LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67), + LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a), + LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87), + LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1), + LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72), + LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53), + LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01), + LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b), + LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4), + LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3), + LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15), + LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c), + LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5), + LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5), + LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4), + LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba), + LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6), + LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7), + LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06), + LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41), + LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7), + LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f), + LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e), + LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6), + LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2), + LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68), + LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c), + LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed), + LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75), + LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86), + LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b), + LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2), +#define RC (&(Cx.q[256*N])) + 0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f, /* rc[ROUNDS] */ + 0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52, + 0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35, + 0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57, + 0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda, + 0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85, + 0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67, + 0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8, + 0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e, + 0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33 + } +}; + +void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n) + { + int r; + const u8 *p=inp; + union { u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q; + +#ifdef GO_FOR_MMX + GO_FOR_MMX(ctx,inp,n); +#endif + do { +#ifdef OPENSSL_SMALL_FOOTPRINT + u64 L[8]; + int i; + + for (i=0;i<64;i++) S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; + for (r=0;rc[i] ^= S.c[i] ^ p[i]; +#else + u64 L0,L1,L2,L3,L4,L5,L6,L7; + +#ifdef STRICT_ALIGNMENT + if ((size_t)p & 7) + { + memcpy (S.c,p,64); + S.q[0] ^= (K.q[0] = H->q[0]); + S.q[1] ^= (K.q[1] = H->q[1]); + S.q[2] ^= (K.q[2] = H->q[2]); + S.q[3] ^= (K.q[3] = H->q[3]); + S.q[4] ^= (K.q[4] = H->q[4]); + S.q[5] ^= (K.q[5] = H->q[5]); + S.q[6] ^= (K.q[6] = H->q[6]); + S.q[7] ^= (K.q[7] = H->q[7]); + } + else +#endif + { + const u64 *pa = (const u64*)p; + S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; + S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; + S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; + S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; + S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; + S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; + S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; + S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; + } + + for(r=0;rc[i] ^= S.c[i] ^ p[i]; + } + else +#endif + { + const u64 *pa=(const u64 *)p; + H->q[0] ^= S.q[0] ^ pa[0]; + H->q[1] ^= S.q[1] ^ pa[1]; + H->q[2] ^= S.q[2] ^ pa[2]; + H->q[3] ^= S.q[3] ^ pa[3]; + H->q[4] ^= S.q[4] ^ pa[4]; + H->q[5] ^= S.q[5] ^ pa[5]; + H->q[6] ^= S.q[6] ^ pa[6]; + H->q[7] ^= S.q[7] ^ pa[7]; + } +#endif + p += 64; + } while(--n); + } diff --git a/crypto/openssl/crypto/whrlpool/wp_dgst.c b/crypto/openssl/crypto/whrlpool/wp_dgst.c new file mode 100644 index 0000000000..ee5c5c1bf3 --- /dev/null +++ b/crypto/openssl/crypto/whrlpool/wp_dgst.c @@ -0,0 +1,264 @@ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + * + */ + +/* + * OpenSSL-specific implementation notes. + * + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect + * number of *bytes* as input length argument. Bit-oriented routine + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and + * does not have one-stroke counterpart. + * + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially + * to serve WHIRLPOOL_Update. This is done for performance. + * + * Unlike authors' reference implementation, block processing + * routine whirlpool_block is designed to operate on multi-block + * input. This is done for perfomance. + */ + +#include "wp_locl.h" +#include + +int WHIRLPOOL_Init (WHIRLPOOL_CTX *c) + { + memset (c,0,sizeof(*c)); + return(1); + } + +int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *_inp,size_t bytes) + { + /* Well, largest suitable chunk size actually is + * (1<<(sizeof(size_t)*8-3))-64, but below number + * is large enough for not to care about excessive + * calls to WHIRLPOOL_BitUpdate... */ + size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4); + const unsigned char *inp = _inp; + + while (bytes>=chunk) + { + WHIRLPOOL_BitUpdate(c,inp,chunk*8); + bytes -= chunk; + inp += chunk; + } + if (bytes) + WHIRLPOOL_BitUpdate(c,inp,bytes*8); + + return(1); + } + +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits) + { + size_t n; + unsigned int bitoff = c->bitoff, + bitrem = bitoff%8, + inpgap = (8-(unsigned int)bits%8)&7; + const unsigned char *inp=_inp; + + /* This 256-bit increment procedure relies on the size_t + * being natural size of CPU register, so that we don't + * have to mask the value in order to detect overflows. */ + c->bitlen[0] += bits; + if (c->bitlen[0] < bits) /* overflow */ + { + n = 1; + do { c->bitlen[n]++; + } while(c->bitlen[n]==0 + && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t))); + } + +#ifndef OPENSSL_SMALL_FOOTPRINT + reconsider: + if (inpgap==0 && bitrem==0) /* byte-oriented loop */ + { + while (bits) + { + if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK)) + { + whirlpool_block(c,inp,n); + inp += n*WHIRLPOOL_BBLOCK/8; + bits %= WHIRLPOOL_BBLOCK; + } + else + { + unsigned int byteoff = bitoff/8; + + bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */ + if (bits >= bitrem) + { + bits -= bitrem; + bitrem /= 8; + memcpy(c->data+byteoff,inp,bitrem); + inp += bitrem; + whirlpool_block(c,c->data,1); + bitoff = 0; + } + else + { + memcpy(c->data+byteoff,inp,bits/8); + bitoff += (unsigned int)bits; + bits = 0; + } + c->bitoff = bitoff; + } + } + } + else /* bit-oriented loop */ +#endif + { + /* + inp + | + +-------+-------+------- + ||||||||||||||||||||| + +-------+-------+------- + +-------+-------+-------+-------+------- + |||||||||||||| c->data + +-------+-------+-------+-------+------- + | + c->bitoff/8 + */ + while (bits) + { + unsigned int byteoff = bitoff/8; + unsigned char b; + +#ifndef OPENSSL_SMALL_FOOTPRINT + if (bitrem==inpgap) + { + c->data[byteoff++] |= inp[0] & (0xff>>inpgap); + inpgap = 8-inpgap; + bitoff += inpgap; bitrem = 0; /* bitoff%8 */ + bits -= inpgap; inpgap = 0; /* bits%8 */ + inp++; + if (bitoff==WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + bitoff = 0; + } + c->bitoff = bitoff; + goto reconsider; + } + else +#endif + if (bits>=8) + { + b = ((inp[0]<>(8-inpgap))); + b &= 0xff; + if (bitrem) c->data[byteoff++] |= b>>bitrem; + else c->data[byteoff++] = b; + bitoff += 8; + bits -= 8; + inp++; + if (bitoff>=WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) c->data[byteoff] = b<<(8-bitrem); + } + else /* remaining less than 8 bits */ + { + b = (inp[0]<data[byteoff++] |= b>>bitrem; + else c->data[byteoff++] = b; + bitoff += (unsigned int)bits; + if (bitoff==WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) c->data[byteoff] = b<<(8-bitrem); + bits = 0; + } + c->bitoff = bitoff; + } + } + } + +int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c) + { + unsigned int bitoff = c->bitoff, + byteoff = bitoff/8; + size_t i,j,v; + unsigned char *p; + + bitoff %= 8; + if (bitoff) c->data[byteoff] |= 0x80>>bitoff; + else c->data[byteoff] = 0x80; + byteoff++; + + /* pad with zeros */ + if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) + { + if (byteoffdata[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff); + whirlpool_block(c,c->data,1); + byteoff = 0; + } + if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) + memset(&c->data[byteoff],0, + (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff); + /* smash 256-bit c->bitlen in big-endian order */ + p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */ + for(i=0;ibitlen[i],j=0;j>=8) + *p-- = (unsigned char)(v&0xff); + + whirlpool_block(c,c->data,1); + + if (md) { + memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH); + memset(c,0,sizeof(*c)); + return(1); + } + return(0); + } + +unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md) + { + WHIRLPOOL_CTX ctx; + static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; + + if (md == NULL) md=m; + WHIRLPOOL_Init(&ctx); + WHIRLPOOL_Update(&ctx,inp,bytes); + WHIRLPOOL_Final(md,&ctx); + return(md); + } diff --git a/crypto/openssl/crypto/whrlpool/wp_locl.h b/crypto/openssl/crypto/whrlpool/wp_locl.h new file mode 100644 index 0000000000..94e56a39f1 --- /dev/null +++ b/crypto/openssl/crypto/whrlpool/wp_locl.h @@ -0,0 +1,3 @@ +#include + +void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t); diff --git a/crypto/openssl/crypto/x509/by_dir.c b/crypto/openssl/crypto/x509/by_dir.c index b3acd80f25..27ca5150c1 100644 --- a/crypto/openssl/crypto/x509/by_dir.c +++ b/crypto/openssl/crypto/x509/by_dir.c @@ -65,28 +65,36 @@ #ifndef NO_SYS_TYPES_H # include #endif -#ifdef MAC_OS_pre_X -# include -#else +#ifndef OPENSSL_NO_POSIX_IO # include #endif #include #include -#ifdef _WIN32 -#define stat _stat -#endif + +typedef struct lookup_dir_hashes_st + { + unsigned long hash; + int suffix; + } BY_DIR_HASH; + +typedef struct lookup_dir_entry_st + { + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; + } BY_DIR_ENTRY; typedef struct lookup_dir_st { BUF_MEM *buffer; - int num_dirs; - char **dirs; - int *dirs_type; - int num_dirs_alloced; + STACK_OF(BY_DIR_ENTRY) *dirs; } BY_DIR; +DECLARE_STACK_OF(BY_DIR_HASH) +DECLARE_STACK_OF(BY_DIR_ENTRY) + static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret); static int new_dir(X509_LOOKUP *lu); @@ -127,7 +135,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, case X509_L_ADD_DIR: if (argl == X509_FILETYPE_DEFAULT) { - dir=(char *)Getenv(X509_get_default_cert_dir_env()); + dir=(char *)getenv(X509_get_default_cert_dir_env()); if (dir) ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); else @@ -156,34 +164,51 @@ static int new_dir(X509_LOOKUP *lu) OPENSSL_free(a); return(0); } - a->num_dirs=0; a->dirs=NULL; - a->dirs_type=NULL; - a->num_dirs_alloced=0; lu->method_data=(char *)a; return(1); } +static void by_dir_hash_free(BY_DIR_HASH *hash) + { + OPENSSL_free(hash); + } + +static int by_dir_hash_cmp(const BY_DIR_HASH * const *a, + const BY_DIR_HASH * const *b) + { + if ((*a)->hash > (*b)->hash) + return 1; + if ((*a)->hash < (*b)->hash) + return -1; + return 0; + } + +static void by_dir_entry_free(BY_DIR_ENTRY *ent) + { + if (ent->dir) + OPENSSL_free(ent->dir); + if (ent->hashes) + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + OPENSSL_free(ent); + } + static void free_dir(X509_LOOKUP *lu) { BY_DIR *a; - int i; a=(BY_DIR *)lu->method_data; - for (i=0; inum_dirs; i++) - if (a->dirs[i] != NULL) OPENSSL_free(a->dirs[i]); - if (a->dirs != NULL) OPENSSL_free(a->dirs); - if (a->dirs_type != NULL) OPENSSL_free(a->dirs_type); - if (a->buffer != NULL) BUF_MEM_free(a->buffer); + if (a->dirs != NULL) + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + if (a->buffer != NULL) + BUF_MEM_free(a->buffer); OPENSSL_free(a); } static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) { int j,len; - int *ip; const char *s,*ss,*p; - char **pp; if (dir == NULL || !*dir) { @@ -197,49 +222,52 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) { if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) { + BY_DIR_ENTRY *ent; ss=s; s=p+1; len=(int)(p-ss); if (len == 0) continue; - for (j=0; jnum_dirs; j++) - if (strlen(ctx->dirs[j]) == (size_t)len && - strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0) + for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) + { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == (size_t)len && + strncmp(ent->dir,ss,(unsigned int)len) == 0) break; - if (jnum_dirs) + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) continue; - if (ctx->num_dirs_alloced < (ctx->num_dirs+1)) + if (ctx->dirs == NULL) { - ctx->num_dirs_alloced+=10; - pp=(char **)OPENSSL_malloc(ctx->num_dirs_alloced* - sizeof(char *)); - ip=(int *)OPENSSL_malloc(ctx->num_dirs_alloced* - sizeof(int)); - if ((pp == NULL) || (ip == NULL)) + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (!ctx->dirs) { X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE); - return(0); + return 0; } - memcpy(pp,ctx->dirs,(ctx->num_dirs_alloced-10)* - sizeof(char *)); - memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-10)* - sizeof(int)); - if (ctx->dirs != NULL) - OPENSSL_free(ctx->dirs); - if (ctx->dirs_type != NULL) - OPENSSL_free(ctx->dirs_type); - ctx->dirs=pp; - ctx->dirs_type=ip; } - ctx->dirs_type[ctx->num_dirs]=type; - ctx->dirs[ctx->num_dirs]=(char *)OPENSSL_malloc((unsigned int)len+1); - if (ctx->dirs[ctx->num_dirs] == NULL) return(0); - strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len); - ctx->dirs[ctx->num_dirs][len]='\0'; - ctx->num_dirs++; + ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); + if (!ent) + return 0; + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = OPENSSL_malloc((unsigned int)len+1); + if (!ent->dir || !ent->hashes) + { + by_dir_entry_free(ent); + return 0; + } + strncpy(ent->dir,ss,(unsigned int)len); + ent->dir[len] = '\0'; + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) + { + by_dir_entry_free(ent); + return 0; + } } - if (*p == '\0') break; + if (*p == '\0') + break; } - return(1); + return 1; } static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, @@ -260,7 +288,6 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, int i,j,k; unsigned long h; BUF_MEM *b=NULL; - struct stat st; X509_OBJECT stmp,*tmp; const char *postfix=""; @@ -296,20 +323,45 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, ctx=(BY_DIR *)xl->method_data; h=X509_NAME_hash(name); - for (i=0; inum_dirs; i++) + for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { - j=strlen(ctx->dirs[i])+1+8+6+1+1; + BY_DIR_ENTRY *ent; + int idx; + BY_DIR_HASH htmp, *hent; + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j=strlen(ent->dir)+1+8+6+1+1; if (!BUF_MEM_grow(b,j)) { X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE); goto finish; } - k=0; + if (type == X509_LU_CRL && ent->hashes) + { + htmp.hash = h; + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) + { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } + else + { + hent = NULL; + k=0; + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + } + else + { + k = 0; + hent = NULL; + } for (;;) { char c = '/'; #ifdef OPENSSL_SYS_VMS - c = ctx->dirs[i][strlen(ctx->dirs[i])-1]; + c = ent->dir[strlen(ent->dir)-1]; if (c != ':' && c != '>' && c != ']') { /* If no separator is present, we assume the @@ -330,32 +382,40 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, /* This is special. When c == '\0', no directory separator should be added. */ BIO_snprintf(b->data,b->max, - "%s%08lx.%s%d",ctx->dirs[i],h, + "%s%08lx.%s%d",ent->dir,h, postfix,k); } else { BIO_snprintf(b->data,b->max, - "%s%c%08lx.%s%d",ctx->dirs[i],c,h, + "%s%c%08lx.%s%d",ent->dir,c,h, postfix,k); } - k++; +#ifndef OPENSSL_NO_POSIX_IO +#ifdef _WIN32 +#define stat _stat +#endif + { + struct stat st; if (stat(b->data,&st) < 0) break; + } +#endif /* found one. */ if (type == X509_LU_X509) { if ((X509_load_cert_file(xl,b->data, - ctx->dirs_type[i])) == 0) + ent->dir_type)) == 0) break; } else if (type == X509_LU_CRL) { if ((X509_load_crl_file(xl,b->data, - ctx->dirs_type[i])) == 0) + ent->dir_type)) == 0) break; } /* else case will caught higher up */ + k++; } /* we have added it to the cache so now pull @@ -366,6 +426,43 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, else tmp = NULL; CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + /* If a CRL, update the last file suffix added for this */ + + if (type == X509_LU_CRL) + { + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* Look for entry again in case another thread added + * an entry first. + */ + if (!hent) + { + htmp.hash = h; + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) + hent = + sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (!hent) + { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) + { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + } + else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + } + if (tmp != NULL) { ok=1; diff --git a/crypto/openssl/crypto/x509/by_file.c b/crypto/openssl/crypto/x509/by_file.c index a5e0d4aefa..57b08ee094 100644 --- a/crypto/openssl/crypto/x509/by_file.c +++ b/crypto/openssl/crypto/x509/by_file.c @@ -100,7 +100,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - file = (char *)Getenv(X509_get_default_cert_file_env()); + file = (char *)getenv(X509_get_default_cert_file_env()); if (file) ok = (X509_load_cert_crl_file(ctx,file, X509_FILETYPE_PEM) != 0); diff --git a/crypto/openssl/crypto/x509/x509.h b/crypto/openssl/crypto/x509/x509.h index 8958e34e9c..604f4fb27f 100644 --- a/crypto/openssl/crypto/x509/x509.h +++ b/crypto/openssl/crypto/x509/x509.h @@ -157,12 +157,12 @@ typedef struct X509_val_st ASN1_TIME *notAfter; } X509_VAL; -typedef struct X509_pubkey_st +struct X509_pubkey_st { X509_ALGOR *algor; ASN1_BIT_STRING *public_key; EVP_PKEY *pkey; - } X509_PUBKEY; + }; typedef struct X509_sig_st { @@ -191,7 +191,9 @@ struct X509_name_st #else char *bytes; #endif - unsigned long hash; /* Keep the hash around for lookups */ +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; } /* X509_NAME */; DECLARE_STACK_OF(X509_NAME) @@ -290,8 +292,11 @@ struct x509_st unsigned long ex_xkusage; unsigned long ex_nscert; ASN1_OCTET_STRING *skid; - struct AUTHORITY_KEYID_st *akid; + AUTHORITY_KEYID *akid; X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; #ifndef OPENSSL_NO_RFC3779 STACK_OF(IPAddressFamily) *rfc3779_addr; struct ASIdentifiers_st *rfc3779_asid; @@ -334,10 +339,11 @@ typedef struct x509_cert_pair_st { #define X509_TRUST_OBJECT_SIGN 5 #define X509_TRUST_OCSP_SIGN 6 #define X509_TRUST_OCSP_REQUEST 7 +#define X509_TRUST_TSA 8 /* Keep these up to date! */ #define X509_TRUST_MIN 1 -#define X509_TRUST_MAX 7 +#define X509_TRUST_MAX 8 /* trust_flags values */ @@ -424,13 +430,17 @@ typedef struct x509_cert_pair_st { XN_FLAG_FN_LN | \ XN_FLAG_FN_ALIGN) -typedef struct X509_revoked_st +struct x509_revoked_st { ASN1_INTEGER *serialNumber; ASN1_TIME *revocationDate; STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; int sequence; /* load sequence */ - } X509_REVOKED; + }; DECLARE_STACK_OF(X509_REVOKED) DECLARE_ASN1_SET_OF(X509_REVOKED) @@ -454,6 +464,22 @@ struct X509_crl_st X509_ALGOR *sig_alg; ASN1_BIT_STRING *signature; int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; } /* X509_CRL */; DECLARE_STACK_OF(X509_CRL) @@ -552,18 +578,19 @@ X509_ALGOR *prf; /* PKCS#8 private key info structure */ -typedef struct pkcs8_priv_key_info_st +struct pkcs8_priv_key_info_st { int broken; /* Flag for various broken formats */ #define PKCS8_OK 0 #define PKCS8_NO_OCTET 1 #define PKCS8_EMBEDDED_PARAM 2 #define PKCS8_NS_DB 3 +#define PKCS8_NEG_PRIVKEY 4 ASN1_INTEGER *version; X509_ALGOR *pkeyalg; ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ STACK_OF(X509_ATTRIBUTE) *attributes; - } PKCS8_PRIV_KEY_INFO; + }; #ifdef __cplusplus } @@ -576,151 +603,6 @@ typedef struct pkcs8_priv_key_info_st extern "C" { #endif -#ifdef SSLEAY_MACROS -#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\ - a->signature,(char *)a->cert_info,r) -#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \ - a->sig_alg,a->signature,(char *)a->req_info,r) -#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \ - a->sig_alg, a->signature,(char *)a->crl,r) - -#define X509_sign(x,pkey,md) \ - ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \ - x->sig_alg, x->signature, (char *)x->cert_info,pkey,md) -#define X509_REQ_sign(x,pkey,md) \ - ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \ - x->signature, (char *)x->req_info,pkey,md) -#define X509_CRL_sign(x,pkey,md) \ - ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \ - x->signature, (char *)x->crl,pkey,md) -#define NETSCAPE_SPKI_sign(x,pkey,md) \ - ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \ - x->signature, (char *)x->spkac,pkey,md) - -#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \ - (char *(*)())d2i_X509,(char *)x509) -#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\ - (int (*)())i2d_X509_ATTRIBUTE, \ - (char *(*)())d2i_X509_ATTRIBUTE,(char *)xa) -#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \ - (int (*)())i2d_X509_EXTENSION, \ - (char *(*)())d2i_X509_EXTENSION,(char *)ex) -#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \ - (char *(*)())d2i_X509, (fp),(unsigned char **)(x509)) -#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509) -#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \ - (char *(*)())d2i_X509, (bp),(unsigned char **)(x509)) -#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509) - -#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \ - (char *(*)())d2i_X509_CRL,(char *)crl) -#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \ - X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\ - (unsigned char **)(crl)) -#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\ - (unsigned char *)crl) -#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \ - X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\ - (unsigned char **)(crl)) -#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\ - (unsigned char *)crl) - -#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \ - (char *(*)())d2i_PKCS7,(char *)p7) -#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \ - PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\ - (unsigned char **)(p7)) -#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\ - (unsigned char *)p7) -#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \ - PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\ - (unsigned char **)(p7)) -#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\ - (unsigned char *)p7) - -#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \ - (char *(*)())d2i_X509_REQ,(char *)req) -#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\ - X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\ - (unsigned char **)(req)) -#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\ - (unsigned char *)req) -#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\ - X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\ - (unsigned char **)(req)) -#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\ - (unsigned char *)req) - -#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \ - (char *(*)())d2i_RSAPublicKey,(char *)rsa) -#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \ - (char *(*)())d2i_RSAPrivateKey,(char *)rsa) - -#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\ - RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \ - (unsigned char **)(rsa)) -#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \ - (unsigned char *)rsa) -#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\ - RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \ - (unsigned char **)(rsa)) -#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \ - (unsigned char *)rsa) - -#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\ - RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \ - (unsigned char **)(rsa)) -#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \ - (unsigned char *)rsa) -#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\ - RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \ - (unsigned char **)(rsa)) -#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \ - (unsigned char *)rsa) - -#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\ - DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \ - (unsigned char **)(dsa)) -#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \ - (unsigned char *)dsa) -#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\ - DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \ - (unsigned char **)(dsa)) -#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \ - (unsigned char *)dsa) - -#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\ - EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \ - (unsigned char **)(ecdsa)) -#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \ - (unsigned char *)ecdsa) -#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\ - EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \ - (unsigned char **)(ecdsa)) -#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \ - (unsigned char *)ecdsa) - -#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\ - (char *(*)())d2i_X509_ALGOR,(char *)xn) - -#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \ - (char *(*)())d2i_X509_NAME,(char *)xn) -#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \ - (int (*)())i2d_X509_NAME_ENTRY, \ - (char *(*)())d2i_X509_NAME_ENTRY,\ - (char *)ne) - -#define X509_digest(data,type,md,len) \ - ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len) -#define X509_NAME_digest(data,type,md,len) \ - ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len) -#ifndef PKCS7_ISSUER_AND_SERIAL_digest -#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \ - ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\ - (char *)data,md,len) -#endif -#endif - #define X509_EXT_PACK_UNKNOWN 1 #define X509_EXT_PACK_STRING 2 @@ -741,6 +623,18 @@ extern "C" { #define X509_CRL_get_issuer(x) ((x)->crl->issuer) #define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new( + int (*crl_init)(X509_CRL *crl), + int (*crl_free)(X509_CRL *crl), + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer), + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + /* This one is only used so that a binary form can output, as in * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */ #define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) @@ -748,7 +642,6 @@ extern "C" { const char *X509_verify_cert_error_string(long n); -#ifndef SSLEAY_MACROS #ifndef OPENSSL_NO_EVP int X509_verify(X509 *a, EVP_PKEY *r); @@ -873,11 +766,11 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, X509_NAME *X509_NAME_dup(X509_NAME *xn); X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); -#endif /* !SSLEAY_MACROS */ - -int X509_cmp_time(ASN1_TIME *s, time_t *t); -int X509_cmp_current_time(ASN1_TIME *s); +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); const char * X509_get_default_cert_area(void ); @@ -965,6 +858,9 @@ DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) DECLARE_ASN1_FUNCTIONS(X509_CRL) int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); X509_PKEY * X509_PKEY_new(void ); void X509_PKEY_free(X509_PKEY *a); @@ -1008,8 +904,8 @@ int X509_set_issuer_name(X509 *x, X509_NAME *name); X509_NAME * X509_get_issuer_name(X509 *a); int X509_set_subject_name(X509 *x, X509_NAME *name); X509_NAME * X509_get_subject_name(X509 *a); -int X509_set_notBefore(X509 *x, ASN1_TIME *tm); -int X509_set_notAfter(X509 *x, ASN1_TIME *tm); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); EVP_PKEY * X509_get_pubkey(X509 *x); ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); @@ -1046,8 +942,8 @@ int X509_REQ_add1_attr_by_txt(X509_REQ *req, int X509_CRL_set_version(X509_CRL *x, long version); int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); -int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm); -int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); int X509_CRL_sort(X509_CRL *crl); int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); @@ -1066,11 +962,18 @@ unsigned long X509_issuer_name_hash(X509 *a); int X509_subject_name_cmp(const X509 *a, const X509 *b); unsigned long X509_subject_name_hash(X509 *x); +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +#endif + int X509_cmp(const X509 *a, const X509 *b); int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); #ifndef OPENSSL_NO_FP_API int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); int X509_print_fp(FILE *bp,X509 *x); @@ -1246,9 +1149,16 @@ DECLARE_ASN1_FUNCTIONS(PBEPARAM) DECLARE_ASN1_FUNCTIONS(PBE2PARAM) DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) -X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen); +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); /* PKCS#8 utilities */ @@ -1259,6 +1169,22 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + PKCS8_PRIV_KEY_INFO *p8); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub); + int X509_check_trust(X509 *x, int id, int flags); int X509_TRUST_get_count(void); X509_TRUST * X509_TRUST_get0(int idx); @@ -1338,7 +1264,10 @@ void ERR_load_X509_strings(void); #define X509_R_KEY_VALUES_MISMATCH 116 #define X509_R_LOADING_CERT_DIR 103 #define X509_R_LOADING_DEFAULTS 104 +#define X509_R_METHOD_NOT_SUPPORTED 124 #define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 #define X509_R_SHOULD_RETRY 106 #define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 #define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 diff --git a/crypto/openssl/crypto/x509/x509_cmp.c b/crypto/openssl/crypto/x509/x509_cmp.c index 2faf92514a..4bc9da07e0 100644 --- a/crypto/openssl/crypto/x509/x509_cmp.c +++ b/crypto/openssl/crypto/x509/x509_cmp.c @@ -116,6 +116,13 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer)); } +#ifndef OPENSSL_NO_SHA +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) + { + return memcmp(a->sha1_hash, b->sha1_hash, 20); + } +#endif + X509_NAME *X509_get_issuer_name(X509 *a) { return(a->cert_info->issuer); @@ -126,6 +133,13 @@ unsigned long X509_issuer_name_hash(X509 *x) return(X509_NAME_hash(x->cert_info->issuer)); } +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *x) + { + return(X509_NAME_hash_old(x->cert_info->issuer)); + } +#endif + X509_NAME *X509_get_subject_name(X509 *a) { return(a->cert_info->subject); @@ -141,6 +155,13 @@ unsigned long X509_subject_name_hash(X509 *x) return(X509_NAME_hash(x->cert_info->subject)); } +#ifndef OPENSSL_NO_MD5 +unsigned long X509_subject_name_hash_old(X509 *x) + { + return(X509_NAME_hash_old(x->cert_info->subject)); + } +#endif + #ifndef OPENSSL_NO_SHA /* Compare two certificates: they must be identical for * this to work. NB: Although "cmp" operations are generally @@ -162,177 +183,63 @@ int X509_cmp(const X509 *a, const X509 *b) #endif -/* Case insensitive string comparision */ -static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b) -{ - int i; - - if (a->length != b->length) - return (a->length - b->length); - - for (i=0; ilength; i++) - { - int ca, cb; - - ca = tolower(a->data[i]); - cb = tolower(b->data[i]); - - if (ca != cb) - return(ca-cb); - } - return 0; -} - -/* Case insensitive string comparision with space normalization - * Space normalization - ignore leading, trailing spaces, - * multiple spaces between characters are replaced by single space - */ -static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b) -{ - unsigned char *pa = NULL, *pb = NULL; - int la, lb; - - la = a->length; - lb = b->length; - pa = a->data; - pb = b->data; - - /* skip leading spaces */ - while (la > 0 && isspace(*pa)) - { - la--; - pa++; - } - while (lb > 0 && isspace(*pb)) - { - lb--; - pb++; - } - - /* skip trailing spaces */ - while (la > 0 && isspace(pa[la-1])) - la--; - while (lb > 0 && isspace(pb[lb-1])) - lb--; - - /* compare strings with space normalization */ - while (la > 0 && lb > 0) +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { - int ca, cb; - - /* compare character */ - ca = tolower(*pa); - cb = tolower(*pb); - if (ca != cb) - return (ca - cb); + int ret; - pa++; pb++; - la--; lb--; + /* Ensure canonical encoding is present and up to date */ - if (la <= 0 || lb <= 0) - break; + if (!a->canon_enc || a->modified) + { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) + return -2; + } - /* is white space next character ? */ - if (isspace(*pa) && isspace(*pb)) + if (!b->canon_enc || b->modified) { - /* skip remaining white spaces */ - while (la > 0 && isspace(*pa)) - { - la--; - pa++; - } - while (lb > 0 && isspace(*pb)) - { - lb--; - pb++; - } + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) + return -2; } - } - if (la > 0 || lb > 0) - return la - lb; - return 0; -} + ret = a->canon_enclen - b->canon_enclen; -static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b) - { - int j; - j = a->length - b->length; - if (j) - return j; - return memcmp(a->data, b->data, a->length); - } + if (ret) + return ret; -#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING) + return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); -int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) - { - int i,j; - X509_NAME_ENTRY *na,*nb; + } - unsigned long nabit, nbbit; +unsigned long X509_NAME_hash(X509_NAME *x) + { + unsigned long ret=0; + unsigned char md[SHA_DIGEST_LENGTH]; - j = sk_X509_NAME_ENTRY_num(a->entries) - - sk_X509_NAME_ENTRY_num(b->entries); - if (j) - return j; - for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) - { - na=sk_X509_NAME_ENTRY_value(a->entries,i); - nb=sk_X509_NAME_ENTRY_value(b->entries,i); - j=na->value->type-nb->value->type; - if (j) - { - nabit = ASN1_tag2bit(na->value->type); - nbbit = ASN1_tag2bit(nb->value->type); - if (!(nabit & STR_TYPE_CMP) || - !(nbbit & STR_TYPE_CMP)) - return j; - if (!asn1_string_memcmp(na->value, nb->value)) - j = 0; - } - else if (na->value->type == V_ASN1_PRINTABLESTRING) - j=nocase_spacenorm_cmp(na->value, nb->value); - else if (na->value->type == V_ASN1_IA5STRING - && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) - j=nocase_cmp(na->value, nb->value); - else - j = asn1_string_memcmp(na->value, nb->value); - if (j) return(j); - j=na->set-nb->set; - if (j) return(j); - } + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x,NULL); + EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL); - /* We will check the object types after checking the values - * since the values will more often be different than the object - * types. */ - for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) - { - na=sk_X509_NAME_ENTRY_value(a->entries,i); - nb=sk_X509_NAME_ENTRY_value(b->entries,i); - j=OBJ_cmp(na->object,nb->object); - if (j) return(j); - } - return(0); + ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| + ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) + )&0xffffffffL; + return(ret); } + #ifndef OPENSSL_NO_MD5 /* I now DER encode the name and hash it. Since I cache the DER encoding, * this is reasonably efficient. */ -unsigned long X509_NAME_hash(X509_NAME *x) + +unsigned long X509_NAME_hash_old(X509_NAME *x) { unsigned long ret=0; unsigned char md[16]; - EVP_MD_CTX md_ctx; /* Make sure X509_NAME structure contains valid cached encoding */ i2d_X509_NAME(x,NULL); - EVP_MD_CTX_init(&md_ctx); - EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL); - EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length); - EVP_DigestFinal_ex(&md_ctx,md,NULL); - EVP_MD_CTX_cleanup(&md_ctx); + EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL); ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) @@ -393,14 +300,19 @@ ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) int X509_check_private_key(X509 *x, EVP_PKEY *k) { - EVP_PKEY *xk=NULL; - int ok=0; + EVP_PKEY *xk; + int ret; xk=X509_get_pubkey(x); - switch (EVP_PKEY_cmp(xk, k)) + + if (xk) + ret = EVP_PKEY_cmp(xk, k); + else + ret = -2; + + switch (ret) { case 1: - ok=1; break; case 0: X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH); @@ -409,24 +321,11 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k) X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH); break; case -2: -#ifndef OPENSSL_NO_EC - if (k->type == EVP_PKEY_EC) - { - X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); - break; - } -#endif -#ifndef OPENSSL_NO_DH - if (k->type == EVP_PKEY_DH) - { - /* No idea */ - X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY); - break; - } -#endif X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); } - - EVP_PKEY_free(xk); - return(ok); + if (xk) + EVP_PKEY_free(xk); + if (ret > 0) + return 1; + return 0; } diff --git a/crypto/openssl/crypto/x509/x509_err.c b/crypto/openssl/crypto/x509/x509_err.c index fb377292da..a01402f416 100644 --- a/crypto/openssl/crypto/x509/x509_err.c +++ b/crypto/openssl/crypto/x509/x509_err.c @@ -1,6 +1,6 @@ /* crypto/x509/x509_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 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 @@ -132,7 +132,10 @@ static ERR_STRING_DATA X509_str_reasons[]= {ERR_REASON(X509_R_KEY_VALUES_MISMATCH) ,"key values mismatch"}, {ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"}, {ERR_REASON(X509_R_LOADING_DEFAULTS) ,"loading defaults"}, +{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) ,"method not supported"}, {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"}, +{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR),"public key decode error"}, +{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR),"public key encode error"}, {ERR_REASON(X509_R_SHOULD_RETRY) ,"should retry"}, {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"}, {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"}, diff --git a/crypto/openssl/crypto/x509/x509_lu.c b/crypto/openssl/crypto/x509/x509_lu.c index b486171868..3a6e04a1de 100644 --- a/crypto/openssl/crypto/x509/x509_lu.c +++ b/crypto/openssl/crypto/x509/x509_lu.c @@ -196,6 +196,8 @@ X509_STORE *X509_STORE_new(void) ret->get_crl = 0; ret->check_crl = 0; ret->cert_crl = 0; + ret->lookup_certs = 0; + ret->lookup_crls = 0; ret->cleanup = 0; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) @@ -296,7 +298,7 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - if (tmp == NULL) + if (tmp == NULL || type == X509_LU_CRL) { for (i=vs->current_method; iget_cert_methods); i++) { @@ -421,14 +423,15 @@ void X509_OBJECT_free_contents(X509_OBJECT *a) } } -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name) +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name, int *pnmatch) { X509_OBJECT stmp; X509 x509_s; X509_CINF cinf_s; X509_CRL crl_s; X509_CRL_INFO crl_info_s; + int idx; stmp.type=type; switch (type) @@ -448,7 +451,29 @@ int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, return -1; } - return sk_X509_OBJECT_find(h,&stmp); + idx = sk_X509_OBJECT_find(h,&stmp); + if (idx >= 0 && pnmatch) + { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) + { + tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(&tobj, &pstmp)) + break; + (*pnmatch)++; + } + } + return idx; + } + + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) + { + return x509_object_idx_cnt(h, type, name, NULL); } X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, @@ -460,19 +485,125 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, return sk_X509_OBJECT_value(h, idx); } +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) + { + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + sk = sk_X509_new_null(); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) + { + /* Nothing found in cache: do lookup to possibly add new + * objects to cache + */ + X509_OBJECT xobj; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) + { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt); + if (idx < 0) + { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_free(sk); + return NULL; + } + } + for (i = 0; i < cnt; i++, idx++) + { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.x509; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(sk, x)) + { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + + } + +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) + { + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj, xobj; + sk = sk_X509_CRL_new_null(); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* Check cache first */ + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + + /* Always do lookup to possibly add new CRLs to cache + */ + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) + { + sk_X509_CRL_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt); + if (idx < 0) + { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_CRL_free(sk); + return NULL; + } + + for (i = 0; i < cnt; i++, idx++) + { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.crl; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(sk, x)) + { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + } + X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) { int idx, i; X509_OBJECT *obj; idx = sk_X509_OBJECT_find(h, x); if (idx == -1) return NULL; - if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); for (i = idx; i < sk_X509_OBJECT_num(h); i++) { obj = sk_X509_OBJECT_value(h, i); if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) return NULL; - if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) + if (x->type == X509_LU_X509) + { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } + else if (x->type == X509_LU_CRL) + { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } + else return obj; } return NULL; @@ -575,5 +706,11 @@ int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) return X509_VERIFY_PARAM_set1(ctx->param, param); } +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)) + { + ctx->verify_cb = verify_cb; + } + IMPLEMENT_STACK_OF(X509_LOOKUP) IMPLEMENT_STACK_OF(X509_OBJECT) diff --git a/crypto/openssl/crypto/x509/x509_obj.c b/crypto/openssl/crypto/x509/x509_obj.c index 1e718f76eb..21fed9f838 100644 --- a/crypto/openssl/crypto/x509/x509_obj.c +++ b/crypto/openssl/crypto/x509/x509_obj.c @@ -72,7 +72,7 @@ int i; char *p; unsigned char *q; BUF_MEM *b=NULL; - static char hex[17]="0123456789ABCDEF"; + static const char hex[17]="0123456789ABCDEF"; int gs_doit[4]; char tmp_buf[80]; #ifdef CHARSET_EBCDIC diff --git a/crypto/openssl/crypto/x509/x509_req.c b/crypto/openssl/crypto/x509/x509_req.c index 3872e1fb64..48183dc00c 100644 --- a/crypto/openssl/crypto/x509/x509_req.c +++ b/crypto/openssl/crypto/x509/x509_req.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -205,10 +206,9 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) if(!ext || (ext->type != V_ASN1_SEQUENCE)) return NULL; p = ext->value.sequence->data; - return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p, - ext->value.sequence->length, - d2i_X509_EXTENSION, X509_EXTENSION_free, - V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + return (STACK_OF(X509_EXTENSION) *) + ASN1_item_d2i(NULL, &p, ext->value.sequence->length, + ASN1_ITEM_rptr(X509_EXTENSIONS)); } /* Add a STACK_OF extensions to a certificate request: allow alternative OIDs @@ -218,8 +218,6 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, int nid) { - unsigned char *p = NULL, *q; - long len; ASN1_TYPE *at = NULL; X509_ATTRIBUTE *attr = NULL; if(!(at = ASN1_TYPE_new()) || @@ -227,15 +225,10 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, at->type = V_ASN1_SEQUENCE; /* Generate encoding of extensions */ - len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION, - V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE); - if(!(p = OPENSSL_malloc(len))) goto err; - q = p; - i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION, - V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE); - at->value.sequence->data = p; - p = NULL; - at->value.sequence->length = len; + at->value.sequence->length = + ASN1_item_i2d((ASN1_VALUE *)exts, + &at->value.sequence->data, + ASN1_ITEM_rptr(X509_EXTENSIONS)); if(!(attr = X509_ATTRIBUTE_new())) goto err; if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err; @@ -250,7 +243,6 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err; return 1; err: - if(p) OPENSSL_free(p); X509_ATTRIBUTE_free(attr); ASN1_TYPE_free(at); return 0; diff --git a/crypto/openssl/crypto/x509/x509_set.c b/crypto/openssl/crypto/x509/x509_set.c index aaf61ca062..4b94fc5847 100644 --- a/crypto/openssl/crypto/x509/x509_set.c +++ b/crypto/openssl/crypto/x509/x509_set.c @@ -104,7 +104,7 @@ int X509_set_subject_name(X509 *x, X509_NAME *name) return(X509_NAME_set(&x->cert_info->subject,name)); } -int X509_set_notBefore(X509 *x, ASN1_TIME *tm) +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) { ASN1_TIME *in; @@ -122,7 +122,7 @@ int X509_set_notBefore(X509 *x, ASN1_TIME *tm) return(in != NULL); } -int X509_set_notAfter(X509 *x, ASN1_TIME *tm) +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) { ASN1_TIME *in; diff --git a/crypto/openssl/crypto/x509/x509_trs.c b/crypto/openssl/crypto/x509/x509_trs.c index ed18700585..a6cb9c8b1b 100644 --- a/crypto/openssl/crypto/x509/x509_trs.c +++ b/crypto/openssl/crypto/x509/x509_trs.c @@ -84,7 +84,8 @@ static X509_TRUST trstandard[] = { {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL}, {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL}, {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL}, -{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL} +{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL}, +{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} }; #define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) diff --git a/crypto/openssl/crypto/x509/x509_txt.c b/crypto/openssl/crypto/x509/x509_txt.c index 73a8ec726f..c44f753c46 100644 --- a/crypto/openssl/crypto/x509/x509_txt.c +++ b/crypto/openssl/crypto/x509/x509_txt.c @@ -162,8 +162,28 @@ const char *X509_verify_cert_error_string(long n) return("invalid or inconsistent certificate policy extension"); case X509_V_ERR_NO_EXPLICIT_POLICY: return("no explicit policy"); - case X509_V_ERR_UNNESTED_RESOURCE: - return("RFC 3779 resource not subset of parent's resources"); + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + return("Different CRL scope"); + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: + return("Unsupported extension feature"); + case X509_V_ERR_UNNESTED_RESOURCE: + return("RFC 3779 resource not subset of parent's resources"); + + case X509_V_ERR_PERMITTED_VIOLATION: + return("permitted subtree violation"); + case X509_V_ERR_EXCLUDED_VIOLATION: + return("excluded subtree violation"); + case X509_V_ERR_SUBTREE_MINMAX: + return("name constraints minimum and maximum not supported"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: + return("unsupported name constraint type"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: + return("unsupported or invalid name constraint syntax"); + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + return("unsupported or invalid name syntax"); + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + return("CRL path validation error"); + default: BIO_snprintf(buf,sizeof buf,"error number %ld",n); return(buf); diff --git a/crypto/openssl/crypto/x509/x509_vfy.c b/crypto/openssl/crypto/x509/x509_vfy.c index b85456e65b..87ebf62525 100644 --- a/crypto/openssl/crypto/x509/x509_vfy.c +++ b/crypto/openssl/crypto/x509/x509_vfy.c @@ -70,14 +70,70 @@ #include #include +/* CRL score values */ + +/* No unhandled critical extensions */ + +#define CRL_SCORE_NOCRITICAL 0x100 + +/* certificate is within CRL scope */ + +#define CRL_SCORE_SCOPE 0x080 + +/* CRL times valid */ + +#define CRL_SCORE_TIME 0x040 + +/* Issuer name matches certificate */ + +#define CRL_SCORE_ISSUER_NAME 0x020 + +/* If this score or above CRL is probably valid */ + +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) + +/* CRL issuer is certificate issuer */ + +#define CRL_SCORE_ISSUER_CERT 0x018 + +/* CRL issuer is on certificate path */ + +#define CRL_SCORE_SAME_PATH 0x008 + +/* CRL issuer matches CRL AKID */ + +#define CRL_SCORE_AKID 0x004 + +/* Have a delta CRL with valid times */ + +#define CRL_SCORE_TIME_DELTA 0x002 + static int null_callback(int ok,X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_name_constraints(X509_STORE_CTX *ctx); static int check_trust(X509_STORE_CTX *ctx); static int check_revocation(X509_STORE_CTX *ctx); static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, + X509_CRL *crl, X509 *x); +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, + X509_CRL *base, STACK_OF(X509_CRL) *crls); +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, + X509 **pissuer, int *pcrl_score); +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons); +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path); + static int internal_verify(X509_STORE_CTX *ctx); const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT; @@ -289,6 +345,12 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (!ok) goto end; + /* Check name constraints */ + + ok = check_name_constraints(ctx); + + if (!ok) goto end; + /* The chain extensions are OK: check trust */ if (param->trust > 0) ok = check_trust(ctx); @@ -398,8 +460,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) X509 *x; int (*cb)(int xok,X509_STORE_CTX *xctx); int proxy_path_length = 0; - int allow_proxy_certs = - !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + int purpose; + int allow_proxy_certs; cb=ctx->verify_cb; /* must_be_ca can have 1 of 3 values: @@ -412,10 +474,22 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) */ must_be_ca = -1; - /* A hack to keep people who don't want to modify their software - happy */ - if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) - allow_proxy_certs = 1; + /* CRL path validation */ + if (ctx->parent) + { + allow_proxy_certs = 0; + purpose = X509_PURPOSE_CRL_SIGN; + } + else + { + allow_proxy_certs = + !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + /* A hack to keep people who don't want to modify their + software happy */ + if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) + allow_proxy_certs = 1; + purpose = ctx->param->purpose; + } /* Check all untrusted certificates */ for (i = 0; i < ctx->last_untrusted; i++) @@ -482,8 +556,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) } if (ctx->param->purpose > 0) { - ret = X509_check_purpose(x, ctx->param->purpose, - must_be_ca > 0); + ret = X509_check_purpose(x, purpose, must_be_ca > 0); if ((ret == 0) || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && (ret != 1))) @@ -536,6 +609,42 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) #endif } +static int check_name_constraints(X509_STORE_CTX *ctx) + { + X509 *x; + int i, j, rv; + /* Check name constraints for all certificates */ + for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) + { + x = sk_X509_value(ctx->chain, i); + /* Ignore self issued certs unless last in chain */ + if (i && (x->ex_flags & EXFLAG_SI)) + continue; + /* Check against constraints for all certificates higher in + * chain including trust anchor. Trust anchor not strictly + * speaking needed but if it includes constraints it is to be + * assumed it expects them to be obeyed. + */ + for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) + { + NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; + if (nc) + { + rv = NAME_CONSTRAINTS_check(x, nc); + if (rv != X509_V_OK) + { + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0,ctx)) + return 0; + } + } + } + } + return 1; + } + static int check_trust(X509_STORE_CTX *ctx) { #ifdef OPENSSL_NO_CHAIN_VERIFY @@ -570,7 +679,12 @@ static int check_revocation(X509_STORE_CTX *ctx) if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) last = sk_X509_num(ctx->chain) - 1; else + { + /* If checking CRL paths this isn't the EE certificate */ + if (ctx->parent) + return 1; last = 0; + } for(i = 0; i <= last; i++) { ctx->error_depth = i; @@ -582,30 +696,65 @@ static int check_revocation(X509_STORE_CTX *ctx) static int check_cert(X509_STORE_CTX *ctx) { - X509_CRL *crl = NULL; + X509_CRL *crl = NULL, *dcrl = NULL; X509 *x; int ok, cnum; cnum = ctx->error_depth; x = sk_X509_value(ctx->chain, cnum); ctx->current_cert = x; - /* Try to retrieve relevant CRL */ - ok = ctx->get_crl(ctx, &crl, x); - /* If error looking up CRL, nothing we can do except - * notify callback - */ - if(!ok) + ctx->current_issuer = NULL; + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); + else + ok = get_crl_delta(ctx, &crl, &dcrl, x); + /* If error looking up CRL, nothing we can do except + * notify callback + */ + if(!ok) + { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) + goto err; + + if (dcrl) + { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) + goto err; + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) + goto err; + } + else + ok = 1; + + /* Don't look in full CRL if delta reason is removefromCRL */ + if (ok != 2) + { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) + goto err; + } + + X509_CRL_free(crl); + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; } - ctx->current_crl = crl; - ok = ctx->check_crl(ctx, crl); - if (!ok) goto err; - ok = ctx->cert_crl(ctx, crl, x); err: - ctx->current_crl = NULL; X509_CRL_free(crl); + X509_CRL_free(dcrl); + + ctx->current_crl = NULL; return ok; } @@ -616,7 +765,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) { time_t *ptime; int i; - ctx->current_crl = crl; + if (notify) + ctx->current_crl = crl; if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) ptime = &ctx->param->check_time; else @@ -625,15 +775,19 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); if (i == 0) { + if (!notify) + return 0; ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; - if (!notify || !ctx->verify_cb(0, ctx)) + if (!ctx->verify_cb(0, ctx)) return 0; } if (i > 0) { + if (!notify) + return 0; ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; - if (!notify || !ctx->verify_cb(0, ctx)) + if (!ctx->verify_cb(0, ctx)) return 0; } @@ -643,92 +797,545 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) if (i == 0) { + if (!notify) + return 0; ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; - if (!notify || !ctx->verify_cb(0, ctx)) + if (!ctx->verify_cb(0, ctx)) return 0; } - - if (i < 0) + /* Ignore expiry of base CRL is delta is valid */ + if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) + return 0; ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; - if (!notify || !ctx->verify_cb(0, ctx)) + if (!ctx->verify_cb(0, ctx)) return 0; } } - ctx->current_crl = NULL; + if (notify) + ctx->current_crl = NULL; return 1; } -/* Lookup CRLs from the supplied list. Look for matching isser name - * and validity. If we can't find a valid CRL return the last one - * with matching name. This gives more meaningful error codes. Otherwise - * we'd get a CRL not found error if a CRL existed with matching name but - * was invalid. - */ - -static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, - X509_NAME *nm, STACK_OF(X509_CRL) *crls) +static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 **pissuer, int *pscore, unsigned int *preasons, + STACK_OF(X509_CRL) *crls) { - int i; + int i, crl_score, best_score = *pscore; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { crl = sk_X509_CRL_value(crls, i); - if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) - continue; - if (check_crl_time(ctx, crl, 0)) + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + + if (crl_score > best_score) { - *pcrl = crl; - CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509); - return 1; + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; } - best_crl = crl; } + if (best_crl) { + if (*pcrl) + X509_CRL_free(*pcrl); *pcrl = best_crl; - CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509); + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (*pdcrl) + { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); } - + + if (best_score >= CRL_SCORE_VALID) + return 1; + return 0; } -/* Retrieve CRL corresponding to certificate: currently just a - * subject lookup: maybe use AKID later... +/* Compare two CRL extensions for delta checking purposes. They should be + * both present or both absent. If both present all fields must be identical. */ -static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) + +static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) { - int ok; - X509_CRL *crl = NULL; - X509_OBJECT xobj; - X509_NAME *nm; - nm = X509_get_issuer_name(x); - ok = get_crl_sk(ctx, &crl, nm, ctx->crls); - if (ok) + ASN1_OCTET_STRING *exta, *extb; + int i; + i = X509_CRL_get_ext_by_NID(a, nid, 0); + if (i >= 0) { - *pcrl = crl; + /* Can't have multiple occurrences */ + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) + return 0; + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } + else + exta = NULL; + + i = X509_CRL_get_ext_by_NID(b, nid, 0); + + if (i >= 0) + { + + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) + return 0; + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } + else + extb = NULL; + + if (!exta && !extb) return 1; + + if (!exta || !extb) + return 0; + + + if (ASN1_OCTET_STRING_cmp(exta, extb)) + return 0; + + return 1; + } + +/* See if a base and delta are compatible */ + +static int check_delta_base(X509_CRL *delta, X509_CRL *base) + { + /* Delta CRL must be a delta */ + if (!delta->base_crl_number) + return 0; + /* Base must have a CRL number */ + if (!base->crl_number) + return 0; + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), + X509_CRL_get_issuer(delta))) + return 0; + /* AKID and IDP must match */ + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) + return 0; + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) + return 0; + /* Delta CRL base number must not exceed Full CRL number. */ + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) + return 0; + /* Delta CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) + return 1; + return 0; + } + +/* For a given base CRL find a delta... maybe extend to delta scoring + * or retrieve a chain of deltas... + */ + +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, + X509_CRL *base, STACK_OF(X509_CRL) *crls) + { + X509_CRL *delta; + int i; + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + return; + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + return; + for (i = 0; i < sk_X509_CRL_num(crls); i++) + { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) + { + if (check_crl_time(ctx, delta, 0)) + *pscore |= CRL_SCORE_TIME_DELTA; + CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); + *dcrl = delta; + return; + } + } + *dcrl = NULL; + } + +/* For a given CRL return how suitable it is for the supplied certificate 'x'. + * The return value is a mask of several criteria. + * If the issuer is not the certificate issuer this is returned in *pissuer. + * The reasons mask is also used to determine if the CRL is suitable: if + * no new reasons the CRL is rejected, otherwise reasons is updated. + */ + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, + X509_CRL *crl, X509 *x) + { + + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; + + /* First see if we can reject CRL straight away */ + + /* Invalid IDP cannot be processed */ + if (crl->idp_flags & IDP_INVALID) + return 0; + /* Reason codes or indirect CRLs need extended CRL support */ + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) + return 0; + } + else if (crl->idp_flags & IDP_REASONS) + { + /* If no new reasons reject */ + if (!(crl->idp_reasons & ~tmp_reasons)) + return 0; + } + /* Don't process deltas at this stage */ + else if (crl->base_crl_number) + return 0; + /* If issuer name doesn't match certificate need indirect CRL */ + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) + { + if (!(crl->idp_flags & IDP_INDIRECT)) + return 0; + } + else + crl_score |= CRL_SCORE_ISSUER_NAME; + + if (!(crl->flags & EXFLAG_CRITICAL)) + crl_score |= CRL_SCORE_NOCRITICAL; + + /* Check expiry */ + if (check_crl_time(ctx, crl, 0)) + crl_score |= CRL_SCORE_TIME; + + /* Check authority key ID and locate certificate issuer */ + crl_akid_check(ctx, crl, pissuer, &crl_score); + + /* If we can't locate certificate issuer at this point forget it */ + + if (!(crl_score & CRL_SCORE_AKID)) + return 0; + + /* Check cert for matching CRL distribution points */ + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) + { + /* If no new reasons reject */ + if (!(crl_reasons & ~tmp_reasons)) + return 0; + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; } - ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj); + *preasons = tmp_reasons; + + return crl_score; + + } - if (!ok) +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, + X509 **pissuer, int *pcrl_score) + { + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + int i; + + if (cidx != sk_X509_num(ctx->chain) - 1) + cidx++; + + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - /* If we got a near match from get_crl_sk use that */ - if (crl) + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { - *pcrl = crl; - return 1; + *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) + { + crl_issuer = sk_X509_value(ctx->chain, cidx); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) + { + *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; + } + } + + /* Anything else needs extended CRL support */ + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + return; + + /* Otherwise the CRL issuer is not on the path. Look for it in the + * set of untrusted certificates. + */ + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) + { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) + { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; + } + } + } + +/* Check the path of a CRL issuer certificate. This creates a new + * X509_STORE_CTX and populates it with most of the parameters from the + * parent. This could be optimised somewhat since a lot of path checking + * will be duplicated by the parent, but this will rarely be used in + * practice. + */ + +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) + { + X509_STORE_CTX crl_ctx; + int ret; + /* Don't allow recursive CRL path validation */ + if (ctx->parent) + return 0; + if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) + return -1; + + crl_ctx.crls = ctx->crls; + /* Copy verify params across */ + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + /* Verify CRL issuer */ + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) + goto err; + + /* Check chain is acceptable */ + + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); + err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; + } + +/* RFC3280 says nothing about the relationship between CRL path + * and certificate path, which could lead to situations where a + * certificate could be revoked or validated by a CA not authorised + * to do so. RFC5280 is more strict and states that the two paths must + * end in the same trust anchor, though some discussions remain... + * until this is resolved we use the RFC5280 version + */ + +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) + { + X509 *cert_ta, *crl_ta; + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) + return 1; + return 0; + } + +/* Check for match between two dist point names: three separate cases. + * 1. Both are relative names and compare X509_NAME types. + * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. + * 3. Both are full names and compare two GENERAL_NAMES. + * 4. One is NULL: automatic match. + */ + + +static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) + { + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + int i, j; + if (!a || !b) + return 1; + if (a->type == 1) + { + if (!a->dpname) + return 0; + /* Case 1: two X509_NAME */ + if (b->type == 1) + { + if (!b->dpname) + return 0; + if (!X509_NAME_cmp(a->dpname, b->dpname)) + return 1; + else + return 0; } + /* Case 2: set name and GENERAL_NAMES appropriately */ + nm = a->dpname; + gens = b->name.fullname; + } + else if (b->type == 1) + { + if (!b->dpname) + return 0; + /* Case 2: set name and GENERAL_NAMES appropriately */ + gens = a->name.fullname; + nm = b->dpname; + } + + /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ + if (nm) + { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gena->d.directoryName)) + return 1; + } + return 0; + } + + /* Else case 3: two GENERAL_NAMES */ + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) + { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) + { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) + return 1; + } + } + + return 0; + + } + +static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) + { + int i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + /* If no CRLissuer return is successful iff don't need a match */ + if (!dp->CRLissuer) + return !!(crl_score & CRL_SCORE_ISSUER_NAME); + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) + { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(gen->d.directoryName, nm)) + return 1; + } + return 0; + } + +/* Check CRLDP and IDP */ + +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons) + { + int i; + if (crl->idp_flags & IDP_ONLYATTR) return 0; + if (x->ex_flags & EXFLAG_CA) + { + if (crl->idp_flags & IDP_ONLYUSER) + return 0; + } + else + { + if (crl->idp_flags & IDP_ONLYCA) + return 0; + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) + { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) + { + if (!crl->idp || + idp_check_dp(dp->distpoint, crl->idp->distpoint)) + { + *preasons &= dp->dp_reasons; + return 1; + } + } } + if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME)) + return 1; + return 0; + } + +/* Retrieve CRL corresponding to current certificate. + * If deltas enabled try to find a delta CRL too + */ + +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) + { + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, + &issuer, &crl_score, &reasons, ctx->crls); + + if (ok) + goto done; + + /* Lookup CRLs from store */ - *pcrl = xobj.data.crl; + skcrl = ctx->lookup_crls(ctx, nm); + + /* If no CRLs found and a near match from get_crl_sk use that */ + if (!skcrl && crl) + goto done; + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + + done: + + /* If we got any kind of CRL use it and return success */ if (crl) - X509_CRL_free(crl); - return 1; + { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; } /* Check CRL validity */ @@ -739,10 +1346,14 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) int ok = 0, chnum, cnum; cnum = ctx->error_depth; chnum = sk_X509_num(ctx->chain) - 1; - /* Find CRL issuer: if not last certificate then issuer + /* if we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer) + issuer = ctx->current_issuer; + + /* Else find CRL issuer: if not last certificate then issuer * is next certificate in chain. */ - if(cnum < chnum) + else if (cnum < chnum) issuer = sk_X509_value(ctx->chain, cnum + 1); else { @@ -758,13 +1369,52 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(issuer) { - /* Check for cRLSign bit if keyUsage present */ - if ((issuer->ex_flags & EXFLAG_KUSAGE) && - !(issuer->ex_kusage & KU_CRL_SIGN)) + /* Skip most tests for deltas because they have already + * been done + */ + if (!crl->base_crl_number) { - ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; - ok = ctx->verify_cb(0, ctx); - if(!ok) goto err; + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) + { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if(!ok) goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) + { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if(!ok) goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) + { + if (check_crl_path(ctx, ctx->current_issuer) <= 0) + { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if(!ok) goto err; + } + } + + if (crl->idp_flags & IDP_INVALID) + { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if(!ok) goto err; + } + + + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) + { + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; } /* Attempt to get issuer certificate public key */ @@ -788,10 +1438,6 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) } } - ok = check_crl_time(ctx, crl, 1); - if (!ok) - goto err; - ok = 1; err: @@ -802,62 +1448,43 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) /* Check certificate against CRL */ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) { - int idx, ok; - X509_REVOKED rtmp; - STACK_OF(X509_EXTENSION) *exts; - X509_EXTENSION *ext; - /* Look for serial number of certificate in CRL */ - rtmp.serialNumber = X509_get_serialNumber(x); - /* Sort revoked into serial number order if not already sorted. - * Do this under a lock to avoid race condition. - */ - if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) + int ok; + X509_REVOKED *rev; + /* The rules changed for this... previously if a CRL contained + * unhandled critical extensions it could still be used to indicate + * a certificate was revoked. This has since been changed since + * critical extension can change the meaning of CRL entries. + */ + if (crl->flags & EXFLAG_CRITICAL) { - CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); - sk_X509_REVOKED_sort(crl->crl->revoked); - CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); + if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + return 1; + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if(!ok) + return 0; } - idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); - /* If found assume revoked: want something cleverer than - * this to handle entry extensions in V2 CRLs. + /* Look for serial number of certificate in CRL + * If found make sure reason is not removeFromCRL. */ - if(idx >= 0) + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; ctx->error = X509_V_ERR_CERT_REVOKED; ok = ctx->verify_cb(0, ctx); - if (!ok) return 0; + if (!ok) + return 0; } - if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - return 1; - - /* See if we have any critical CRL extensions: since we - * currently don't handle any CRL extensions the CRL must be - * rejected. - * This code accesses the X509_CRL structure directly: applications - * shouldn't do this. - */ - - exts = crl->crl->extensions; - - for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) - { - ext = sk_X509_EXTENSION_value(exts, idx); - if (ext->critical > 0) - { - ctx->error = - X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; - ok = ctx->verify_cb(0, ctx); - if(!ok) return 0; - break; - } - } return 1; } static int check_policy(X509_STORE_CTX *ctx) { int ret; + if (ctx->parent) + return 1; ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, ctx->param->policies, ctx->param->flags); if (ret == 0) @@ -880,7 +1507,8 @@ static int check_policy(X509_STORE_CTX *ctx) continue; ctx->current_cert = x; ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; - ret = ctx->verify_cb(0, ctx); + if(!ctx->verify_cb(0, ctx)) + return 0; } return 1; } @@ -1039,12 +1667,12 @@ end: return ok; } -int X509_cmp_current_time(ASN1_TIME *ctm) +int X509_cmp_current_time(const ASN1_TIME *ctm) { return X509_cmp_time(ctm, NULL); } -int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) +int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) { char *str; ASN1_TIME atm; @@ -1099,6 +1727,7 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) offset= -offset; } atm.type=ctm->type; + atm.flags = 0; atm.length=sizeof(buff2); atm.data=(unsigned char *)buff2; @@ -1127,19 +1756,28 @@ ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) return X509_time_adj(s, adj, NULL); } -ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) + { + return X509_time_adj_ex(s, 0, offset_sec, in_tm); + } + +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *in_tm) { time_t t; - int type = -1; if (in_tm) t = *in_tm; else time(&t); - t+=adj; - if (s) type = s->type; - if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); - if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t); - return ASN1_TIME_set(s, t); + if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) + { + if (s->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec); + if (s->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, + offset_sec); + } + return ASN1_TIME_adj(s, t, offset_day, offset_sec); } int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) @@ -1242,6 +1880,21 @@ STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) return chain; } +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) + { + return ctx->current_issuer; + } + +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) + { + return ctx->current_crl; + } + +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) + { + return ctx->parent; + } + void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) { ctx->cert=x; @@ -1363,6 +2016,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->current_cert=NULL; ctx->current_issuer=NULL; ctx->tree = NULL; + ctx->parent = NULL; ctx->param = X509_VERIFY_PARAM_new(); @@ -1428,7 +2082,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, if (store && store->get_crl) ctx->get_crl = store->get_crl; else - ctx->get_crl = get_crl; + ctx->get_crl = NULL; if (store && store->check_crl) ctx->check_crl = store->check_crl; @@ -1440,6 +2094,16 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, else ctx->cert_crl = cert_crl; + if (store && store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = X509_STORE_get1_certs; + + if (store && store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = X509_STORE_get1_crls; + ctx->check_policy = check_policy; @@ -1472,7 +2136,8 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) if (ctx->cleanup) ctx->cleanup(ctx); if (ctx->param != NULL) { - X509_VERIFY_PARAM_free(ctx->param); + if (ctx->parent == NULL) + X509_VERIFY_PARAM_free(ctx->param); ctx->param=NULL; } if (ctx->tree != NULL) diff --git a/crypto/openssl/crypto/x509/x509_vfy.h b/crypto/openssl/crypto/x509/x509_vfy.h index 86ae35f69d..fe09b30aaa 100644 --- a/crypto/openssl/crypto/x509/x509_vfy.h +++ b/crypto/openssl/crypto/x509/x509_vfy.h @@ -77,6 +77,7 @@ extern "C" { #endif +#if 0 /* Outer object */ typedef struct x509_hash_dir_st { @@ -85,6 +86,7 @@ typedef struct x509_hash_dir_st int *dirs_type; int num_dirs_alloced; } X509_HASH_DIR_CTX; +#endif typedef struct x509_file_st { @@ -198,6 +200,8 @@ struct x509_store_st int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); int (*cleanup)(X509_STORE_CTX *ctx); CRYPTO_EX_DATA ex_data; @@ -246,6 +250,8 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ int (*check_policy)(X509_STORE_CTX *ctx); + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); int (*cleanup)(X509_STORE_CTX *ctx); /* The following is built up */ @@ -263,6 +269,11 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ X509 *current_issuer; /* cert currently being tested as valid issuer */ X509_CRL *current_crl; /* current CRL */ + int current_crl_score; /* score of current CRL */ + unsigned int current_reasons; /* Reason mask */ + + X509_STORE_CTX *parent; /* For CRL path validation: parent context */ + CRYPTO_EX_DATA ex_data; } /* X509_STORE_CTX */; @@ -330,8 +341,18 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_ERR_INVALID_EXTENSION 41 #define X509_V_ERR_INVALID_POLICY_EXTENSION 42 #define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +#define X509_V_ERR_UNNESTED_RESOURCE 46 -#define X509_V_ERR_UNNESTED_RESOURCE 44 +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 /* The application is not happy */ #define X509_V_ERR_APPLICATION_VERIFICATION 50 @@ -362,10 +383,14 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_FLAG_INHIBIT_MAP 0x400 /* Notify callback that policy is OK */ #define X509_V_FLAG_NOTIFY_POLICY 0x800 - +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +#define X509_V_FLAG_USE_DELTAS 0x2000 /* Check selfsigned CA signature */ #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 + #define X509_VP_FLAG_DEFAULT 0x1 #define X509_VP_FLAG_OVERWRITE 0x2 #define X509_VP_FLAG_RESET_FLAGS 0x4 @@ -387,11 +412,16 @@ void X509_OBJECT_free_contents(X509_OBJECT *a); X509_STORE *X509_STORE_new(void ); void X509_STORE_free(X509_STORE *v); +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); int X509_STORE_set_trust(X509_STORE *ctx, int trust); int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + X509_STORE_CTX *X509_STORE_CTX_new(void); int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); @@ -450,6 +480,9 @@ int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); diff --git a/crypto/openssl/crypto/x509/x509_vpm.c b/crypto/openssl/crypto/x509/x509_vpm.c index 01c5541e2e..dfd89d89fa 100644 --- a/crypto/openssl/crypto/x509/x509_vpm.c +++ b/crypto/openssl/crypto/x509/x509_vpm.c @@ -74,6 +74,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param) param->name = NULL; param->purpose = 0; param->trust = 0; + /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ param->inh_flags = 0; param->flags = 0; param->depth = -1; @@ -328,7 +329,7 @@ static const X509_VERIFY_PARAM default_table[] = { NULL /* policies */ }, { - "pkcs7", /* S/MIME signing parameters */ + "pkcs7", /* S/MIME sign parameters */ 0, /* Check time */ 0, /* internal flags */ 0, /* flags */ @@ -338,7 +339,7 @@ static const X509_VERIFY_PARAM default_table[] = { NULL /* policies */ }, { - "smime_sign", /* S/MIME signing parameters */ + "smime_sign", /* S/MIME sign parameters */ 0, /* Check time */ 0, /* internal flags */ 0, /* flags */ @@ -370,12 +371,17 @@ static const X509_VERIFY_PARAM default_table[] = { static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; -static int table_cmp(const void *pa, const void *pb) +static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) + { - const X509_VERIFY_PARAM *a = pa, *b = pb; return strcmp(a->name, b->name); } +DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, + table); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, + table); + static int param_cmp(const X509_VERIFY_PARAM * const *a, const X509_VERIFY_PARAM * const *b) { @@ -411,6 +417,7 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) { int idx; X509_VERIFY_PARAM pm; + pm.name = (char *)name; if (param_table) { @@ -418,11 +425,8 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) if (idx != -1) return sk_X509_VERIFY_PARAM_value(param_table, idx); } - return (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm, - (char *)&default_table, - sizeof(default_table)/sizeof(X509_VERIFY_PARAM), - sizeof(X509_VERIFY_PARAM), - table_cmp); + return OBJ_bsearch_table(&pm, default_table, + sizeof(default_table)/sizeof(X509_VERIFY_PARAM)); } void X509_VERIFY_PARAM_table_cleanup(void) diff --git a/crypto/openssl/crypto/x509/x509cset.c b/crypto/openssl/crypto/x509/x509cset.c index 7f4004b291..3109defb0b 100644 --- a/crypto/openssl/crypto/x509/x509cset.c +++ b/crypto/openssl/crypto/x509/x509cset.c @@ -81,7 +81,7 @@ int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) } -int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) { ASN1_TIME *in; @@ -99,7 +99,7 @@ int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) return(in != NULL); } -int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) { ASN1_TIME *in; diff --git a/crypto/openssl/crypto/x509/x509name.c b/crypto/openssl/crypto/x509/x509name.c index 068abfe5f0..27bc4dc9a3 100644 --- a/crypto/openssl/crypto/x509/x509name.c +++ b/crypto/openssl/crypto/x509/x509name.c @@ -356,7 +356,7 @@ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type, OBJ_obj2nid(ne->object)) ? 1 : 0; - if (len < 0) len=strlen((char *)bytes); + if (len < 0) len=strlen((const char *)bytes); i=ASN1_STRING_set(ne->value,bytes,len); if (!i) return(0); if (type != V_ASN1_UNDEF) diff --git a/crypto/openssl/crypto/x509/x509type.c b/crypto/openssl/crypto/x509/x509type.c index 2cd994c5b0..3385ad3f67 100644 --- a/crypto/openssl/crypto/x509/x509type.c +++ b/crypto/openssl/crypto/x509/x509type.c @@ -91,6 +91,10 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey) break; case EVP_PKEY_DH: ret=EVP_PK_DH|EVP_PKT_EXCH; + break; + case NID_id_GostR3410_94: + case NID_id_GostR3410_2001: + ret=EVP_PKT_EXCH|EVP_PKT_SIGN; break; default: break; diff --git a/crypto/openssl/crypto/x509/x_all.c b/crypto/openssl/crypto/x509/x_all.c index 9039caad60..ebae30b701 100644 --- a/crypto/openssl/crypto/x509/x_all.c +++ b/crypto/openssl/crypto/x509/x_all.c @@ -57,7 +57,6 @@ */ #include -#undef SSLEAY_MACROS #include #include "cryptlib.h" #include @@ -83,12 +82,6 @@ int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) a->sig_alg,a->signature,a->req_info,r)); } -int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r) - { - return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), - a->sig_alg, a->signature,a->crl,r)); - } - int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) { return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), diff --git a/crypto/openssl/crypto/x509v3/ext_dat.h b/crypto/openssl/crypto/x509v3/ext_dat.h index 3eaec46f8a..76daee6fcd 100644 --- a/crypto/openssl/crypto/x509v3/ext_dat.h +++ b/crypto/openssl/crypto/x509v3/ext_dat.h @@ -61,21 +61,19 @@ extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; -extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld; +extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; -extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp; -#ifndef OPENSSL_NO_RFC3779 +extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; extern X509V3_EXT_METHOD v3_addr, v3_asid; -#endif /* This table will be searched using OBJ_bsearch so it *must* kept in * order of the ext_nid values. */ -static X509V3_EXT_METHOD *standard_exts[] = { +static const X509V3_EXT_METHOD *standard_exts[] = { &v3_nscert, &v3_ns_ia5_list[0], &v3_ns_ia5_list[1], @@ -122,7 +120,10 @@ static X509V3_EXT_METHOD *standard_exts[] = { &v3_pci, &v3_name_constraints, &v3_policy_mappings, -&v3_inhibit_anyp +&v3_inhibit_anyp, +&v3_idp, +&v3_alt[2], +&v3_freshest_crl, }; /* Number of standard extensions */ diff --git a/crypto/openssl/crypto/x509v3/pcy_cache.c b/crypto/openssl/crypto/x509v3/pcy_cache.c index 1030931b71..172b7e7ee4 100644 --- a/crypto/openssl/crypto/x509v3/pcy_cache.c +++ b/crypto/openssl/crypto/x509v3/pcy_cache.c @@ -139,7 +139,6 @@ static int policy_cache_new(X509 *x) return 0; cache->anyPolicy = NULL; cache->data = NULL; - cache->maps = NULL; cache->any_skip = -1; cache->explicit_skip = -1; cache->map_skip = -1; diff --git a/crypto/openssl/crypto/x509v3/pcy_data.c b/crypto/openssl/crypto/x509v3/pcy_data.c index fb392b901f..3444b03195 100644 --- a/crypto/openssl/crypto/x509v3/pcy_data.c +++ b/crypto/openssl/crypto/x509v3/pcy_data.c @@ -82,17 +82,21 @@ void policy_data_free(X509_POLICY_DATA *data) * another source. */ -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit) +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, + const ASN1_OBJECT *cid, int crit) { X509_POLICY_DATA *ret; - if (!policy && !id) + ASN1_OBJECT *id; + if (!policy && !cid) return NULL; - if (id) + if (cid) { - id = OBJ_dup(id); + id = OBJ_dup(cid); if (!id) return NULL; } + else + id = NULL; ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); if (!ret) return NULL; diff --git a/crypto/openssl/crypto/x509v3/pcy_int.h b/crypto/openssl/crypto/x509v3/pcy_int.h index 3780de4fcd..ccff92846e 100644 --- a/crypto/openssl/crypto/x509v3/pcy_int.h +++ b/crypto/openssl/crypto/x509v3/pcy_int.h @@ -56,12 +56,10 @@ * */ -DECLARE_STACK_OF(X509_POLICY_DATA) -DECLARE_STACK_OF(X509_POLICY_REF) -DECLARE_STACK_OF(X509_POLICY_NODE) typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; -typedef struct X509_POLICY_REF_st X509_POLICY_REF; + +DECLARE_STACK_OF(X509_POLICY_DATA) /* Internal structures */ @@ -110,16 +108,6 @@ struct X509_POLICY_DATA_st #define POLICY_DATA_FLAG_CRITICAL 0x10 -/* This structure is an entry from a table of mapped policies which - * cross reference the policy it refers to. - */ - -struct X509_POLICY_REF_st - { - ASN1_OBJECT *subjectDomainPolicy; - const X509_POLICY_DATA *data; - }; - /* This structure is cached with a certificate */ struct X509_POLICY_CACHE_st { @@ -127,8 +115,6 @@ struct X509_POLICY_CACHE_st { X509_POLICY_DATA *anyPolicy; /* other policy data */ STACK_OF(X509_POLICY_DATA) *data; - /* If policyMappings extension present a table of mapped policies */ - STACK_OF(X509_POLICY_REF) *maps; /* If InhibitAnyPolicy present this is its value or -1 if absent. */ long any_skip; /* If policyConstraints and requireExplicitPolicy present this is its @@ -193,7 +179,7 @@ struct X509_POLICY_TREE_st /* Internal functions */ -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, int crit); void policy_data_free(X509_POLICY_DATA *data); @@ -209,15 +195,18 @@ void policy_cache_init(void); void policy_cache_free(X509_POLICY_CACHE *cache); X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, const ASN1_OBJECT *id); X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, const ASN1_OBJECT *id); X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, + const X509_POLICY_DATA *data, X509_POLICY_NODE *parent, X509_POLICY_TREE *tree); void policy_node_free(X509_POLICY_NODE *node); +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); const X509_POLICY_CACHE *policy_cache_set(X509 *x); diff --git a/crypto/openssl/crypto/x509v3/pcy_map.c b/crypto/openssl/crypto/x509v3/pcy_map.c index f28796e6d4..21163b529d 100644 --- a/crypto/openssl/crypto/x509v3/pcy_map.c +++ b/crypto/openssl/crypto/x509v3/pcy_map.c @@ -62,31 +62,6 @@ #include "pcy_int.h" -static int ref_cmp(const X509_POLICY_REF * const *a, - const X509_POLICY_REF * const *b) - { - return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); - } - -static void policy_map_free(X509_POLICY_REF *map) - { - if (map->subjectDomainPolicy) - ASN1_OBJECT_free(map->subjectDomainPolicy); - OPENSSL_free(map); - } - -static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *id) - { - X509_POLICY_REF tmp; - int idx; - tmp.subjectDomainPolicy = id; - - idx = sk_X509_POLICY_REF_find(cache->maps, &tmp); - if (idx == -1) - return NULL; - return sk_X509_POLICY_REF_value(cache->maps, idx); - } - /* Set policy mapping entries in cache. * Note: this modifies the passed POLICY_MAPPINGS structure */ @@ -94,7 +69,6 @@ static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *i int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) { POLICY_MAPPING *map; - X509_POLICY_REF *ref = NULL; X509_POLICY_DATA *data; X509_POLICY_CACHE *cache = x->policy_cache; int i; @@ -104,7 +78,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) ret = -1; goto bad_mapping; } - cache->maps = sk_X509_POLICY_REF_new(ref_cmp); for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { map = sk_POLICY_MAPPING_value(maps, i); @@ -116,13 +89,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) goto bad_mapping; } - /* If we've already mapped from this OID bad mapping */ - if (policy_map_find(cache, map->subjectDomainPolicy) != NULL) - { - ret = -1; - goto bad_mapping; - } - /* Attempt to find matching policy data */ data = policy_cache_find_data(cache, map->issuerDomainPolicy); /* If we don't have anyPolicy can't map */ @@ -138,7 +104,7 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) if (!data) goto bad_mapping; data->qualifier_set = cache->anyPolicy->qualifier_set; - map->issuerDomainPolicy = NULL; + /*map->issuerDomainPolicy = NULL;*/ data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; if (!sk_X509_POLICY_DATA_push(cache->data, data)) @@ -149,23 +115,10 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) } else data->flags |= POLICY_DATA_FLAG_MAPPED; - if (!sk_ASN1_OBJECT_push(data->expected_policy_set, map->subjectDomainPolicy)) goto bad_mapping; - - ref = OPENSSL_malloc(sizeof(X509_POLICY_REF)); - if (!ref) - goto bad_mapping; - - ref->subjectDomainPolicy = map->subjectDomainPolicy; map->subjectDomainPolicy = NULL; - ref->data = data; - - if (!sk_X509_POLICY_REF_push(cache->maps, ref)) - goto bad_mapping; - - ref = NULL; } @@ -173,13 +126,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) bad_mapping: if (ret == -1) x->ex_flags |= EXFLAG_INVALID_POLICY; - if (ref) - policy_map_free(ref); - if (ret <= 0) - { - sk_X509_POLICY_REF_pop_free(cache->maps, policy_map_free); - cache->maps = NULL; - } sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); return ret; diff --git a/crypto/openssl/crypto/x509v3/pcy_node.c b/crypto/openssl/crypto/x509v3/pcy_node.c index 6587cb05ab..bd1e7f1ae8 100644 --- a/crypto/openssl/crypto/x509v3/pcy_node.c +++ b/crypto/openssl/crypto/x509v3/pcy_node.c @@ -92,13 +92,25 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, } X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, const ASN1_OBJECT *id) { - return tree_find_sk(level->nodes, id); + X509_POLICY_NODE *node; + int i; + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) + { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (node->parent == parent) + { + if (!OBJ_cmp(node->data->valid_policy, id)) + return node; + } + } + return NULL; } X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, + const X509_POLICY_DATA *data, X509_POLICY_NODE *parent, X509_POLICY_TREE *tree) { @@ -155,4 +167,31 @@ void policy_node_free(X509_POLICY_NODE *node) OPENSSL_free(node); } +/* See if a policy node matches a policy OID. If mapping enabled look through + * expected policy set otherwise just valid policy. + */ + +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) + { + int i; + ASN1_OBJECT *policy_oid; + const X509_POLICY_DATA *x = node->data; + + if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP) + || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) + { + if (!OBJ_cmp(x->valid_policy, oid)) + return 1; + return 0; + } + + for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) + { + policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); + if (!OBJ_cmp(policy_oid, oid)) + return 1; + } + return 0; + } diff --git a/crypto/openssl/crypto/x509v3/pcy_tree.c b/crypto/openssl/crypto/x509v3/pcy_tree.c index 89f84bfa18..92f6b24556 100644 --- a/crypto/openssl/crypto/x509v3/pcy_tree.c +++ b/crypto/openssl/crypto/x509v3/pcy_tree.c @@ -62,6 +62,75 @@ #include "pcy_int.h" +/* Enable this to print out the complete policy tree at various point during + * evaluation. + */ + +/*#define OPENSSL_POLICY_DEBUG*/ + +#ifdef OPENSSL_POLICY_DEBUG + +static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, + X509_POLICY_NODE *node, int indent) + { + if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) + BIO_puts(err, " Not Mapped\n"); + else + { + int i; + STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; + ASN1_OBJECT *oid; + BIO_puts(err, " Expected: "); + for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) + { + oid = sk_ASN1_OBJECT_value(pset, i); + if (i) + BIO_puts(err, ", "); + i2a_ASN1_OBJECT(err, oid); + } + BIO_puts(err, "\n"); + } + } + +static void tree_print(char *str, X509_POLICY_TREE *tree, + X509_POLICY_LEVEL *curr) + { + X509_POLICY_LEVEL *plev; + X509_POLICY_NODE *node; + int i; + BIO *err; + err = BIO_new_fp(stderr, BIO_NOCLOSE); + if (!curr) + curr = tree->levels + tree->nlevel; + else + curr++; + BIO_printf(err, "Level print after %s\n", str); + BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); + for (plev = tree->levels; plev != curr; plev++) + { + BIO_printf(err, "Level %ld, flags = %x\n", + plev - tree->levels, plev->flags); + for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) + { + node = sk_X509_POLICY_NODE_value(plev->nodes, i); + X509_POLICY_NODE_print(err, node, 2); + expected_print(err, plev, node, 2); + BIO_printf(err, " Flags: %x\n", node->data->flags); + } + if (plev->anyPolicy) + X509_POLICY_NODE_print(err, plev->anyPolicy, 2); + } + + BIO_free(err); + + } +#else + +#define tree_print(a,b,c) /* */ + +#endif + /* Initialize policy tree. Return values: * 0 Some internal error occured. * -1 Inconsistent or invalid extensions in certificates. @@ -87,8 +156,10 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, *ptree = NULL; n = sk_X509_num(certs); +#if 0 /* Disable policy mapping for now... */ flags |= X509_V_FLAG_INHIBIT_MAP; +#endif if (flags & X509_V_FLAG_EXPLICIT_POLICY) explicit_policy = 0; @@ -184,7 +255,6 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, level++; x = sk_X509_value(certs, i); cache = policy_cache_set(x); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); level->cert = x; @@ -213,13 +283,13 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, level->flags |= X509_V_FLAG_INHIBIT_MAP; else { - map_skip--; + if (!(x->ex_flags & EXFLAG_SI)) + map_skip--; if ((cache->map_skip >= 0) && (cache->map_skip < map_skip)) map_skip = cache->map_skip; } - } *ptree = tree; @@ -237,7 +307,32 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, } -/* This corresponds to RFC3280 XXXX XXXXX: +static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + const X509_POLICY_DATA *data) + { + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int i, matched = 0; + /* Iterate through all in nodes linking matches */ + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) + { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + if (policy_node_match(last, node, data->valid_policy)) + { + if (!level_add_node(curr, data, node, NULL)) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) + { + if (!level_add_node(curr, data, last->anyPolicy, NULL)) + return 0; + } + return 1; + } + +/* This corresponds to RFC3280 6.1.3(d)(1): * link any data from CertificatePolicies onto matching parent * or anyPolicy if no match. */ @@ -248,7 +343,6 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr, int i; X509_POLICY_LEVEL *last; X509_POLICY_DATA *data; - X509_POLICY_NODE *parent; last = curr - 1; for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { @@ -261,40 +355,109 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr, * link because then it will have the mapping flags * right and we can prune it later. */ +#if 0 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) continue; - /* Look for matching node in parent */ - parent = level_find_node(last, data->valid_policy); - /* If no match link to anyPolicy */ - if (!parent) - parent = last->anyPolicy; - if (parent && !level_add_node(curr, data, parent, NULL)) +#endif + /* Look for matching nodes in previous level */ + if (!tree_link_matching_nodes(curr, data)) return 0; } return 1; } -/* This corresponds to RFC3280 XXXX XXXXX: +/* This corresponds to RFC3280 6.1.3(d)(2): * Create new data for any unmatched policies in the parent and link * to anyPolicy. */ +static int tree_add_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id, + X509_POLICY_NODE *node, + X509_POLICY_TREE *tree) + { + X509_POLICY_DATA *data; + if (id == NULL) + id = node->data->valid_policy; + /* Create a new node with qualifiers from anyPolicy and + * id from unmatched node. + */ + data = policy_data_new(NULL, id, node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) + { + policy_data_free(data); + return 0; + } + + return 1; + } + +static int tree_link_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_NODE *node, + X509_POLICY_TREE *tree) + { + const X509_POLICY_LEVEL *last = curr - 1; + int i; + + if ( (last->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) + { + /* If no policy mapping: matched if one child present */ + if (node->nchild) + return 1; + if (!tree_add_unmatched(curr, cache, NULL, node, tree)) + return 0; + /* Add it */ + } + else + { + /* If mapping: matched if one child per expected policy set */ + STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; + if (node->nchild == sk_ASN1_OBJECT_num(expset)) + return 1; + /* Locate unmatched nodes */ + for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) + { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); + if (level_find_node(curr, node, oid)) + continue; + if (!tree_add_unmatched(curr, cache, oid, node, tree)) + return 0; + } + + } + + return 1; + + } + static int tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, X509_POLICY_TREE *tree) { int i; - X509_POLICY_DATA *data; + /*X509_POLICY_DATA *data;*/ X509_POLICY_NODE *node; - X509_POLICY_LEVEL *last; - - last = curr - 1; + X509_POLICY_LEVEL *last = curr - 1; for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { node = sk_X509_POLICY_NODE_value(last->nodes, i); + if (!tree_link_unmatched(curr, cache, node, tree)) + return 0; + +#if 0 + /* Skip any node with any children: we only want unmathced * nodes. * @@ -303,6 +466,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, */ if (node->nchild) continue; + /* Create a new node with qualifiers from anyPolicy and * id from unmatched node. */ @@ -319,6 +483,9 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, policy_data_free(data); return 0; } + +#endif + } /* Finally add link to anyPolicy */ if (last->anyPolicy) @@ -337,30 +504,36 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) { + STACK_OF(X509_POLICY_NODE) *nodes; X509_POLICY_NODE *node; int i; - for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) + nodes = curr->nodes; + if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { - node = sk_X509_POLICY_NODE_value(curr->nodes, i); - /* Delete any mapped data: see RFC3280 XXXX */ - if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { - node->parent->nchild--; - OPENSSL_free(node); - (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); + node = sk_X509_POLICY_NODE_value(nodes, i); + /* Delete any mapped data: see RFC3280 XXXX */ + if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) + { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes,i); + } } } for(;;) { --curr; - for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) + nodes = curr->nodes; + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { - node = sk_X509_POLICY_NODE_value(curr->nodes, i); + node = sk_X509_POLICY_NODE_value(nodes, i); if (node->nchild == 0) { node->parent->nchild--; OPENSSL_free(node); - (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); + (void)sk_X509_POLICY_NODE_delete(nodes, i); } } if (curr->anyPolicy && !curr->anyPolicy->nchild) @@ -536,6 +709,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree) if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) && !tree_link_any(curr, cache, tree)) return 0; + tree_print("before tree_prune()", tree, curr); ret = tree_prune(tree, curr); if (ret != 1) return ret; @@ -604,7 +778,6 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, *pexplicit_policy = 0; ret = tree_init(&tree, certs, flags); - switch (ret) { @@ -612,6 +785,10 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, case 2: return 1; + /* Some internal error */ + case -1: + return -1; + /* Some internal error */ case 0: return 0; @@ -646,6 +823,8 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, if (!tree) goto error; ret = tree_evaluate(tree); + tree_print("tree_evaluate()", tree, NULL); + if (ret <= 0) goto error; diff --git a/crypto/openssl/crypto/x509v3/v3_addr.c b/crypto/openssl/crypto/x509v3/v3_addr.c index efdf7c3ba7..9087d66e0a 100644 --- a/crypto/openssl/crypto/x509v3/v3_addr.c +++ b/crypto/openssl/crypto/x509v3/v3_addr.c @@ -236,7 +236,7 @@ static int i2r_IPAddressOrRanges(BIO *out, /* * i2r handler for an IPAddrBlocks extension. */ -static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method, +static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, int indent) @@ -315,8 +315,7 @@ static int IPAddressOrRange_cmp(const IPAddressOrRange *a, const int length) { unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; - int prefixlen_a = 0; - int prefixlen_b = 0; + int prefixlen_a = 0, prefixlen_b = 0; int r; switch (a->type) { @@ -596,10 +595,10 @@ static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, return NULL; switch (afi) { case IANA_AFI_IPV4: - (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); + sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); break; case IANA_AFI_IPV6: - (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); + sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); break; } f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; @@ -856,7 +855,7 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, if (!make_addressRange(&merged, a_min, b_max, length)) return 0; sk_IPAddressOrRange_set(aors, i, merged); - (void)sk_IPAddressOrRange_delete(aors, i + 1); + sk_IPAddressOrRange_delete(aors, i + 1); IPAddressOrRange_free(a); IPAddressOrRange_free(b); --i; @@ -880,7 +879,7 @@ int v3_addr_canonize(IPAddrBlocks *addr) v3_addr_get_afi(f))) return 0; } - (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); + sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); sk_IPAddressFamily_sort(addr); OPENSSL_assert(v3_addr_is_canonical(addr)); return 1; @@ -889,7 +888,7 @@ int v3_addr_canonize(IPAddrBlocks *addr) /* * v2i handler for the IPAddrBlocks extension. */ -static void *v2i_IPAddrBlocks(struct v3_ext_method *method, +static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values) { @@ -1125,7 +1124,7 @@ int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) return 1; if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) return 0; - (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); + sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); for (i = 0; i < sk_IPAddressFamily_num(a); i++) { IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); int j = sk_IPAddressFamily_find(b, fa); @@ -1167,7 +1166,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, { IPAddrBlocks *child = NULL; int i, j, ret = 1; - X509 *x = NULL; + X509 *x; OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); OPENSSL_assert(ctx != NULL || ext != NULL); @@ -1180,6 +1179,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, */ if (ext != NULL) { i = -1; + x = NULL; } else { i = 0; x = sk_X509_value(chain, i); @@ -1189,7 +1189,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, } if (!v3_addr_is_canonical(ext)) validation_err(X509_V_ERR_INVALID_EXTENSION); - (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); + sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE); ret = 0; @@ -1215,7 +1215,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, } continue; } - (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); + sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); for (j = 0; j < sk_IPAddressFamily_num(child); j++) { IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); @@ -1242,6 +1242,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, /* * Trust anchor can't inherit. */ + OPENSSL_assert(x != NULL); if (x->rfc3779_addr != NULL) { for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j); diff --git a/crypto/openssl/crypto/x509v3/v3_alt.c b/crypto/openssl/crypto/x509v3/v3_alt.c index 69244e4976..d29d94338e 100644 --- a/crypto/openssl/crypto/x509v3/v3_alt.c +++ b/crypto/openssl/crypto/x509v3/v3_alt.c @@ -82,6 +82,12 @@ NULL, NULL, NULL}, (X509V3_EXT_I2V)i2v_GENERAL_NAMES, (X509V3_EXT_V2I)v2i_issuer_alt, NULL, NULL, NULL}, + +{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), +0,0,0,0, +0,0, +(X509V3_EXT_I2V)i2v_GENERAL_NAMES, +NULL, NULL, NULL, NULL}, }; STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, @@ -387,8 +393,8 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) } -GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { GENERAL_NAME *gen; GENERAL_NAMES *gens = NULL; @@ -409,28 +415,22 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, return NULL; } -GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf) +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf) { return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); } -GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, - X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf, int is_nc) +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + int gen_type, char *value, int is_nc) { char is_string = 0; - int type; GENERAL_NAME *gen = NULL; - char *name, *value; - - name = cnf->name; - value = cnf->value; - if(!value) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE); + X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE); return NULL; } @@ -441,74 +441,62 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, gen = GENERAL_NAME_new(); if(gen == NULL) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE); + X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); return NULL; } } - if(!name_cmp(name, "email")) - { - is_string = 1; - type = GEN_EMAIL; - } - else if(!name_cmp(name, "URI")) - { - is_string = 1; - type = GEN_URI; - } - else if(!name_cmp(name, "DNS")) + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: is_string = 1; - type = GEN_DNS; - } - else if(!name_cmp(name, "RID")) + break; + + case GEN_RID: { ASN1_OBJECT *obj; if(!(obj = OBJ_txt2obj(value,0))) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_OBJECT); + X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT); ERR_add_error_data(2, "value=", value); goto err; } gen->d.rid = obj; - type = GEN_RID; } - else if(!name_cmp(name, "IP")) - { + break; + + case GEN_IPADD: if (is_nc) gen->d.ip = a2i_IPADDRESS_NC(value); else gen->d.ip = a2i_IPADDRESS(value); if(gen->d.ip == NULL) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_IP_ADDRESS); + X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS); ERR_add_error_data(2, "value=", value); goto err; } - type = GEN_IPADD; - } - else if(!name_cmp(name, "dirName")) - { - type = GEN_DIRNAME; + break; + + case GEN_DIRNAME: if (!do_dirname(gen, value, ctx)) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_DIRNAME_ERROR); + X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR); goto err; } - } - else if(!name_cmp(name, "otherName")) - { + break; + + case GEN_OTHERNAME: if (!do_othername(gen, value, ctx)) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_OTHERNAME_ERROR); + X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR); goto err; } - type = GEN_OTHERNAME; - } - else - { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION); - ERR_add_error_data(2, "name=", name); + break; + default: + X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE); goto err; } @@ -518,12 +506,12 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, strlen(value))) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE); + X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); goto err; } } - gen->type = type; + gen->type = gen_type; return gen; @@ -533,6 +521,48 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, return NULL; } +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) + { + int type; + + char *name, *value; + + name = cnf->name; + value = cnf->value; + + if(!value) + { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE); + return NULL; + } + + if(!name_cmp(name, "email")) + type = GEN_EMAIL; + else if(!name_cmp(name, "URI")) + type = GEN_URI; + else if(!name_cmp(name, "DNS")) + type = GEN_DNS; + else if(!name_cmp(name, "RID")) + type = GEN_RID; + else if(!name_cmp(name, "IP")) + type = GEN_IPADD; + else if(!name_cmp(name, "dirName")) + type = GEN_DIRNAME; + else if(!name_cmp(name, "otherName")) + type = GEN_OTHERNAME; + else + { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION); + ERR_add_error_data(2, "name=", name); + return NULL; + } + + return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); + + } + static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) { char *objtmp = NULL, *p; @@ -578,7 +608,6 @@ static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) if (!ret) X509_NAME_free(nm); gen->d.dirn = nm; - X509V3_section_free(ctx, sk); return ret; diff --git a/crypto/openssl/crypto/x509v3/v3_asid.c b/crypto/openssl/crypto/x509v3/v3_asid.c index abd497ed1f..56702f86b9 100644 --- a/crypto/openssl/crypto/x509v3/v3_asid.c +++ b/crypto/openssl/crypto/x509v3/v3_asid.c @@ -152,7 +152,7 @@ static int i2r_ASIdentifierChoice(BIO *out, /* * i2r method for an ASIdentifier extension. */ -static int i2r_ASIdentifiers(X509V3_EXT_METHOD *method, +static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out, int indent) @@ -466,7 +466,7 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) break; } ASIdOrRange_free(b); - (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); + sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); i--; continue; } @@ -495,7 +495,7 @@ int v3_asid_canonize(ASIdentifiers *asid) /* * v2i method for an ASIdentifier extension. */ -static void *v2i_ASIdentifiers(struct v3_ext_method *method, +static void *v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values) { @@ -707,7 +707,7 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, { ASIdOrRanges *child_as = NULL, *child_rdi = NULL; int i, ret = 1, inherit_as = 0, inherit_rdi = 0; - X509 *x = NULL; + X509 *x; assert(chain != NULL && sk_X509_num(chain) > 0); assert(ctx != NULL || ext != NULL); @@ -720,6 +720,7 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, */ if (ext != NULL) { i = -1; + x = NULL; } else { i = 0; x = sk_X509_value(chain, i); @@ -799,6 +800,7 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, /* * Trust anchor can't inherit. */ + assert(x != NULL); if (x->rfc3779_asid != NULL) { if (x->rfc3779_asid->asnum != NULL && x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) diff --git a/crypto/openssl/crypto/x509v3/v3_conf.c b/crypto/openssl/crypto/x509v3/v3_conf.c index 11eb6b7fd5..6730f9a6ee 100644 --- a/crypto/openssl/crypto/x509v3/v3_conf.c +++ b/crypto/openssl/crypto/x509v3/v3_conf.c @@ -72,14 +72,14 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, in static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx); static char *conf_lhash_get_string(void *db, char *section, char *value); static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); -static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, - int crit, void *ext_struc); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, + int crit, void *ext_struc); static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len); /* CONF *conf: Config file */ /* char *name: Name */ /* char *value: Value */ X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, - char *value) + char *value) { int crit; int ext_type; @@ -99,7 +99,7 @@ X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, /* CONF *conf: Config file */ /* char *value: Value */ X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, - char *value) + char *value) { int crit; int ext_type; @@ -113,9 +113,9 @@ X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, /* CONF *conf: Config file */ /* char *value: Value */ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, char *value) + int crit, char *value) { - X509V3_EXT_METHOD *method; + const X509V3_EXT_METHOD *method; X509_EXTENSION *ext; STACK_OF(CONF_VALUE) *nval; void *ext_struc; @@ -172,8 +172,8 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, } -static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, - int crit, void *ext_struc) +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, + int crit, void *ext_struc) { unsigned char *ext_der; int ext_len; @@ -214,7 +214,7 @@ static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) { - X509V3_EXT_METHOD *method; + const X509V3_EXT_METHOD *method; if (!(method = X509V3_EXT_get_nid(ext_nid))) { X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION); return NULL; @@ -258,7 +258,8 @@ static int v3_check_generic(char **value) /* Create a generic extension: for now just handle DER type */ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, - int crit, int gen_type, X509V3_CTX *ctx) + int crit, int gen_type, + X509V3_CTX *ctx) { unsigned char *ext_der=NULL; long ext_len; @@ -322,7 +323,7 @@ static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len) int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, - STACK_OF(X509_EXTENSION) **sk) + STACK_OF(X509_EXTENSION) **sk) { X509_EXTENSION *ext; STACK_OF(CONF_VALUE) *nval; @@ -343,7 +344,7 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, /* Convenience functions to add extensions to a certificate, CRL and request */ int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509 *cert) + X509 *cert) { STACK_OF(X509_EXTENSION) **sk = NULL; if (cert) @@ -354,7 +355,7 @@ int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, /* Same as above but for a CRL */ int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509_CRL *crl) + X509_CRL *crl) { STACK_OF(X509_EXTENSION) **sk = NULL; if (crl) @@ -443,7 +444,7 @@ void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) } void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, - X509_CRL *crl, int flags) + X509_CRL *crl, int flags) { ctx->issuer_cert = issuer; ctx->subject_cert = subj; @@ -454,8 +455,8 @@ void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, /* Old conf compatibility functions */ -X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, - char *value) +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value) { CONF ctmp; CONF_set_nconf(&ctmp, conf); @@ -464,8 +465,8 @@ X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, /* LHASH *conf: Config file */ /* char *value: Value */ -X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, - char *value) +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + int ext_nid, char *value) { CONF ctmp; CONF_set_nconf(&ctmp, conf); @@ -489,14 +490,14 @@ NULL, NULL }; -void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash) +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) { ctx->db_meth = &conf_lhash_method; ctx->db = lhash; } -int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, - X509 *cert) +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert) { CONF ctmp; CONF_set_nconf(&ctmp, conf); @@ -505,8 +506,8 @@ int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, /* Same as above but for a CRL */ -int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, - X509_CRL *crl) +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl) { CONF ctmp; CONF_set_nconf(&ctmp, conf); @@ -515,8 +516,8 @@ int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, /* Add extensions to certificate request */ -int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, - X509_REQ *req) +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req) { CONF ctmp; CONF_set_nconf(&ctmp, conf); diff --git a/crypto/openssl/crypto/x509v3/v3_cpols.c b/crypto/openssl/crypto/x509v3/v3_cpols.c index ad0506d75c..1f0798b946 100644 --- a/crypto/openssl/crypto/x509v3/v3_cpols.c +++ b/crypto/openssl/crypto/x509v3/v3_cpols.c @@ -450,5 +450,8 @@ void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) else BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); } - + + IMPLEMENT_STACK_OF(X509_POLICY_NODE) +IMPLEMENT_STACK_OF(X509_POLICY_DATA) + diff --git a/crypto/openssl/crypto/x509v3/v3_crld.c b/crypto/openssl/crypto/x509v3/v3_crld.c index 181a8977b1..790a6dd032 100644 --- a/crypto/openssl/crypto/x509v3/v3_crld.c +++ b/crypto/openssl/crypto/x509v3/v3_crld.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 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 @@ -63,45 +63,254 @@ #include #include -static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, - STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *extlist); -static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); - -const X509V3_EXT_METHOD v3_crld = { -NID_crl_distribution_points, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(CRL_DIST_POINTS), -0,0,0,0, -0,0, -(X509V3_EXT_I2V)i2v_crld, -(X509V3_EXT_V2I)v2i_crld, -0,0, -NULL +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent); + +const X509V3_EXT_METHOD v3_crld = + { + NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0,0,0,0, + 0,0, + 0, + v2i_crld, + i2r_crldp,0, + NULL + }; + +const X509V3_EXT_METHOD v3_freshest_crl = + { + NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0,0,0,0, + 0,0, + 0, + v2i_crld, + i2r_crldp,0, + NULL + }; + +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect) + { + STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(GENERAL_NAME) *gens; + if (*sect == '@') + gnsect = X509V3_get_section(ctx, sect + 1); + else + gnsect = X509V3_parse_list(sect); + if (!gnsect) + { + X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, + X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + if (*sect == '@') + X509V3_section_free(ctx, gnsect); + else + sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); + return gens; + } + +static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, + CONF_VALUE *cnf) + { + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + if (!strncmp(cnf->name, "fullname", 9)) + { + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) + goto err; + } + else if (!strcmp(cnf->name, "relativename")) + { + int ret; + STACK_OF(CONF_VALUE) *dnsect; + X509_NAME *nm; + nm = X509_NAME_new(); + if (!nm) + return -1; + dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) + { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_SECTION_NOT_FOUND); + return -1; + } + ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + X509V3_section_free(ctx, dnsect); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) + goto err; + /* Since its a name fragment can't have more than one + * RDNSequence + */ + if (sk_X509_NAME_ENTRY_value(rnm, + sk_X509_NAME_ENTRY_num(rnm) - 1)->set) + { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } + else + return 0; + + if (*pdp) + { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } + + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) + goto err; + if (fnm) + { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } + else + { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + + err: + if (fnm) + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + if (rnm) + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; + } + +static const BIT_STRING_BITNAME reason_flags[] = { +{0, "Unused", "unused"}, +{1, "Key Compromise", "keyCompromise"}, +{2, "CA Compromise", "CACompromise"}, +{3, "Affiliation Changed", "affiliationChanged"}, +{4, "Superseded", "superseded"}, +{5, "Cessation Of Operation", "cessationOfOperation"}, +{6, "Certificate Hold", "certificateHold"}, +{7, "Privilege Withdrawn", "privilegeWithdrawn"}, +{8, "AA Compromise", "AACompromise"}, +{-1, NULL, NULL} }; -static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, - STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *exts) -{ - DIST_POINT *point; +static int set_reasons(ASN1_BIT_STRING **preas, char *value) + { + STACK_OF(CONF_VALUE) *rsk = NULL; + const BIT_STRING_BITNAME *pbn; + const char *bnam; + int i, ret = 0; + rsk = X509V3_parse_list(value); + if (!rsk) + return 0; + if (*preas) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) + { + bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) + { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) + goto err; + } + for (pbn = reason_flags; pbn->lname; pbn++) + { + if (!strcmp(pbn->sname, bnam)) + { + if (!ASN1_BIT_STRING_set_bit(*preas, + pbn->bitnum, 1)) + goto err; + break; + } + } + if (!pbn->lname) + goto err; + } + ret = 1; + + err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; + } + +static int print_reasons(BIO *out, const char *rname, + ASN1_BIT_STRING *rflags, int indent) + { + int first = 1; + const BIT_STRING_BITNAME *pbn; + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) + { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) + { + if (first) + first = 0; + else + BIO_puts(out, ", "); + BIO_puts(out, pbn->lname); + } + } + if (first) + BIO_puts(out, "\n"); + else + BIO_puts(out, "\n"); + return 1; + } + +static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) + { int i; - for(i = 0; i < sk_DIST_POINT_num(crld); i++) { - point = sk_DIST_POINT_value(crld, i); - if(point->distpoint) { - if(point->distpoint->type == 0) - exts = i2v_GENERAL_NAMES(NULL, - point->distpoint->name.fullname, exts); - else X509V3_add_value("RelativeName","", &exts); + CONF_VALUE *cnf; + DIST_POINT *point = NULL; + point = DIST_POINT_new(); + if (!point) + goto err; + for(i = 0; i < sk_CONF_VALUE_num(nval); i++) + { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(cnf->name, "reasons")) + { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } + else if (!strcmp(cnf->name, "CRLissuer")) + { + point->CRLissuer = + gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) + goto err; + } } - if(point->reasons) - X509V3_add_value("reasons","", &exts); - if(point->CRLissuer) - X509V3_add_value("CRLissuer","", &exts); + + return point; + + + err: + if (point) + DIST_POINT_free(point); + return NULL; } - return exts; -} -static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) + { STACK_OF(DIST_POINT) *crld = NULL; GENERAL_NAMES *gens = NULL; GENERAL_NAME *gen = NULL; @@ -111,19 +320,44 @@ static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { DIST_POINT *point; cnf = sk_CONF_VALUE_value(nval, i); - if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; - if(!(gens = GENERAL_NAMES_new())) goto merr; - if(!sk_GENERAL_NAME_push(gens, gen)) goto merr; - gen = NULL; - if(!(point = DIST_POINT_new())) goto merr; - if(!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - if(!(point->distpoint = DIST_POINT_NAME_new())) goto merr; - point->distpoint->name.fullname = gens; - point->distpoint->type = 0; - gens = NULL; + if (!cnf->value) + { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = crldp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (!point) + goto err; + if(!sk_DIST_POINT_push(crld, point)) + { + DIST_POINT_free(point); + goto merr; + } + } + else + { + if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if(!(gens = GENERAL_NAMES_new())) + goto merr; + if(!sk_GENERAL_NAME_push(gens, gen)) + goto merr; + gen = NULL; + if(!(point = DIST_POINT_new())) + goto merr; + if(!sk_DIST_POINT_push(crld, point)) + { + DIST_POINT_free(point); + goto merr; + } + if(!(point->distpoint = DIST_POINT_NAME_new())) + goto merr; + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } } return crld; @@ -139,11 +373,31 @@ static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, IMPLEMENT_STACK_OF(DIST_POINT) IMPLEMENT_ASN1_SET_OF(DIST_POINT) +static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) + { + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + + switch(operation) + { + case ASN1_OP_NEW_POST: + dpn->dpname = NULL; + break; + + case ASN1_OP_FREE_POST: + if (dpn->dpname) + X509_NAME_free(dpn->dpname); + break; + } + return 1; + } + -ASN1_CHOICE(DIST_POINT_NAME) = { +ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) -} ASN1_CHOICE_END(DIST_POINT_NAME) +} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) + IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) @@ -160,3 +414,203 @@ ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) + +ASN1_SEQUENCE(ISSUING_DIST_POINT) = { + ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), + ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) +} ASN1_SEQUENCE_END(ISSUING_DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent); +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_idp = + { + NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ISSUING_DIST_POINT), + 0,0,0,0, + 0,0, + 0, + v2i_idp, + i2r_idp,0, + NULL + }; + +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) + { + ISSUING_DIST_POINT *idp = NULL; + CONF_VALUE *cnf; + char *name, *val; + int i, ret; + idp = ISSUING_DIST_POINT_new(); + if (!idp) + goto merr; + for(i = 0; i < sk_CONF_VALUE_num(nval); i++) + { + cnf = sk_CONF_VALUE_value(nval, i); + name = cnf->name; + val = cnf->value; + ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(name, "onlyuser")) + { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) + goto err; + } + else if (!strcmp(name, "onlyCA")) + { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) + goto err; + } + else if (!strcmp(name, "onlyAA")) + { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) + goto err; + } + else if (!strcmp(name, "indirectCRL")) + { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) + goto err; + } + else if (!strcmp(name, "onlysomereasons")) + { + if (!set_reasons(&idp->onlysomereasons, val)) + goto err; + } + else + { + X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + + merr: + X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE); + err: + ISSUING_DIST_POINT_free(idp); + return NULL; + } + +static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) + { + int i; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; + } + +static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) + { + if (dpn->type == 0) + { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } + else + { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", + indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; + } + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent) + { + ISSUING_DIST_POINT *idp = pidp; + if (idp->distpoint) + print_distpoint(out, idp->distpoint, indent); + if (idp->onlyuser > 0) + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + if (idp->onlyCA > 0) + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + if (idp->indirectCRL > 0) + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + if (idp->onlysomereasons) + print_reasons(out, "Only Some Reasons", + idp->onlysomereasons, indent); + if (idp->onlyattr > 0) + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) + && (idp->indirectCRL <= 0) && !idp->onlysomereasons + && (idp->onlyattr <= 0)) + BIO_printf(out, "%*s\n", indent, ""); + + return 1; + } + +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent) + { + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + int i; + for(i = 0; i < sk_DIST_POINT_num(crld); i++) + { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if(point->distpoint) + print_distpoint(out, point->distpoint, indent); + if(point->reasons) + print_reasons(out, "Reasons", point->reasons, + indent); + if(point->CRLissuer) + { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; + } + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) + { + int i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + if (!dpn || (dpn->type != 1)) + return 1; + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) + return 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) + { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) + { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + /* generate cached encoding of name */ + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) + { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; + } diff --git a/crypto/openssl/crypto/x509v3/v3_enum.c b/crypto/openssl/crypto/x509v3/v3_enum.c index 36576eaa4d..c0575e368d 100644 --- a/crypto/openssl/crypto/x509v3/v3_enum.c +++ b/crypto/openssl/crypto/x509v3/v3_enum.c @@ -61,14 +61,17 @@ #include static ENUMERATED_NAMES crl_reasons[] = { -{0, "Unspecified", "unspecified"}, -{1, "Key Compromise", "keyCompromise"}, -{2, "CA Compromise", "CACompromise"}, -{3, "Affiliation Changed", "affiliationChanged"}, -{4, "Superseded", "superseded"}, -{5, "Cessation Of Operation", "cessationOfOperation"}, -{6, "Certificate Hold", "certificateHold"}, -{8, "Remove From CRL", "removeFromCRL"}, +{CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, +{CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, +{CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, +{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"}, +{CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, +{CRL_REASON_CESSATION_OF_OPERATION, + "Cessation Of Operation", "cessationOfOperation"}, +{CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, +{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, +{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"}, +{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, {-1, NULL, NULL} }; diff --git a/crypto/openssl/crypto/x509v3/v3_extku.c b/crypto/openssl/crypto/x509v3/v3_extku.c index c0d14500ed..1c66532757 100644 --- a/crypto/openssl/crypto/x509v3/v3_extku.c +++ b/crypto/openssl/crypto/x509v3/v3_extku.c @@ -63,9 +63,10 @@ #include #include -static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist); const X509V3_EXT_METHOD v3_ext_ku = { @@ -97,8 +98,9 @@ ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, - void *a, STACK_OF(CONF_VALUE) *ext_list) +static STACK_OF(CONF_VALUE) * + i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *ext_list) { EXTENDED_KEY_USAGE *eku = a; int i; @@ -112,8 +114,8 @@ static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, return ext_list; } -static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { EXTENDED_KEY_USAGE *extku; char *extval; diff --git a/crypto/openssl/crypto/x509v3/v3_genn.c b/crypto/openssl/crypto/x509v3/v3_genn.c index 84b4b1c881..b628357301 100644 --- a/crypto/openssl/crypto/x509v3/v3_genn.c +++ b/crypto/openssl/crypto/x509v3/v3_genn.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 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 @@ -99,3 +99,154 @@ ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) + +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) + { + return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME, + (d2i_of_void *) d2i_GENERAL_NAME, + (char *) a); + } + +/* Returns 0 if they are equal, != 0 otherwise. */ +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) + { + int result = -1; + + if (!a || !b || a->type != b->type) return -1; + switch(a->type) + { + case GEN_X400: + case GEN_EDIPARTY: + result = ASN1_TYPE_cmp(a->d.other, b->d.other); + break; + + case GEN_OTHERNAME: + result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); + break; + + case GEN_DIRNAME: + result = X509_NAME_cmp(a->d.dirn, b->d.dirn); + break; + + case GEN_IPADD: + result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); + break; + + case GEN_RID: + result = OBJ_cmp(a->d.rid, b->d.rid); + break; + } + return result; + } + +/* Returns 0 if they are equal, != 0 otherwise. */ +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) + { + int result = -1; + + if (!a || !b) return -1; + /* Check their type first. */ + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) + return result; + /* Check the value. */ + result = ASN1_TYPE_cmp(a->value, b->value); + return result; + } + +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) + { + switch(type) + { + case GEN_X400: + case GEN_EDIPARTY: + a->d.other = value; + break; + + case GEN_OTHERNAME: + a->d.otherName = value; + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + a->d.ia5 = value; + break; + + case GEN_DIRNAME: + a->d.dirn = value; + break; + + case GEN_IPADD: + a->d.ip = value; + break; + + case GEN_RID: + a->d.rid = value; + break; + } + a->type = type; + } + +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) + { + if (ptype) + *ptype = a->type; + switch(a->type) + { + case GEN_X400: + case GEN_EDIPARTY: + return a->d.other; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; + + default: + return NULL; + } + } + +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value) + { + OTHERNAME *oth; + oth = OTHERNAME_new(); + if (!oth) + return 0; + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; + } + +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue) + { + if (gen->type != GEN_OTHERNAME) + return 0; + if (poid) + *poid = gen->d.otherName->type_id; + if (pvalue) + *pvalue = gen->d.otherName->value; + return 1; + } + diff --git a/crypto/openssl/crypto/x509v3/v3_lib.c b/crypto/openssl/crypto/x509v3/v3_lib.c index df3a48f43e..0f1e1d4422 100644 --- a/crypto/openssl/crypto/x509v3/v3_lib.c +++ b/crypto/openssl/crypto/x509v3/v3_lib.c @@ -84,20 +84,24 @@ int X509V3_EXT_add(X509V3_EXT_METHOD *ext) } static int ext_cmp(const X509V3_EXT_METHOD * const *a, - const X509V3_EXT_METHOD * const *b) + const X509V3_EXT_METHOD * const *b) { return ((*a)->ext_nid - (*b)->ext_nid); } -X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) +DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, const X509V3_EXT_METHOD *, + ext); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); + +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) { - X509V3_EXT_METHOD tmp, *t = &tmp, **ret; + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, * const *ret; int idx; if(nid < 0) return NULL; tmp.ext_nid = nid; - ret = (X509V3_EXT_METHOD **) OBJ_bsearch((char *)&t, - (char *)standard_exts, STANDARD_EXTENSION_COUNT, - sizeof(X509V3_EXT_METHOD *), (int (*)(const void *, const void *))ext_cmp); + ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); if(ret) return *ret; if(!ext_list) return NULL; idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); @@ -105,7 +109,7 @@ X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) return sk_X509V3_EXT_METHOD_value(ext_list, idx); } -X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) { int nid; if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL; @@ -122,7 +126,9 @@ int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) int X509V3_EXT_add_alias(int nid_to, int nid_from) { - X509V3_EXT_METHOD *ext, *tmpext; + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + if(!(ext = X509V3_EXT_get_nid(nid_from))) { X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND); return 0; @@ -161,7 +167,7 @@ int X509V3_add_standard_extensions(void) void *X509V3_EXT_d2i(X509_EXTENSION *ext) { - X509V3_EXT_METHOD *method; + const X509V3_EXT_METHOD *method; const unsigned char *p; if(!(method = X509V3_EXT_get(ext))) return NULL; diff --git a/crypto/openssl/crypto/x509v3/v3_ncons.c b/crypto/openssl/crypto/x509v3/v3_ncons.c index 4e706be3e1..689df46acd 100644 --- a/crypto/openssl/crypto/x509v3/v3_ncons.c +++ b/crypto/openssl/crypto/x509v3/v3_ncons.c @@ -63,15 +63,22 @@ #include #include -static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind); -static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, - BIO *bp, int ind, char *name); +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, + BIO *bp, int ind, char *name); static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); +static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); + const X509V3_EXT_METHOD v3_name_constraints = { NID_name_constraints, 0, ASN1_ITEM_ref(NAME_CONSTRAINTS), @@ -99,8 +106,8 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) -static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { int i; CONF_VALUE tval, *val; @@ -155,8 +162,8 @@ static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, -static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, - void *a, BIO *bp, int ind) +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind) { NAME_CONSTRAINTS *ncons = a; do_i2r_name_constraints(method, ncons->permittedSubtrees, @@ -166,9 +173,9 @@ static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, return 1; } -static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, - BIO *bp, int ind, char *name) +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, + BIO *bp, int ind, char *name) { GENERAL_SUBTREE *tree; int i; @@ -218,3 +225,282 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) return 1; } +/* Check a certificate conforms to a specified set of constraints. + * Return values: + * X509_V_OK: All constraints obeyed. + * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. + * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. + * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. + * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name + + */ + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) + { + int r, i; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + if (X509_NAME_entry_count(nm) > 0) + { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + + gntmp.type = GEN_EMAIL; + + + /* Process any email address attributes in subject name */ + + for (i = -1;;) + { + X509_NAME_ENTRY *ne; + i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, + i); + if (i == -1) + break; + ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + } + + } + + for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) + { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); + r = nc_match(gen, nc); + if (r != X509_V_OK) + return r; + } + + return X509_V_OK; + + } + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) + { + GENERAL_SUBTREE *sub; + int i, r, match = 0; + + /* Permitted subtrees: if any subtrees exist of matching the type + * at least one subtree must match. + */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) + { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + /* If we already have a match don't bother trying any more */ + if (match == 2) + continue; + if (match == 0) + match = 1; + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + match = 2; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + } + + if (match == 1) + return X509_V_ERR_PERMITTED_VIOLATION; + + /* Excluded subtrees: must not match any of these */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) + { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + return X509_V_ERR_EXCLUDED_VIOLATION; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + + } + + return X509_V_OK; + + } + +static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) + { + switch(base->type) + { + case GEN_DIRNAME: + return nc_dn(gen->d.directoryName, base->d.directoryName); + + case GEN_DNS: + return nc_dns(gen->d.dNSName, base->d.dNSName); + + case GEN_EMAIL: + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + + case GEN_URI: + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } + + } + +/* directoryName name constraint matching. + * The canonical encoding of X509_NAME makes this comparison easy. It is + * matched if the subtree is a subset of the name. + */ + +static int nc_dn(X509_NAME *nm, X509_NAME *base) + { + /* Ensure canonical encodings are up to date. */ + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->modified && i2d_X509_NAME(base, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->canon_enclen > nm->canon_enclen) + return X509_V_ERR_PERMITTED_VIOLATION; + if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) + return X509_V_ERR_PERMITTED_VIOLATION; + return X509_V_OK; + } + +static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) + { + char *baseptr = (char *)base->data; + char *dnsptr = (char *)dns->data; + /* Empty matches everything */ + if (!*baseptr) + return X509_V_OK; + /* Otherwise can add zero or more components on the left so + * compare RHS and if dns is longer and expect '.' as preceding + * character. + */ + if (dns->length > base->length) + { + dnsptr += dns->length - base->length; + if (dnsptr[-1] != '.') + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if (strcasecmp(baseptr, dnsptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + + } + +static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) + { + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; + + const char *baseat = strchr(baseptr, '@'); + const char *emlat = strchr(emlptr, '@'); + if (!emlat) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + /* Special case: inital '.' is RHS match */ + if (!baseat && (*baseptr == '.')) + { + if (eml->length > base->length) + { + emlptr += eml->length - base->length; + if (!strcasecmp(baseptr, emlptr)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* If we have anything before '@' match local part */ + + if (baseat) + { + if (baseat != baseptr) + { + if ((baseat - baseptr) != (emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + /* Case sensitive match of local part */ + if (strncmp(baseptr, emlptr, emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + } + /* Position base after '@' */ + baseptr = baseat + 1; + } + emlptr = emlat + 1; + /* Just have hostname left to match: case insensitive */ + if (strcasecmp(baseptr, emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + + } + +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) + { + const char *baseptr = (char *)base->data; + const char *hostptr = (char *)uri->data; + const char *p = strchr(hostptr, ':'); + int hostlen; + /* Check for foo:// and skip past it */ + if (!p || (p[1] != '/') || (p[2] != '/')) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + hostptr = p + 3; + + /* Determine length of hostname part of URI */ + + /* Look for a port indicator as end of hostname first */ + + p = strchr(hostptr, ':'); + /* Otherwise look for trailing slash */ + if (!p) + p = strchr(hostptr, '/'); + + if (!p) + hostlen = strlen(hostptr); + else + hostlen = p - hostptr; + + if (hostlen == 0) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* Special case: inital '.' is RHS match */ + if (*baseptr == '.') + { + if (hostlen > base->length) + { + p = hostptr + hostlen - base->length; + if (!strncasecmp(p, baseptr, base->length)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + + } diff --git a/crypto/openssl/crypto/x509v3/v3_ocsp.c b/crypto/openssl/crypto/x509v3/v3_ocsp.c index 5c19cf4130..0c165af314 100644 --- a/crypto/openssl/crypto/x509v3/v3_ocsp.c +++ b/crypto/openssl/crypto/x509v3/v3_ocsp.c @@ -68,19 +68,26 @@ /* OCSP extensions and a couple of CRL entry extensions */ -static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); -static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); -static int i2r_object(X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent); +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, + int indent); static void *ocsp_nonce_new(void); static int i2d_ocsp_nonce(void *a, unsigned char **pp); static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); static void ocsp_nonce_free(void *a); -static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); -static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent); -static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str); -static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind); +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, + void *nocheck, BIO *out, int indent); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str); +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind); const X509V3_EXT_METHOD v3_ocsp_crlid = { NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), @@ -148,7 +155,8 @@ const X509V3_EXT_METHOD v3_ocsp_serviceloc = { NULL }; -static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, + int ind) { OCSP_CRLID *a = in; if (a->crlUrl) @@ -174,7 +182,8 @@ static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) return 0; } -static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, int ind) +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, + BIO *bp, int ind) { if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0; if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0; @@ -182,7 +191,8 @@ static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, in } -static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) +static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, + int ind) { if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0; if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0; @@ -232,7 +242,8 @@ static void ocsp_nonce_free(void *a) M_ASN1_OCTET_STRING_free(a); } -static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent) +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent) { if(BIO_printf(out, "%*s", indent, "") <= 0) return 0; if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0; @@ -241,17 +252,20 @@ static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int /* Nocheck is just a single NULL. Don't print anything and always set it */ -static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent) +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, + BIO *out, int indent) { return 1; } -static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str) { return ASN1_NULL_new(); } -static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind) { int i; OCSP_SERVICELOC *a = in; diff --git a/crypto/openssl/crypto/x509v3/v3_pci.c b/crypto/openssl/crypto/x509v3/v3_pci.c index 601211f416..0dcfa004fe 100644 --- a/crypto/openssl/crypto/x509v3/v3_pci.c +++ b/crypto/openssl/crypto/x509v3/v3_pci.c @@ -82,7 +82,7 @@ static int process_pci_value(CONF_VALUE *val, { if (*language) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); + X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); X509V3_conf_err(val); return 0; } @@ -97,7 +97,7 @@ static int process_pci_value(CONF_VALUE *val, { if (*pathlen) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); + X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); X509V3_conf_err(val); return 0; } @@ -128,7 +128,12 @@ static int process_pci_value(CONF_VALUE *val, unsigned char *tmp_data2 = string_to_hex(val->value + 4, &val_len); - if (!tmp_data2) goto err; + if (!tmp_data2) + { + X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT); + X509V3_conf_err(val); + goto err; + } tmp_data = OPENSSL_realloc((*policy)->data, (*policy)->length + val_len + 1); @@ -140,6 +145,17 @@ static int process_pci_value(CONF_VALUE *val, (*policy)->length += val_len; (*policy)->data[(*policy)->length] = '\0'; } + else + { + OPENSSL_free(tmp_data2); + /* realloc failure implies the original data space is b0rked too! */ + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(tmp_data2); } else if (strncmp(val->value, "file:", 5) == 0) { @@ -169,6 +185,7 @@ static int process_pci_value(CONF_VALUE *val, (*policy)->length += n; (*policy)->data[(*policy)->length] = '\0'; } + BIO_free_all(b); if (n < 0) { @@ -190,6 +207,15 @@ static int process_pci_value(CONF_VALUE *val, (*policy)->length += val_len; (*policy)->data[(*policy)->length] = '\0'; } + else + { + /* realloc failure implies the original data space is b0rked too! */ + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } } else { diff --git a/crypto/openssl/crypto/x509v3/v3_pcons.c b/crypto/openssl/crypto/x509v3/v3_pcons.c index 86c0ff70e6..30ca652351 100644 --- a/crypto/openssl/crypto/x509v3/v3_pcons.c +++ b/crypto/openssl/crypto/x509v3/v3_pcons.c @@ -64,10 +64,12 @@ #include #include -static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, - void *bcons, STACK_OF(CONF_VALUE) *extlist); -static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); +static STACK_OF(CONF_VALUE) * +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons, + STACK_OF(CONF_VALUE) *extlist); +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_policy_constraints = { NID_policy_constraints, 0, @@ -88,8 +90,9 @@ ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) -static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, - void *a, STACK_OF(CONF_VALUE) *extlist) +static STACK_OF(CONF_VALUE) * +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *extlist) { POLICY_CONSTRAINTS *pcons = a; X509V3_add_value_int("Require Explicit Policy", @@ -99,8 +102,9 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, return extlist; } -static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) { POLICY_CONSTRAINTS *pcons=NULL; CONF_VALUE *val; diff --git a/crypto/openssl/crypto/x509v3/v3_pmaps.c b/crypto/openssl/crypto/x509v3/v3_pmaps.c index da03bbc35d..865bcd3980 100644 --- a/crypto/openssl/crypto/x509v3/v3_pmaps.c +++ b/crypto/openssl/crypto/x509v3/v3_pmaps.c @@ -63,10 +63,11 @@ #include #include -static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, - void *pmps, STACK_OF(CONF_VALUE) *extlist); +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) * +i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps, + STACK_OF(CONF_VALUE) *extlist); const X509V3_EXT_METHOD v3_policy_mappings = { NID_policy_mappings, 0, @@ -92,8 +93,9 @@ ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, - void *a, STACK_OF(CONF_VALUE) *ext_list) +static STACK_OF(CONF_VALUE) * +i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *ext_list) { POLICY_MAPPINGS *pmaps = a; POLICY_MAPPING *pmap; @@ -109,8 +111,8 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, return ext_list; } -static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { POLICY_MAPPINGS *pmaps; POLICY_MAPPING *pmap; diff --git a/crypto/openssl/crypto/x509v3/v3_prn.c b/crypto/openssl/crypto/x509v3/v3_prn.c index c1bb17f105..3146218708 100644 --- a/crypto/openssl/crypto/x509v3/v3_prn.c +++ b/crypto/openssl/crypto/x509v3/v3_prn.c @@ -110,7 +110,7 @@ int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int inde void *ext_str = NULL; char *value = NULL; const unsigned char *p; - X509V3_EXT_METHOD *method; + const X509V3_EXT_METHOD *method; STACK_OF(CONF_VALUE) *nval = NULL; int ok = 1; diff --git a/crypto/openssl/crypto/x509v3/v3_purp.c b/crypto/openssl/crypto/x509v3/v3_purp.c index e18751e01c..181bd34979 100644 --- a/crypto/openssl/crypto/x509v3/v3_purp.c +++ b/crypto/openssl/crypto/x509v3/v3_purp.c @@ -71,6 +71,7 @@ static int purpose_smime(const X509 *x, int ca); static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca); static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca); static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca); +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca); static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); @@ -87,6 +88,7 @@ static X509_PURPOSE xstandard[] = { {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL}, {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL}, }; #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) @@ -265,11 +267,14 @@ int X509_PURPOSE_get_trust(X509_PURPOSE *xp) return xp->trust; } -static int nid_cmp(int *a, int *b) +static int nid_cmp(const int *a, const int *b) { return *a - *b; } +DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid); + int X509_supported_extension(X509_EXTENSION *ex) { /* This table is a list of the NIDs of supported extensions: @@ -280,7 +285,7 @@ int X509_supported_extension(X509_EXTENSION *ex) * searched using bsearch. */ - static int supported_nids[] = { + static const int supported_nids[] = { NID_netscape_cert_type, /* 71 */ NID_key_usage, /* 83 */ NID_subject_alt_name, /* 85 */ @@ -292,24 +297,62 @@ int X509_supported_extension(X509_EXTENSION *ex) NID_sbgp_autonomousSysNum, /* 291 */ #endif NID_policy_constraints, /* 401 */ - NID_proxyCertInfo, /* 661 */ + NID_proxyCertInfo, /* 663 */ + NID_name_constraints, /* 666 */ + NID_policy_mappings, /* 747 */ NID_inhibit_any_policy /* 748 */ }; - int ex_nid; - - ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); if (ex_nid == NID_undef) return 0; - if (OBJ_bsearch((char *)&ex_nid, (char *)supported_nids, - sizeof(supported_nids)/sizeof(int), sizeof(int), - (int (*)(const void *, const void *))nid_cmp)) + if (OBJ_bsearch_nid(&ex_nid, supported_nids, + sizeof(supported_nids)/sizeof(int))) return 1; return 0; } - + +static void setup_dp(X509 *x, DIST_POINT *dp) + { + X509_NAME *iname = NULL; + int i; + if (dp->reasons) + { + if (dp->reasons->length > 0) + dp->dp_reasons = dp->reasons->data[0]; + if (dp->reasons->length > 1) + dp->dp_reasons |= (dp->reasons->data[1] << 8); + dp->dp_reasons &= CRLDP_ALL_REASONS; + } + else + dp->dp_reasons = CRLDP_ALL_REASONS; + if (!dp->distpoint || (dp->distpoint->type != 1)) + return; + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) + { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) + { + iname = gen->d.directoryName; + break; + } + } + if (!iname) + iname = X509_get_issuer_name(x); + + DIST_POINT_set_dpname(dp->distpoint, iname); + + } + +static void setup_crldp(X509 *x) + { + int i; + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) + setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); + } static void x509v3_cache_extensions(X509 *x) { @@ -417,16 +460,25 @@ static void x509v3_cache_extensions(X509 *x) } x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); + if (!x->nc && (i != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + #ifndef OPENSSL_NO_RFC3779 - x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); - x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, - NULL, NULL); + x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); + x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, + NULL, NULL); #endif for (i = 0; i < X509_get_ext_count(x); i++) { ex = X509_get_ext(x, i); if (!X509_EXTENSION_get_critical(ex)) continue; + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) + == NID_freshest_crl) + x->ex_flags |= EXFLAG_FRESHEST; if (!X509_supported_extension(ex)) { x->ex_flags |= EXFLAG_CRITICAL; @@ -594,6 +646,41 @@ static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) return 1; } +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int i_ext; + + /* If ca is true we must return if this is a valid CA certificate. */ + if (ca) return check_ca(x); + + /* + * Check the optional key usage field: + * if Key Usage is present, it must be one of digitalSignature + * and/or nonRepudiation (other values are not consistent and shall + * be rejected). + */ + if ((x->ex_flags & EXFLAG_KUSAGE) + && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) + return 0; + + /* Only time stamp key usage is permitted and it's required. */ + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + return 0; + + /* Extended Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0); + if (i_ext >= 0) + { + X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) + return 0; + } + + return 1; +} + static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) { return 1; @@ -618,39 +705,14 @@ int X509_check_issued(X509 *issuer, X509 *subject) return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; x509v3_cache_extensions(issuer); x509v3_cache_extensions(subject); - if(subject->akid) { - /* Check key ids (if present) */ - if(subject->akid->keyid && issuer->skid && - ASN1_OCTET_STRING_cmp(subject->akid->keyid, issuer->skid) ) - return X509_V_ERR_AKID_SKID_MISMATCH; - /* Check serial number */ - if(subject->akid->serial && - ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), - subject->akid->serial)) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; - /* Check issuer name */ - if(subject->akid->issuer) { - /* Ugh, for some peculiar reason AKID includes - * SEQUENCE OF GeneralName. So look for a DirName. - * There may be more than one but we only take any - * notice of the first. - */ - GENERAL_NAMES *gens; - GENERAL_NAME *gen; - X509_NAME *nm = NULL; - int i; - gens = subject->akid->issuer; - for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - if(gen->type == GEN_DIRNAME) { - nm = gen->d.dirn; - break; - } - } - if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + + if(subject->akid) + { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; } - } + if(subject->ex_flags & EXFLAG_PROXY) { if(ku_reject(issuer, KU_DIGITAL_SIGNATURE)) @@ -661,3 +723,45 @@ int X509_check_issued(X509 *issuer, X509 *subject) return X509_V_OK; } +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) + { + + if(!akid) + return X509_V_OK; + + /* Check key ids (if present) */ + if(akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) ) + return X509_V_ERR_AKID_SKID_MISMATCH; + /* Check serial number */ + if(akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + /* Check issuer name */ + if(akid->issuer) + { + /* Ugh, for some peculiar reason AKID includes + * SEQUENCE OF GeneralName. So look for a DirName. + * There may be more than one but we only take any + * notice of the first. + */ + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + int i; + gens = akid->issuer; + for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + gen = sk_GENERAL_NAME_value(gens, i); + if(gen->type == GEN_DIRNAME) + { + nm = gen->d.dirn; + break; + } + } + if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + return X509_V_OK; + } + diff --git a/crypto/openssl/crypto/x509v3/v3_utl.c b/crypto/openssl/crypto/x509v3/v3_utl.c index 7a45216c00..e030234540 100644 --- a/crypto/openssl/crypto/x509v3/v3_utl.c +++ b/crypto/openssl/crypto/x509v3/v3_utl.c @@ -67,9 +67,9 @@ static char *strip_spaces(char *name); static int sk_strcmp(const char * const *a, const char * const *b); -static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens); -static void str_free(void *str); -static int append_ia5(STACK **sk, ASN1_IA5STRING *email); +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens); +static void str_free(OPENSSL_STRING str); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); static int ipv4_from_asc(unsigned char *v4, const char *in); static int ipv6_from_asc(unsigned char *v6, const char *in); @@ -360,10 +360,10 @@ static char *strip_spaces(char *name) * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines) */ -char *hex_to_string(unsigned char *buffer, long len) +char *hex_to_string(const unsigned char *buffer, long len) { char *tmp, *q; - unsigned char *p; + const unsigned char *p; int i; const static char hexdig[] = "0123456789ABCDEF"; if(!buffer || !len) return NULL; @@ -389,7 +389,7 @@ char *hex_to_string(unsigned char *buffer, long len) * a buffer */ -unsigned char *string_to_hex(char *str, long *len) +unsigned char *string_to_hex(const char *str, long *len) { unsigned char *hexbuf, *q; unsigned char ch, cl, *p; @@ -463,21 +463,23 @@ static int sk_strcmp(const char * const *a, const char * const *b) return strcmp(*a, *b); } -STACK *X509_get1_email(X509 *x) +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) { GENERAL_NAMES *gens; - STACK *ret; + STACK_OF(OPENSSL_STRING) *ret; + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); ret = get_email(X509_get_subject_name(x), gens); sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); return ret; } -STACK *X509_get1_ocsp(X509 *x) +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) { AUTHORITY_INFO_ACCESS *info; - STACK *ret = NULL; + STACK_OF(OPENSSL_STRING) *ret = NULL; int i; + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); if (!info) return NULL; @@ -497,11 +499,12 @@ STACK *X509_get1_ocsp(X509 *x) return ret; } -STACK *X509_REQ_get1_email(X509_REQ *x) +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) { GENERAL_NAMES *gens; STACK_OF(X509_EXTENSION) *exts; - STACK *ret; + STACK_OF(OPENSSL_STRING) *ret; + exts = X509_REQ_get_extensions(x); gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); ret = get_email(X509_REQ_get_subject_name(x), gens); @@ -511,9 +514,9 @@ STACK *X509_REQ_get1_email(X509_REQ *x) } -static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens) +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens) { - STACK *ret = NULL; + STACK_OF(OPENSSL_STRING) *ret = NULL; X509_NAME_ENTRY *ne; ASN1_IA5STRING *email; GENERAL_NAME *gen; @@ -536,23 +539,23 @@ static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens) return ret; } -static void str_free(void *str) +static void str_free(OPENSSL_STRING str) { OPENSSL_free(str); } -static int append_ia5(STACK **sk, ASN1_IA5STRING *email) +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) { char *emtmp; /* First some sanity checks */ if(email->type != V_ASN1_IA5STRING) return 1; if(!email->data || !email->length) return 1; - if(!*sk) *sk = sk_new(sk_strcmp); + if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp); if(!*sk) return 0; /* Don't add duplicates */ - if(sk_find(*sk, (char *)email->data) != -1) return 1; + if(sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) return 1; emtmp = BUF_strdup((char *)email->data); - if(!emtmp || !sk_push(*sk, emtmp)) { + if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { X509_email_free(*sk); *sk = NULL; return 0; @@ -560,9 +563,9 @@ static int append_ia5(STACK **sk, ASN1_IA5STRING *email) return 1; } -void X509_email_free(STACK *sk) +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) { - sk_pop_free(sk, str_free); + sk_OPENSSL_STRING_pop_free(sk, str_free); } /* Convert IP addresses both IPv4 and IPv6 into an diff --git a/crypto/openssl/crypto/x509v3/v3err.c b/crypto/openssl/crypto/x509v3/v3err.c index d538ad8b80..f9f6f1f91f 100644 --- a/crypto/openssl/crypto/x509v3/v3err.c +++ b/crypto/openssl/crypto/x509v3/v3err.c @@ -1,6 +1,6 @@ /* crypto/x509v3/v3err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -70,6 +70,7 @@ static ERR_STRING_DATA X509V3_str_functs[]= { +{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "A2I_GENERAL_NAME"}, {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), "ASIDENTIFIERCHOICE_CANONIZE"}, {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), "ASIDENTIFIERCHOICE_IS_CANONICAL"}, {ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, @@ -79,6 +80,7 @@ static ERR_STRING_DATA X509V3_str_functs[]= {ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"}, {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"}, {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, +{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"}, {ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"}, @@ -95,6 +97,7 @@ static ERR_STRING_DATA X509V3_str_functs[]= {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"}, +{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"}, {ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, @@ -110,6 +113,7 @@ static ERR_STRING_DATA X509V3_str_functs[]= {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"}, {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, +{ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"}, {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"}, {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"}, {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"}, @@ -141,6 +145,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) ,"bn dec2bn error"}, {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"}, {ERR_REASON(X509V3_R_DIRNAME_ERROR) ,"dirname error"}, +{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"}, {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) ,"duplicate zone id"}, {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"}, {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"}, @@ -154,6 +159,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"}, {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) ,"illegal hex digit"}, {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"}, +{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS),"invalid multiple rdns"}, {ERR_REASON(X509V3_R_INVALID_ASNUMBER) ,"invalid asnumber"}, {ERR_REASON(X509V3_R_INVALID_ASRANGE) ,"invalid asrange"}, {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"}, @@ -187,9 +193,9 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"}, {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"}, {ERR_REASON(X509V3_R_OTHERNAME_ERROR) ,"othername error"}, -{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED),"policy language alreadty defined"}, +{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),"policy language already defined"}, {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"}, -{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED),"policy path length alreadty defined"}, +{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),"policy path length already defined"}, {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"}, {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"}, {ERR_REASON(X509V3_R_SECTION_NOT_FOUND) ,"section not found"}, @@ -200,6 +206,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"}, {ERR_REASON(X509V3_R_UNKNOWN_OPTION) ,"unknown option"}, {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"}, +{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) ,"unsupported type"}, {ERR_REASON(X509V3_R_USER_TOO_LONG) ,"user too long"}, {0,NULL} }; diff --git a/crypto/openssl/crypto/x509v3/x509v3.h b/crypto/openssl/crypto/x509v3/x509v3.h index 9ef83da755..b308abe7cd 100644 --- a/crypto/openssl/crypto/x509v3/x509v3.h +++ b/crypto/openssl/crypto/x509v3/x509v3.h @@ -76,12 +76,19 @@ typedef void * (*X509V3_EXT_NEW)(void); typedef void (*X509V3_EXT_FREE)(void *); typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long); typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); -typedef STACK_OF(CONF_VALUE) * (*X509V3_EXT_I2V)(struct v3_ext_method *method, void *ext, STACK_OF(CONF_VALUE) *extlist); -typedef void * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values); -typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, void *ext); -typedef void * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str); -typedef int (*X509V3_EXT_I2R)(struct v3_ext_method *method, void *ext, BIO *out, int indent); -typedef void * (*X509V3_EXT_R2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext); +typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); /* V3 extension structure */ @@ -220,24 +227,41 @@ union { GENERAL_NAMES *fullname; STACK_OF(X509_NAME_ENTRY) *relativename; } name; +/* If relativename then this contains the full distribution point name */ +X509_NAME *dpname; } DIST_POINT_NAME; - -typedef struct DIST_POINT_st { +/* All existing reasons */ +#define CRLDP_ALL_REASONS 0x807f + +#define CRL_REASON_NONE -1 +#define CRL_REASON_UNSPECIFIED 0 +#define CRL_REASON_KEY_COMPROMISE 1 +#define CRL_REASON_CA_COMPROMISE 2 +#define CRL_REASON_AFFILIATION_CHANGED 3 +#define CRL_REASON_SUPERSEDED 4 +#define CRL_REASON_CESSATION_OF_OPERATION 5 +#define CRL_REASON_CERTIFICATE_HOLD 6 +#define CRL_REASON_REMOVE_FROM_CRL 8 +#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +#define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { DIST_POINT_NAME *distpoint; ASN1_BIT_STRING *reasons; GENERAL_NAMES *CRLissuer; -} DIST_POINT; +int dp_reasons; +}; typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; DECLARE_STACK_OF(DIST_POINT) DECLARE_ASN1_SET_OF(DIST_POINT) -typedef struct AUTHORITY_KEYID_st { +struct AUTHORITY_KEYID_st { ASN1_OCTET_STRING *keyid; GENERAL_NAMES *issuer; ASN1_INTEGER *serial; -} AUTHORITY_KEYID; +}; /* Strong extranet structures */ @@ -303,10 +327,10 @@ typedef struct GENERAL_SUBTREE_st { DECLARE_STACK_OF(GENERAL_SUBTREE) -typedef struct NAME_CONSTRAINTS_st { +struct NAME_CONSTRAINTS_st { STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; -} NAME_CONSTRAINTS; +}; typedef struct POLICY_CONSTRAINTS_st { ASN1_INTEGER *requireExplicitPolicy; @@ -329,6 +353,31 @@ typedef struct PROXY_CERT_INFO_EXTENSION_st DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) +struct ISSUING_DIST_POINT_st + { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; + }; + +/* Values in idp_flags field */ +/* IDP present */ +#define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +#define IDP_INVALID 0x2 +/* onlyuser true */ +#define IDP_ONLYUSER 0x4 +/* onlyCA true */ +#define IDP_ONLYCA 0x8 +/* onlyattr true */ +#define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +#define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +#define IDP_REASONS 0x40 #define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ ",name:", val->name, ",value:", val->value); @@ -373,6 +422,7 @@ DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) #define EXFLAG_PROXY 0x400 #define EXFLAG_INVALID_POLICY 0x800 +#define EXFLAG_FRESHEST 0x1000 #define KU_DIGITAL_SIGNATURE 0x0080 #define KU_NON_REPUDIATION 0x0040 @@ -424,9 +474,10 @@ typedef struct x509_purpose_st { #define X509_PURPOSE_CRL_SIGN 6 #define X509_PURPOSE_ANY 7 #define X509_PURPOSE_OCSP_HELPER 8 +#define X509_PURPOSE_TIMESTAMP_SIGN 9 #define X509_PURPOSE_MIN 1 -#define X509_PURPOSE_MAX 8 +#define X509_PURPOSE_MAX 9 /* Flags for X509V3_EXT_print() */ @@ -471,6 +522,9 @@ DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, @@ -486,11 +540,18 @@ DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); -GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); DECLARE_ASN1_FUNCTIONS(OTHERNAME) DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5); ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); @@ -507,6 +568,11 @@ DECLARE_ASN1_FUNCTIONS(NOTICEREF) DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) DECLARE_ASN1_FUNCTIONS(DIST_POINT) DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) @@ -524,11 +590,16 @@ DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + int gen_type, char *value, int is_nc); + #ifdef HEADER_CONF_H -GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf); -GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); void X509V3_conf_free(CONF_VALUE *val); X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value); @@ -538,18 +609,23 @@ int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert) int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); -X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value); -X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value); -int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert); -int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); -int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + int ext_nid, char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); int X509V3_add_value_bool_nf(char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); + STACK_OF(CONF_VALUE) **extlist); int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); -void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); #endif char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); @@ -576,8 +652,8 @@ int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); int X509V3_EXT_add_alias(int nid_to, int nid_from); void X509V3_EXT_cleanup(void); -X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); -X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); int X509V3_add_standard_extensions(void); STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); void *X509V3_EXT_d2i(X509_EXTENSION *ext); @@ -587,8 +663,8 @@ void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx); X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); -char *hex_to_string(unsigned char *buffer, long len); -unsigned char *string_to_hex(char *str, long *len); +char *hex_to_string(const unsigned char *buffer, long len); +unsigned char *string_to_hex(const char *str, long *len); int name_cmp(const char *name, const char *cmp); void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, @@ -603,6 +679,7 @@ int X509_check_purpose(X509 *x, int id, int ca); int X509_supported_extension(X509_EXTENSION *ex); int X509_PURPOSE_set(int *p, int purpose); int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); int X509_PURPOSE_get_count(void); X509_PURPOSE * X509_PURPOSE_get0(int idx); int X509_PURPOSE_get_by_sname(char *sname); @@ -616,10 +693,10 @@ int X509_PURPOSE_get_trust(X509_PURPOSE *xp); void X509_PURPOSE_cleanup(void); int X509_PURPOSE_get_id(X509_PURPOSE *); -STACK *X509_get1_email(X509 *x); -STACK *X509_REQ_get1_email(X509_REQ *x); -void X509_email_free(STACK *sk); -STACK *X509_get1_ocsp(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); @@ -628,6 +705,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, unsigned long chtype); void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DECLARE_STACK_OF(X509_POLICY_NODE) #ifndef OPENSSL_NO_RFC3779 @@ -787,8 +865,9 @@ void ERR_load_X509V3_strings(void); /* Error codes for the X509V3 functions. */ /* Function codes. */ -#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 156 -#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 157 +#define X509V3_F_A2I_GENERAL_NAME 164 +#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 #define X509V3_F_COPY_EMAIL 122 #define X509V3_F_COPY_ISSUER 123 #define X509V3_F_DO_DIRNAME 144 @@ -796,6 +875,7 @@ void ERR_load_X509V3_strings(void); #define X509V3_F_DO_EXT_I2D 135 #define X509V3_F_DO_EXT_NCONF 151 #define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 +#define X509V3_F_GNAMES_FROM_SECTNAME 156 #define X509V3_F_HEX_TO_STRING 111 #define X509V3_F_I2S_ASN1_ENUMERATED 121 #define X509V3_F_I2S_ASN1_IA5STRING 149 @@ -812,13 +892,14 @@ void ERR_load_X509V3_strings(void); #define X509V3_F_S2I_ASN1_OCTET_STRING 112 #define X509V3_F_S2I_ASN1_SKEY_ID 114 #define X509V3_F_S2I_SKEY_ID 115 +#define X509V3_F_SET_DIST_POINT_NAME 158 #define X509V3_F_STRING_TO_HEX 113 #define X509V3_F_SXNET_ADD_ID_ASC 125 #define X509V3_F_SXNET_ADD_ID_INTEGER 126 #define X509V3_F_SXNET_ADD_ID_ULONG 127 #define X509V3_F_SXNET_GET_ID_ASC 128 #define X509V3_F_SXNET_GET_ID_ULONG 129 -#define X509V3_F_V2I_ASIDENTIFIERS 158 +#define X509V3_F_V2I_ASIDENTIFIERS 163 #define X509V3_F_V2I_ASN1_BIT_STRING 101 #define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 #define X509V3_F_V2I_AUTHORITY_KEYID 119 @@ -827,6 +908,7 @@ void ERR_load_X509V3_strings(void); #define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 #define X509V3_F_V2I_GENERAL_NAMES 118 #define X509V3_F_V2I_GENERAL_NAME_EX 117 +#define X509V3_F_V2I_IDP 157 #define X509V3_F_V2I_IPADDRBLOCKS 159 #define X509V3_F_V2I_ISSUER_ALT 153 #define X509V3_F_V2I_NAME_CONSTRAINTS 147 @@ -855,6 +937,7 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_BN_DEC2BN_ERROR 100 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 #define X509V3_R_DIRNAME_ERROR 149 +#define X509V3_R_DISTPOINT_ALREADY_SET 160 #define X509V3_R_DUPLICATE_ZONE_ID 133 #define X509V3_R_ERROR_CONVERTING_ZONE 131 #define X509V3_R_ERROR_CREATING_EXTENSION 144 @@ -868,12 +951,13 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 #define X509V3_R_ILLEGAL_HEX_DIGIT 113 #define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 -#define X509V3_R_INVALID_ASNUMBER 160 -#define X509V3_R_INVALID_ASRANGE 161 +#define X509V3_R_INVALID_MULTIPLE_RDNS 161 +#define X509V3_R_INVALID_ASNUMBER 162 +#define X509V3_R_INVALID_ASRANGE 163 #define X509V3_R_INVALID_BOOLEAN_STRING 104 #define X509V3_R_INVALID_EXTENSION_STRING 105 -#define X509V3_R_INVALID_INHERITANCE 162 -#define X509V3_R_INVALID_IPADDRESS 163 +#define X509V3_R_INVALID_INHERITANCE 165 +#define X509V3_R_INVALID_IPADDRESS 166 #define X509V3_R_INVALID_NAME 106 #define X509V3_R_INVALID_NULL_ARGUMENT 107 #define X509V3_R_INVALID_NULL_NAME 108 @@ -901,9 +985,9 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_ODD_NUMBER_OF_DIGITS 112 #define X509V3_R_OPERATION_NOT_DEFINED 148 #define X509V3_R_OTHERNAME_ERROR 147 -#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED 155 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 #define X509V3_R_POLICY_PATH_LENGTH 156 -#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED 157 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 #define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 #define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 #define X509V3_R_SECTION_NOT_FOUND 150 @@ -914,6 +998,7 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_UNKNOWN_EXTENSION_NAME 130 #define X509V3_R_UNKNOWN_OPTION 120 #define X509V3_R_UNSUPPORTED_OPTION 117 +#define X509V3_R_UNSUPPORTED_TYPE 167 #define X509V3_R_USER_TOO_LONG 132 #ifdef __cplusplus diff --git a/crypto/openssl/doc/apps/asn1parse.pod b/crypto/openssl/doc/apps/asn1parse.pod index 542d969066..f7bb926211 100644 --- a/crypto/openssl/doc/apps/asn1parse.pod +++ b/crypto/openssl/doc/apps/asn1parse.pod @@ -72,11 +72,11 @@ option can be used multiple times to "drill down" into a nested structure. =item B<-genstr string>, B<-genconf file> generate encoded data based on B, B or both using -ASN1_generate_nconf() format. If B only is present then the string -is obtained from the default section using the name B. The encoded -data is passed through the ASN1 parser and printed out as though it came -from a file, the contents can thus be examined and written to a file -using the B option. +L format. If B only is +present then the string is obtained from the default section using the name +B. The encoded data is passed through the ASN1 parser and printed out as +though it came from a file, the contents can thus be examined and written to a +file using the B option. =back @@ -168,4 +168,8 @@ Example config file: There should be options to change the format of output lines. The output of some ASN.1 types is not well handled (if at all). +=head1 SEE ALSO + +L + =cut diff --git a/crypto/openssl/doc/apps/ca.pod b/crypto/openssl/doc/apps/ca.pod index 5618c2dc9d..9ff0cc3612 100644 --- a/crypto/openssl/doc/apps/ca.pod +++ b/crypto/openssl/doc/apps/ca.pod @@ -205,7 +205,9 @@ the section of the configuration file containing certificate extensions to be added when a certificate is issued (defaults to B unless the B<-extfile> option is used). If no extension section is present then, a V1 certificate is created. If the extension section -is present (even if it is empty), then a V3 certificate is created. +is present (even if it is empty), then a V3 certificate is created. See the:w +L manual page for details of the +extension section format. =item B<-extfile file> @@ -215,7 +217,7 @@ used). =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. @@ -299,7 +301,9 @@ include. If no CRL extension section is present then a V1 CRL is created, if the CRL extension section is present (even if it is empty) then a V2 CRL is created. The CRL extensions specified are CRL extensions and B CRL entry extensions. It should be noted -that some software (for example Netscape) can't handle V2 CRLs. +that some software (for example Netscape) can't handle V2 CRLs. See +L manual page for details of the +extension section format. =back @@ -666,6 +670,6 @@ then even if a certificate is issued with CA:TRUE it will not be valid. =head1 SEE ALSO L, L, L, L, -L +L, L =cut diff --git a/crypto/openssl/doc/apps/ciphers.pod b/crypto/openssl/doc/apps/ciphers.pod index 694e433ef3..f44aa00a2f 100644 --- a/crypto/openssl/doc/apps/ciphers.pod +++ b/crypto/openssl/doc/apps/ciphers.pod @@ -8,6 +8,7 @@ ciphers - SSL cipher display and cipher list tool. B B [B<-v>] +[B<-V>] [B<-ssl2>] [B<-ssl3>] [B<-tls1>] @@ -15,7 +16,7 @@ B B =head1 DESCRIPTION -The B command converts OpenSSL cipher lists into ordered +The B command converts textual OpenSSL cipher lists into ordered SSL cipher preference lists. It can be used as a test tool to determine the appropriate cipherlist. @@ -25,7 +26,7 @@ the appropriate cipherlist. =item B<-v> -verbose option. List ciphers with a complete description of +Verbose option. List ciphers with a complete description of protocol version (SSLv2 or SSLv3; the latter includes TLS), key exchange, authentication, encryption and mac algorithms used along with any key size restrictions and whether the algorithm is classed as an "export" cipher. @@ -33,6 +34,10 @@ Note that without the B<-v> option, ciphers may seem to appear twice in a cipher list; this is when similar ciphers are available for SSL v2 and for SSL v3/TLS v1. +=item B<-V> + +Like B<-V>, but include cipher suite codes in output (hex format). + =item B<-ssl3> only include SSL v3 ciphers. @@ -104,8 +109,8 @@ The following is a list of all permitted cipher strings and their meanings. =item B -the default cipher list. This is determined at compile time and is normally -B. This must be the first cipher string +the default cipher list. This is determined at compile time and, as of OpenSSL +1.0.0, is normally B. This must be the first cipher string specified. =item B @@ -116,7 +121,8 @@ not included by B (use B if necessary). =item B -all ciphers suites except the B ciphers which must be explicitly enabled. +all cipher suites except the B ciphers which must be explicitly enabled; +as of OpenSSL, the B cipher suites are reasonably ordered by default =item B @@ -245,6 +251,33 @@ cipher suites using MD5. cipher suites using SHA1. +=item B + +cipher suites using GOST R 34.10 (either 2001 or 94) for authenticaction +(needs an engine supporting GOST algorithms). + +=item B + +cipher suites using GOST R 34.10-2001 authentication. + +=item B + +cipher suites using GOST R 34.10-94 authentication (note that R 34.10-94 +standard has been expired so use GOST R 34.10-2001) + +=item B + +cipher suites, using VKO 34.10 key exchange, specified in the RFC 4357. + +=item B + +cipher suites, using HMAC based on GOST R 34.11-94. + +=item B + +cipher suites using GOST 28147-89 MAC B HMAC. + + =back =head1 CIPHER SUITE NAMES @@ -370,6 +403,16 @@ e.g. DES-CBC3-SHA. In these cases, RSA authentication is used. TLS_DH_anon_WITH_SEED_CBC_SHA ADH-SEED-SHA +=head2 GOST ciphersuites from draft-chudov-cryptopro-cptls, extending TLS v1.0 + +Note: these ciphers require an engine which including GOST cryptographic +algorithms, such as the B engine, included in the OpenSSL distribution. + + TLS_GOSTR341094_WITH_28147_CNT_IMIT GOST94-GOST89-GOST89 + TLS_GOSTR341001_WITH_28147_CNT_IMIT GOST2001-GOST89-GOST89 + TLS_GOSTR341094_WITH_NULL_GOSTR3411 GOST94-NULL-GOST94 + TLS_GOSTR341001_WITH_NULL_GOSTR3411 GOST2001-NULL-GOST94 + =head2 Additional Export 1024 and other cipher suites Note: these ciphers can also be used in SSL v3. @@ -428,7 +471,8 @@ L, L, L =head1 HISTORY -The B and B selection options were -added in version 0.9.7. +The B and B selection options +for cipherlist strings were added in OpenSSL 0.9.7. +The B<-V> option for the B command was added in OpenSSL 1.0.0. =cut diff --git a/crypto/openssl/doc/apps/cms.pod b/crypto/openssl/doc/apps/cms.pod new file mode 100644 index 0000000000..a09588a18d --- /dev/null +++ b/crypto/openssl/doc/apps/cms.pod @@ -0,0 +1,602 @@ +=pod + +=head1 NAME + +cms - CMS utility + +=head1 SYNOPSIS + +B B +[B<-encrypt>] +[B<-decrypt>] +[B<-sign>] +[B<-verify>] +[B<-cmsout>] +[B<-resign>] +[B<-data_create>] +[B<-data_out>] +[B<-digest_create>] +[B<-digest_verify>] +[B<-compress>] +[B<-uncompress>] +[B<-EncryptedData_encrypt>] +[B<-sign_receipt>] +[B<-verify_receipt receipt>] +[B<-in filename>] +[B<-inform SMIME|PEM|DER>] +[B<-rctform SMIME|PEM|DER>] +[B<-out filename>] +[B<-outform SMIME|PEM|DER>] +[B<-stream -indef -noindef>] +[B<-noindef>] +[B<-content filename>] +[B<-text>] +[B<-noout>] +[B<-print>] +[B<-CAfile file>] +[B<-CApath dir>] +[B<-md digest>] +[B<-[cipher]>] +[B<-nointern>] +[B<-no_signer_cert_verify>] +[B<-nocerts>] +[B<-noattr>] +[B<-nosmimecap>] +[B<-binary>] +[B<-nodetach>] +[B<-certfile file>] +[B<-certsout file>] +[B<-signer file>] +[B<-recip file>] +[B<-keyid>] +[B<-receipt_request_all -receipt_request_first>] +[B<-receipt_request_from emailaddress>] +[B<-receipt_request_to emailaddress>] +[B<-receipt_request_print>] +[B<-secretkey key>] +[B<-secretkeyid id>] +[B<-econtent_type type>] +[B<-inkey file>] +[B<-passin arg>] +[B<-rand file(s)>] +[B] +[B<-to addr>] +[B<-from addr>] +[B<-subject subj>] +[cert.pem]... + +=head1 DESCRIPTION + +The B command handles S/MIME v3.1 mail. It can encrypt, decrypt, sign and +verify, compress and uncompress S/MIME messages. + +=head1 COMMAND OPTIONS + +There are fourteen operation options that set the type of operation to be +performed. The meaning of the other options varies according to the operation +type. + +=over 4 + +=item B<-encrypt> + +encrypt mail for the given recipient certificates. Input file is the message +to be encrypted. The output file is the encrypted mail in MIME format. The +actual CMS type is EnvelopedData. + +=item B<-decrypt> + +decrypt mail using the supplied certificate and private key. Expects an +encrypted mail message in MIME format for the input file. The decrypted mail +is written to the output file. + +=item B<-sign> + +sign mail using the supplied certificate and private key. Input file is +the message to be signed. The signed message in MIME format is written +to the output file. + +=item B<-verify> + +verify signed mail. Expects a signed mail message on input and outputs +the signed data. Both clear text and opaque signing is supported. + +=item B<-cmsout> + +takes an input message and writes out a PEM encoded CMS structure. + +=item B<-resign> + +resign a message: take an existing message and one or more new signers. + +=item B<-data_create> + +Create a CMS B type. + +=item B<-data_out> + +B type and output the content. + +=item B<-digest_create> + +Create a CMS B type. + +=item B<-digest_verify> + +Verify a CMS B type and output the content. + +=item B<-compress> + +Create a CMS B type. OpenSSL must be compiled with B +support for this option to work, otherwise it will output an error. + +=item B<-uncompress> + +Uncompress a CMS B type and output the content. OpenSSL must be +compiled with B support for this option to work, otherwise it will +output an error. + +=item B<-EncryptedData_encrypt> + +Encrypt suppled content using supplied symmetric key and algorithm using a CMS +B type and output the content. + +=item B<-sign_receipt> + +Generate and output a signed receipt for the supplied message. The input +message B contain a signed receipt request. Functionality is otherwise +similar to the B<-sign> operation. + +=item B<-verify_receipt receipt> + +Verify a signed receipt in filename B. The input message B +contain the original receipt request. Functionality is otherwise similar +to the B<-verify> operation. + +=item B<-in filename> + +the input message to be encrypted or signed or the message to be decrypted +or verified. + +=item B<-inform SMIME|PEM|DER> + +this specifies the input format for the CMS structure. The default +is B which reads an S/MIME format message. B and B +format change this to expect PEM and DER format CMS structures +instead. This currently only affects the input format of the CMS +structure, if no CMS structure is being input (for example with +B<-encrypt> or B<-sign>) this option has no effect. + +=item B<-rctform SMIME|PEM|DER> + +specify the format for a signed receipt for use with the B<-receipt_verify> +operation. + +=item B<-out filename> + +the message text that has been decrypted or verified or the output MIME +format message that has been signed or verified. + +=item B<-outform SMIME|PEM|DER> + +this specifies the output format for the CMS structure. The default +is B which writes an S/MIME format message. B and B +format change this to write PEM and DER format CMS structures +instead. This currently only affects the output format of the CMS +structure, if no CMS structure is being output (for example with +B<-verify> or B<-decrypt>) this option has no effect. + +=item B<-stream -indef -noindef> + +the B<-stream> and B<-indef> options are equivalent and enable streaming I/O +for encoding operations. This permits single pass processing of data without +the need to hold the entire contents in memory, potentially supporting very +large files. Streaming is automatically set for S/MIME signing with detached +data if the output format is B it is currently off by default for all +other operations. + +=item B<-noindef> + +disable streaming I/O where it would produce and indefinite length constructed +encoding. This option currently has no effect. In future streaming will be +enabled by default on all relevant operations and this option will disable it. + +=item B<-content filename> + +This specifies a file containing the detached content, this is only +useful with the B<-verify> command. This is only usable if the CMS +structure is using the detached signature form where the content is +not included. This option will override any content if the input format +is S/MIME and it uses the multipart/signed MIME content type. + +=item B<-text> + +this option adds plain text (text/plain) MIME headers to the supplied +message if encrypting or signing. If decrypting or verifying it strips +off text headers: if the decrypted or verified message is not of MIME +type text/plain then an error occurs. + +=item B<-noout> + +for the B<-cmsout> operation do not output the parsed CMS structure. This +is useful when combined with the B<-print> option or if the syntax of the CMS +structure is being checked. + +=item B<-print> + +for the B<-cmsout> operation print out all fields of the CMS structure. This +is mainly useful for testing purposes. + +=item B<-CAfile file> + +a file containing trusted CA certificates, only used with B<-verify>. + +=item B<-CApath dir> + +a directory containing trusted CA certificates, only used with +B<-verify>. This directory must be a standard certificate directory: that +is a hash of each subject name (using B) should be linked +to each certificate. + +=item B<-md digest> + +digest algorithm to use when signing or resigning. If not present then the +default digest algorithm for the signing key will be used (usually SHA1). + +=item B<-[cipher]> + +the encryption algorithm to use. For example triple DES (168 bits) - B<-des3> +or 256 bit AES - B<-aes256>. Any standard algorithm name (as used by the +EVP_get_cipherbyname() function) can also be used preceded by a dash, for +example B<-aes_128_cbc>. See L|enc(1)> for a list of ciphers +supported by your version of OpenSSL. + +If not specified triple DES is used. Only used with B<-encrypt> and +B<-EncryptedData_create> commands. + +=item B<-nointern> + +when verifying a message normally certificates (if any) included in +the message are searched for the signing certificate. With this option +only the certificates specified in the B<-certfile> option are used. +The supplied certificates can still be used as untrusted CAs however. + +=item B<-no_signer_cert_verify> + +do not verify the signers certificate of a signed message. + +=item B<-nocerts> + +when signing a message the signer's certificate is normally included +with this option it is excluded. This will reduce the size of the +signed message but the verifier must have a copy of the signers certificate +available locally (passed using the B<-certfile> option for example). + +=item B<-noattr> + +normally when a message is signed a set of attributes are included which +include the signing time and supported symmetric algorithms. With this +option they are not included. + +=item B<-nosmimecap> + +exclude the list of supported algorithms from signed attributes, other options +such as signing time and content type are still included. + +=item B<-binary> + +normally the input message is converted to "canonical" format which is +effectively using CR and LF as end of line: as required by the S/MIME +specification. When this option is present no translation occurs. This +is useful when handling binary data which may not be in MIME format. + +=item B<-nodetach> + +when signing a message use opaque signing: this form is more resistant +to translation by mail relays but it cannot be read by mail agents that +do not support S/MIME. Without this option cleartext signing with +the MIME type multipart/signed is used. + +=item B<-certfile file> + +allows additional certificates to be specified. When signing these will +be included with the message. When verifying these will be searched for +the signers certificates. The certificates should be in PEM format. + +=item B<-certsout file> + +any certificates contained in the message are written to B. + +=item B<-signer file> + +a signing certificate when signing or resigning a message, this option can be +used multiple times if more than one signer is required. If a message is being +verified then the signers certificates will be written to this file if the +verification was successful. + +=item B<-recip file> + +the recipients certificate when decrypting a message. This certificate +must match one of the recipients of the message or an error occurs. + +=item B<-keyid> + +use subject key identifier to identify certificates instead of issuer name and +serial number. The supplied certificate B include a subject key +identifier extension. Supported by B<-sign> and B<-encrypt> options. + +=item B<-receipt_request_all -receipt_request_first> + +for B<-sign> option include a signed receipt request. Indicate requests should +be provided by all receipient or first tier recipients (those mailed directly +and not from a mailing list). Ignored it B<-receipt_request_from> is included. + +=item B<-receipt_request_from emailaddress> + +for B<-sign> option include a signed receipt request. Add an explicit email +address where receipts should be supplied. + +=item B<-receipt_request_to emailaddress> + +Add an explicit email address where signed receipts should be sent to. This +option B but supplied if a signed receipt it requested. + +=item B<-receipt_request_print> + +For the B<-verify> operation print out the contents of any signed receipt +requests. + +=item B<-secretkey key> + +specify symmetric key to use. The key must be supplied in hex format and be +consistent with the algorithm used. Supported by the B<-EncryptedData_encrypt> +B<-EncrryptedData_decrypt>, B<-encrypt> and B<-decrypt> options. When used +with B<-encrypt> or B<-decrypt> the supplied key is used to wrap or unwrap the +content encryption key using an AES key in the B type. + +=item B<-secretkeyid id> + +the key identifier for the supplied symmetric key for B type. +This option B be present if the B<-secretkey> option is used with +B<-encrypt>. With B<-decrypt> operations the B is used to locate the +relevant key if it is not supplied then an attempt is used to decrypt any +B structures. + +=item B<-econtent_type type> + +set the encapsulated content type to B if not supplied the B type +is used. The B argument can be any valid OID name in either text or +numerical format. + +=item B<-inkey file> + +the private key to use when signing or decrypting. This must match the +corresponding certificate. If this option is not specified then the +private key must be included in the certificate file specified with +the B<-recip> or B<-signer> file. When signing this option can be used +multiple times to specify successive keys. + +=item B<-passin arg> + +the private key password source. For more information about the format of B +see the B section in L. + +=item B<-rand file(s)> + +a file or files containing random data used to seed the random number +generator, or an EGD socket (see L). +Multiple files can be specified separated by a OS-dependent character. +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for +all others. + +=item B + +one or more certificates of message recipients: used when encrypting +a message. + +=item B<-to, -from, -subject> + +the relevant mail headers. These are included outside the signed +portion of a message so they may be included manually. If signing +then many S/MIME mail clients check the signers certificate's email +address matches that specified in the From: address. + +=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig> + +Set various certificate chain valiadition option. See the +L|verify(1)> manual page for details. + +=back + +=head1 NOTES + +The MIME message must be sent without any blank lines between the +headers and the output. Some mail programs will automatically add +a blank line. Piping the mail directly to sendmail is one way to +achieve the correct format. + +The supplied message to be signed or encrypted must include the +necessary MIME headers or many S/MIME clients wont display it +properly (if at all). You can use the B<-text> option to automatically +add plain text headers. + +A "signed and encrypted" message is one where a signed message is +then encrypted. This can be produced by encrypting an already signed +message: see the examples section. + +This version of the program only allows one signer per message but it +will verify multiple signers on received messages. Some S/MIME clients +choke if a message contains multiple signers. It is possible to sign +messages "in parallel" by signing an already signed message. + +The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME +clients. Strictly speaking these process CMS enveloped data: CMS +encrypted data is used for other purposes. + +The B<-resign> option uses an existing message digest when adding a new +signer. This means that attributes must be present in at least one existing +signer using the same message digest or this operation will fail. + +The B<-stream> and B<-indef> options enable experimental streaming I/O support. +As a result the encoding is BER using indefinite length constructed encoding +and no longer DER. Streaming is supported for the B<-encrypt> operation and the +B<-sign> operation if the content is not detached. + +Streaming is always used for the B<-sign> operation with detached data but +since the content is no longer part of the CMS structure the encoding +remains DER. + +=head1 EXIT CODES + +=over 4 + +=item 0 + +the operation was completely successfully. + +=item 1 + +an error occurred parsing the command options. + +=item 2 + +one of the input files could not be read. + +=item 3 + +an error occurred creating the CMS file or when reading the MIME +message. + +=item 4 + +an error occurred decrypting or verifying the message. + +=item 5 + +the message was verified correctly but an error occurred writing out +the signers certificates. + +=back + +=head1 COMPATIBILITY WITH PKCS#7 format. + +The B utility can only process the older B format. The B +utility supports Cryptographic Message Syntax format. Use of some features +will result in messages which cannot be processed by applications which only +support the older format. These are detailed below. + +The use of the B<-keyid> option with B<-sign> or B<-encrypt>. + +The B<-outform PEM> option uses different headers. + +The B<-compress> option. + +The B<-secretkey> option when used with B<-encrypt>. + +Additionally the B<-EncryptedData_create> and B<-data_create> type cannot +be processed by the older B command. + +=head1 EXAMPLES + +Create a cleartext signed message: + + openssl cms -sign -in message.txt -text -out mail.msg \ + -signer mycert.pem + +Create an opaque signed message + + openssl cms -sign -in message.txt -text -out mail.msg -nodetach \ + -signer mycert.pem + +Create a signed message, include some additional certificates and +read the private key from another file: + + openssl cms -sign -in in.txt -text -out mail.msg \ + -signer mycert.pem -inkey mykey.pem -certfile mycerts.pem + +Create a signed message with two signers, use key identifier: + + openssl cms -sign -in message.txt -text -out mail.msg \ + -signer mycert.pem -signer othercert.pem -keyid + +Send a signed message under Unix directly to sendmail, including headers: + + openssl cms -sign -in in.txt -text -signer mycert.pem \ + -from steve@openssl.org -to someone@somewhere \ + -subject "Signed message" | sendmail someone@somewhere + +Verify a message and extract the signer's certificate if successful: + + openssl cms -verify -in mail.msg -signer user.pem -out signedtext.txt + +Send encrypted mail using triple DES: + + openssl cms -encrypt -in in.txt -from steve@openssl.org \ + -to someone@somewhere -subject "Encrypted message" \ + -des3 user.pem -out mail.msg + +Sign and encrypt mail: + + openssl cms -sign -in ml.txt -signer my.pem -text \ + | openssl cms -encrypt -out mail.msg \ + -from steve@openssl.org -to someone@somewhere \ + -subject "Signed and Encrypted message" -des3 user.pem + +Note: the encryption command does not include the B<-text> option because the +message being encrypted already has MIME headers. + +Decrypt mail: + + openssl cms -decrypt -in mail.msg -recip mycert.pem -inkey key.pem + +The output from Netscape form signing is a PKCS#7 structure with the +detached signature format. You can use this program to verify the +signature by line wrapping the base64 encoded structure and surrounding +it with: + + -----BEGIN PKCS7----- + -----END PKCS7----- + +and using the command, + + openssl cms -verify -inform PEM -in signature.pem -content content.txt + +alternatively you can base64 decode the signature and use + + openssl cms -verify -inform DER -in signature.der -content content.txt + +Create an encrypted message using 128 bit Camellia: + + openssl cms -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem + +Add a signer to an existing message: + + openssl cms -resign -in mail.msg -signer newsign.pem -out mail2.msg + +=head1 BUGS + +The MIME parser isn't very clever: it seems to handle most messages that I've +thrown at it but it may choke on others. + +The code currently will only write out the signer's certificate to a file: if +the signer has a separate encryption certificate this must be manually +extracted. There should be some heuristic that determines the correct +encryption certificate. + +Ideally a database should be maintained of a certificates for each email +address. + +The code doesn't currently take note of the permitted symmetric encryption +algorithms as supplied in the SMIMECapabilities signed attribute. this means the +user has to manually include the correct encryption algorithm. It should store +the list of permitted ciphers in a database and only use those. + +No revocation checking is done on the signer's certificate. + +=head1 HISTORY + +The use of multiple B<-signer> options and the B<-resign> command were first +added in OpenSSL 1.0.0 + + +=cut diff --git a/crypto/openssl/doc/apps/dgst.pod b/crypto/openssl/doc/apps/dgst.pod index 908cd2a6d6..b035edf08e 100644 --- a/crypto/openssl/doc/apps/dgst.pod +++ b/crypto/openssl/doc/apps/dgst.pod @@ -14,6 +14,7 @@ B B [B<-binary>] [B<-out filename>] [B<-sign filename>] +[B<-keyform arg>] [B<-passin arg>] [B<-verify filename>] [B<-prverify filename>] @@ -61,6 +62,23 @@ filename to output to, or standard output by default. digitally sign the digest using the private key in "filename". +=item B<-keyform arg> + +Specifies the key format to sign digest with. Only PEM and ENGINE +formats are supported by the B command. + +=item B<-engine id> + +Use engine B for operations (including private key storage). +This engine is not used as source for digest algorithms, unless it is +also specified in the configuration file. + +=item B<-sigopt nm:v> + +Pass options to the signature algorithm during sign or verify operations. +Names and values of these options are algorithm-specific. + + =item B<-passin arg> the private key password source. For more information about the format of B @@ -83,6 +101,35 @@ the actual signature to verify. create a hashed MAC using "key". +=item B<-mac alg> + +create MAC (keyed Message Authentication Code). The most popular MAC +algorithm is HMAC (hash-based MAC), but there are other MAC algorithms +which are not based on hash, for instance B algorithm, +supported by B engine. MAC keys and other options should be set +via B<-macopt> parameter. + +=item B<-macopt nm:v> + +Passes options to MAC algorithm, specified by B<-mac> key. +Following options are supported by both by B and B: + +=over 8 + +=item B + +Specifies MAC key as alphnumeric string (use if key contain printable +characters only). String length must conform to any restrictions of +the MAC algorithm for example exactly 32 chars for gost-mac. + +=item B + +Specifies MAC key in hexadecimal form (two hex digits per byte). +Key length must conform to any restrictions of the MAC algorithm +for example exactly 32 chars for gost-mac. + +=back + =item B<-rand file(s)> a file or files containing random data used to seed the random number diff --git a/crypto/openssl/doc/apps/dhparam.pod b/crypto/openssl/doc/apps/dhparam.pod index c31db95a47..9edb4ff4e1 100644 --- a/crypto/openssl/doc/apps/dhparam.pod +++ b/crypto/openssl/doc/apps/dhparam.pod @@ -99,7 +99,7 @@ be loaded by calling the BIB<()> function. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/dsa.pod b/crypto/openssl/doc/apps/dsa.pod index ed06b8806d..ddbc9327fa 100644 --- a/crypto/openssl/doc/apps/dsa.pod +++ b/crypto/openssl/doc/apps/dsa.pod @@ -109,7 +109,7 @@ a public key. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/dsaparam.pod b/crypto/openssl/doc/apps/dsaparam.pod index b9b1b93b42..ba5ec4d72c 100644 --- a/crypto/openssl/doc/apps/dsaparam.pod +++ b/crypto/openssl/doc/apps/dsaparam.pod @@ -85,7 +85,7 @@ the input file (if any) is ignored. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/ec.pod b/crypto/openssl/doc/apps/ec.pod index 1d4a36dbf4..ba6dc4689b 100644 --- a/crypto/openssl/doc/apps/ec.pod +++ b/crypto/openssl/doc/apps/ec.pod @@ -130,7 +130,7 @@ is currently not implemented in OpenSSL. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/ecparam.pod b/crypto/openssl/doc/apps/ecparam.pod index 1a12105da7..788c074d7b 100644 --- a/crypto/openssl/doc/apps/ecparam.pod +++ b/crypto/openssl/doc/apps/ecparam.pod @@ -121,7 +121,7 @@ all others. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/enc.pod b/crypto/openssl/doc/apps/enc.pod index d3049e82e9..3dee4ed992 100644 --- a/crypto/openssl/doc/apps/enc.pod +++ b/crypto/openssl/doc/apps/enc.pod @@ -12,17 +12,24 @@ B [B<-pass arg>] [B<-e>] [B<-d>] -[B<-a>] +[B<-a/-base64>] [B<-A>] [B<-k password>] [B<-kfile filename>] [B<-K key>] [B<-iv IV>] +[B<-S salt>] +[B<-salt>] +[B<-nosalt>] +[B<-z>] +[B<-md>] [B<-p>] [B<-P>] [B<-bufsize number>] [B<-nopad>] [B<-debug>] +[B<-none>] +[B<-engine id>] =head1 DESCRIPTION @@ -72,6 +79,10 @@ base64 process the data. This means that if encryption is taking place the data is base64 encoded after encryption. If decryption is set then the input data is base64 decoded before being decrypted. +=item B<-base64> + +same as B<-a> + =item B<-A> if the B<-a> option is set then base64 process the data on one line. @@ -87,10 +98,18 @@ read the password to derive the key from the first line of B. This is for compatibility with previous versions of OpenSSL. Superseded by the B<-pass> argument. +=item B<-nosalt> + +do not use a salt + +=item B<-salt> + +use salt (randomly generated or provide with B<-S> option) when +encrypting (this is the default). + =item B<-S salt> -the actual salt to use: this must be represented as a string comprised only -of hex digits. +the actual salt to use: this must be represented as a string of hex digits. =item B<-K key> @@ -129,12 +148,34 @@ disable standard block padding debug the BIOs used for I/O. +=item B<-z> + +Compress or decompress clear text using zlib before encryption or after +decryption. This option exists only if OpenSSL with compiled with zlib +or zlib-dynamic option. + +=item B<-none> + +Use NULL cipher (no encryption or decryption of input). + =back =head1 NOTES The program can be called either as B or -B. +B. But the first form doesn't work with +engine-provided ciphers, because this form is processed before the +configuration file is read and any ENGINEs loaded. + +Engines which provide entirely new encryption algorithms (such as ccgost +engine which provides gost89 algorithm) should be configured in the +configuration file. Engines, specified in the command line using -engine +options can only be used for hadrware-assisted implementations of +ciphers, which are supported by OpenSSL core or other engine, specified +in the configuration file. + +When enc command lists supported ciphers, ciphers provided by engines, +specified in the configuration files are listed too. A password will be prompted for to derive the key and IV if necessary. @@ -167,6 +208,14 @@ Blowfish and RC5 algorithms use a 128 bit key. =head1 SUPPORTED CIPHERS +Note that some of these ciphers can be disabled at compile time +and some are available only if an appropriate engine is configured +in the configuration file. The output of the B command run with +unsupported options (for example B) includes a +list of ciphers, supported by your versesion of OpenSSL, including +ones provided by configured engines. + + base64 Base 64 bf-cbc Blowfish in CBC mode @@ -201,6 +250,9 @@ Blowfish and RC5 algorithms use a 128 bit key. desx DESX algorithm. + gost89 GOST 28147-89 in CFB mode (provided by ccgost engine) + gost89-cnt `GOST 28147-89 in CNT mode (provided by ccgost engine) + idea-cbc IDEA algorithm in CBC mode idea same as idea-cbc idea-cfb IDEA in CFB mode diff --git a/crypto/openssl/doc/apps/gendsa.pod b/crypto/openssl/doc/apps/gendsa.pod index 2c56cc7888..8c7f114ca0 100644 --- a/crypto/openssl/doc/apps/gendsa.pod +++ b/crypto/openssl/doc/apps/gendsa.pod @@ -40,7 +40,7 @@ all others. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/genpkey.pod b/crypto/openssl/doc/apps/genpkey.pod new file mode 100644 index 0000000000..1611b5ca78 --- /dev/null +++ b/crypto/openssl/doc/apps/genpkey.pod @@ -0,0 +1,213 @@ +=pod + +=head1 NAME + +genpkey - generate a private key + +=head1 SYNOPSIS + +B B +[B<-out filename>] +[B<-outform PEM|DER>] +[B<-pass arg>] +[B<-cipher>] +[B<-engine id>] +[B<-paramfile file>] +[B<-algorithm alg>] +[B<-pkeyopt opt:value>] +[B<-genparam>] +[B<-text>] + +=head1 DESCRIPTION + +The B command generates a private key. + +=head1 OPTIONS + +=over 4 + +=item B<-out filename> + +the output filename. If this argument is not specified then standard output is +used. + +=item B<-outform DER|PEM> + +This specifies the output format DER or PEM. + +=item B<-pass arg> + +the output file password source. For more information about the format of B +see the B section in L. + +=item B<-cipher> + +This option encrypts the private key with the supplied cipher. Any algorithm +name accepted by EVP_get_cipherbyname() is acceptable such as B. + +=item B<-engine id> + +specifying an engine (by its unique B string) will cause B +to attempt to obtain a functional reference to the specified engine, +thus initialising it if needed. The engine will then be set as the default +for all available algorithms. If used this option should precede all other +options. + +=item B<-algorithm alg> + +public key algorithm to use such as RSA, DSA or DH. If used this option must +precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm> +are mutually exclusive. + +=item B<-pkeyopt opt:value> + +set the public key algorithm option B to B. The precise set of +options supported depends on the public key algorithm used and its +implementation. See B below for more details. + +=item B<-genparam> + +generate a set of parameters instead of a private key. If used this option must +precede and B<-algorithm>, B<-paramfile> or B<-pkeyopt> options. + +=item B<-paramfile filename> + +Some public key algorithms generate a private key based on a set of parameters. +They can be supplied using this option. If this option is used the public key +algorithm used is determined by the parameters. If used this option must +precede and B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm> +are mutually exclusive. + +=item B<-text> + +Print an (unencrypted) text representation of private and public keys and +parameters along with the PEM or DER structure. + +=back + +=head1 KEY GENERATION OPTIONS + +The options supported by each algorith and indeed each implementation of an +algorithm can vary. The options for the OpenSSL implementations are detailed +below. + +=head1 RSA KEY GENERATION OPTIONS + +=over 4 + +=item B + +The number of bits in the generated key. If not specified 1024 is used. + +=item B + +The RSA public exponent value. This can be a large decimal or +hexadecimal value if preceded by B<0x>. Default value is 65537. + +=back + +=head1 DSA PARAMETER GENERATION OPTIONS + +=over 4 + +=item B + +The number of bits in the generated parameters. If not specified 1024 is used. + +=head1 DH PARAMETER GENERATION OPTIONS + +=over 4 + +=item B + +The number of bits in the prime parameter B

. + +=item B + +The value to use for the generator B. + +=back + +=head1 EC PARAMETER GENERATION OPTIONS + +=over 4 + +=item B + +the EC curve to use. + +=back + +=head1 GOST2001 KEY GENERATION AND PARAMETER OPTIONS + +Gost 2001 support is not enabled by default. To enable this algorithm, +one should load the ccgost engine in the OpenSSL configuration file. +See README.gost file in the engines/ccgost directiry of the source +distribution for more details. + +Use of a parameter file for the GOST R 34.10 algorithm is optional. +Parameters can be specified during key generation directly as well as +during generation of parameter file. + +=over 4 + +=item B + +Specifies GOST R 34.10-2001 parameter set according to RFC 4357. +Parameter set can be specified using abbreviated name, object short name or +numeric OID. Following parameter sets are supported: + + paramset OID Usage + A 1.2.643.2.2.35.1 Signature + B 1.2.643.2.2.35.2 Signature + C 1.2.643.2.2.35.3 Signature + XA 1.2.643.2.2.36.0 Key exchange + XB 1.2.643.2.2.36.1 Key exchange + test 1.2.643.2.2.35.0 Test purposes + +=back + + + +=head1 NOTES + +The use of the genpkey program is encouraged over the algorithm specific +utilities because additional algorithm options and ENGINE provided algorithms +can be used. + +=head1 EXAMPLES + +Generate an RSA private key using default parameters: + + openssl genpkey -algorithm RSA -out key.pem + +Encrypt output private key using 128 bit AES and the passphrase "hello": + + openssl genpkey -algorithm RSA -out key.pem -aes-128-cbc -pass pass:hello + +Generate a 2048 bit RSA key using 3 as the public exponent: + + openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048 \ + -pkeyopt rsa_keygen_pubexp:3 + +Generate 1024 bit DSA parameters: + + openssl genpkey -genparam -algorithm DSA -out dsap.pem \ + -pkeyopt dsa_paramgen_bits:1024 + +Generate DSA key from parameters: + + openssl genpkey -paramfile dsap.pem -out dsakey.pem + +Generate 1024 bit DH parameters: + + openssl genpkey -genparam -algorithm DH -out dhp.pem \ + -pkeyopt dh_paramgen_prime_len:1024 + +Generate DH key from parameters: + + openssl genpkey -paramfile dhp.pem -out dhkey.pem + + +=cut + diff --git a/crypto/openssl/doc/apps/genrsa.pod b/crypto/openssl/doc/apps/genrsa.pod index 25af4d1475..7dcac2a779 100644 --- a/crypto/openssl/doc/apps/genrsa.pod +++ b/crypto/openssl/doc/apps/genrsa.pod @@ -57,7 +57,7 @@ all others. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/ocsp.pod b/crypto/openssl/doc/apps/ocsp.pod index b58ddc1788..af2e12e418 100644 --- a/crypto/openssl/doc/apps/ocsp.pod +++ b/crypto/openssl/doc/apps/ocsp.pod @@ -51,6 +51,7 @@ B B [B<-ndays n>] [B<-resp_key_id>] [B<-nrequest n>] +[B<-md5|-sha1|...>] =head1 DESCRIPTION @@ -206,6 +207,11 @@ information is immediately available. In this case the age of the B f is checked to see it is not older than B seconds old. By default this additional check is not performed. +=item B<-md5|-sha1|-sha256|-ripemod160|...> + +this option sets digest algorithm to use for certificate identification +in the OCSP request. By default SHA-1 is used. + =back =head1 OCSP SERVER OPTIONS diff --git a/crypto/openssl/doc/apps/openssl.pod b/crypto/openssl/doc/apps/openssl.pod index 964cdf0f02..738142e9ff 100644 --- a/crypto/openssl/doc/apps/openssl.pod +++ b/crypto/openssl/doc/apps/openssl.pod @@ -12,7 +12,7 @@ I [ I ] [ I ] -B [ B | B | B ] +B [ B | B | B | B | B | B] B BI [ I ] @@ -26,12 +26,14 @@ The B program is a command line tool for using the various cryptography functions of OpenSSL's B library from the shell. It can be used for - o Creation of RSA, DH and DSA key parameters + o Creation and management of private keys, public keys and parameters + o Public key cryptographic operations o Creation of X.509 certificates, CSRs and CRLs o Calculation of Message Digests o Encryption and Decryption with Ciphers o SSL/TLS Client and Server Tests o Handling of S/MIME signed or encrypted mail + o Time Stamp requests, generation and verification =head1 COMMAND SUMMARY @@ -44,6 +46,14 @@ and B output a list (one entry per line) of the names of all standard commands, message digest commands, or cipher commands, respectively, that are available in the present B utility. +The pseudo-commands B and +B list all cipher and message digest names, one entry per line. Aliases are listed as: + + from => to + +The pseudo-command B lists all supported public +key algorithms. + The pseudo-command BI tests whether a command of the specified name is available. If no command named I exists, it returns 0 (success) and prints BI; otherwise it returns 1 @@ -71,6 +81,10 @@ Certificate Authority (CA) Management. Cipher Suite Description Determination. +=item L|cms(1)> + +CMS (Cryptographic Message Syntax) utility + =item L|crl(1)> Certificate Revocation List (CRL) Management. @@ -88,25 +102,40 @@ Message Digest Calculation. Diffie-Hellman Parameter Management. Obsoleted by L|dhparam(1)>. +=item L|dhparam(1)> + +Generation and Management of Diffie-Hellman Parameters. Superseded by +L|genpkey(1)> and L|pkeyparam(1)> + + =item L|dsa(1)> DSA Data Management. =item L|dsaparam(1)> -DSA Parameter Generation. +DSA Parameter Generation and Management. Superseded by +L|genpkey(1)> and L|pkeyparam(1)> + +=item L|ec(1)> + +EC (Elliptic curve) key processing + +=item L|ecparam(1)> + +EC parameter manipulation and generation =item L|enc(1)> Encoding with Ciphers. -=item L|errstr(1)> +=item L|engine(1)> -Error Number to Error String Conversion. +Engine (loadble module) information and manipulation. -=item L|dhparam(1)> +=item L|errstr(1)> -Generation and Management of Diffie-Hellman Parameters. +Error Number to Error String Conversion. =item B @@ -115,11 +144,20 @@ Obsoleted by L|dhparam(1)>. =item L|gendsa(1)> -Generation of DSA Parameters. +Generation of DSA Private Key from Parameters. Superseded by +L|genpkey(1)> and L|pkey(1)> + +=item L|genpkey(1)> + +Generation of Private Key or Parameters. =item L|genrsa(1)> -Generation of RSA Parameters. +Generation of RSA Private Key. Superceded by L|genpkey(1)>. + +=item L|nseq(1)> + +Create or examine a netscape certificate sequence =item L|ocsp(1)> @@ -137,21 +175,35 @@ PKCS#12 Data Management. PKCS#7 Data Management. +=item L|pkey(1)> + +Public and private key management. + +=item L|pkeyparam(1)> + +Public key algorithm parameter management. + +=item L|pkeyutl(1)> + +Public key algorithm cryptographic operation utility. + =item L|rand(1)> Generate pseudo-random bytes. =item L|req(1)> -X.509 Certificate Signing Request (CSR) Management. +PKCS#10 X.509 Certificate Signing Request (CSR) Management. =item L|rsa(1)> -RSA Data Management. +RSA key management. + =item L|rsautl(1)> -RSA utility for signing, verification, encryption, and decryption. +RSA utility for signing, verification, encryption, and decryption. Superseded +by L|pkeyutl(1)> =item L|s_client(1)> @@ -185,6 +237,14 @@ S/MIME mail processing. Algorithm Speed Measurement. +=item L|spkac(1)> + +SPKAC printing and generating utility + +=item L|ts(1)> + +Time Stamping Authority tool (client/server) + =item L|verify(1)> X.509 Certificate Verification. @@ -227,6 +287,8 @@ SHA Digest SHA-1 Digest +=back + =item B SHA-224 Digest @@ -243,8 +305,6 @@ SHA-384 Digest SHA-512 Digest -=back - =head2 ENCODING AND CIPHER COMMANDS =over 10 @@ -339,7 +399,7 @@ read the password from standard input. L, L, L, L, L, L, L, L, L, -L, L, +L, L, L, L, L, L, L, L, L, L, @@ -348,12 +408,13 @@ L, L, L, L, L, L, L, L, L, -L, L +L, L, L =head1 HISTORY The openssl(1) document appeared in OpenSSL 0.9.2. The BIB<-commands> pseudo-commands were added in OpenSSL 0.9.3; +The BIB<-algorithms> pseudo-commands were added in OpenSSL 1.0.0; the BI pseudo-commands were added in OpenSSL 0.9.5a. For notes on the availability of other commands, see their individual manual pages. diff --git a/crypto/openssl/doc/apps/pkcs12.pod b/crypto/openssl/doc/apps/pkcs12.pod index 7d84146293..f69a5c5a4c 100644 --- a/crypto/openssl/doc/apps/pkcs12.pod +++ b/crypto/openssl/doc/apps/pkcs12.pod @@ -23,22 +23,23 @@ B B [B<-cacerts>] [B<-nokeys>] [B<-info>] -[B<-des>] -[B<-des3>] -[B<-idea>] -[B<-nodes>] +[B<-des | -des3 | -idea | -aes128 | -aes192 | -aes256 | -camellia128 | -camellia192 | -camellia256 | -nodes>] [B<-noiter>] -[B<-maciter>] +[B<-maciter | -nomaciter | -nomac>] [B<-twopass>] [B<-descert>] -[B<-certpbe>] -[B<-keypbe>] +[B<-certpbe cipher>] +[B<-keypbe cipher>] +[B<-macalg digest>] [B<-keyex>] [B<-keysig>] [B<-password arg>] [B<-passin arg>] [B<-passout arg>] [B<-rand file(s)>] +[B<-CAfile file>] +[B<-CApath dir>] +[B<-CSP name>] =head1 DESCRIPTION @@ -49,7 +50,7 @@ programs including Netscape, MSIE and MS Outlook. =head1 COMMAND OPTIONS There are a lot of options the meaning of some depends of whether a PKCS#12 file -is being created or parsed. By default a PKCS#12 file is parsed a PKCS#12 +is being created or parsed. By default a PKCS#12 file is parsed. A PKCS#12 file can be created by using the B<-export> option (see below). =head1 PARSING OPTIONS @@ -63,25 +64,25 @@ by default. =item B<-out filename> -The filename to write certificates and private keys to, standard output by default. -They are all written in PEM format. +The filename to write certificates and private keys to, standard output by +default. They are all written in PEM format. =item B<-pass arg>, B<-passin arg> -the PKCS#12 file (i.e. input file) password source. For more information about the -format of B see the B section in +the PKCS#12 file (i.e. input file) password source. For more information about +the format of B see the B section in L. =item B<-passout arg> -pass phrase source to encrypt any outputed private keys with. For more information -about the format of B see the B section in -L. +pass phrase source to encrypt any outputed private keys with. For more +information about the format of B see the B section +in L. =item B<-noout> -this option inhibits output of the keys and certificates to the output file version -of the PKCS#12 file. +this option inhibits output of the keys and certificates to the output file +version of the PKCS#12 file. =item B<-clcerts> @@ -116,6 +117,14 @@ use triple DES to encrypt private keys before outputting, this is the default. use IDEA to encrypt private keys before outputting. +=item B<-aes128>, B<-aes192>, B<-aes256> + +use AES to encrypt private keys before outputting. + +=item B<-camellia128>, B<-camellia192>, B<-camellia256> + +use Camellia to encrypt private keys before outputting. + =item B<-nodes> don't encrypt the private keys at all. @@ -148,10 +157,10 @@ by default. =item B<-in filename> -The filename to read certificates and private keys from, standard input by default. -They must all be in PEM format. The order doesn't matter but one private key and -its corresponding certificate should be present. If additional certificates are -present they will also be included in the PKCS#12 file. +The filename to read certificates and private keys from, standard input by +default. They must all be in PEM format. The order doesn't matter but one +private key and its corresponding certificate should be present. If additional +certificates are present they will also be included in the PKCS#12 file. =item B<-inkey filename> @@ -160,8 +169,8 @@ in the input file. =item B<-name friendlyname> -This specifies the "friendly name" for the certificate and private key. This name -is typically displayed in list boxes by software importing the file. +This specifies the "friendly name" for the certificate and private key. This +name is typically displayed in list boxes by software importing the file. =item B<-certfile filename> @@ -201,9 +210,11 @@ key is encrypted using triple DES and the certificate using 40 bit RC2. =item B<-keypbe alg>, B<-certpbe alg> these options allow the algorithm used to encrypt the private key and -certificates to be selected. Although any PKCS#5 v1.5 or PKCS#12 algorithms -can be selected it is advisable only to use PKCS#12 algorithms. See the list -in the B section for more information. +certificates to be selected. Any PKCS#5 v1.5 or PKCS#12 PBE algorithm name +can be used (see B section for more information). If a a cipher name +(as output by the B command is specified then it +is used with PKCS#5 v2.0. For interoperability reasons it is advisable to only +use PKCS#12 algorithms. =item B<-keyex|-keysig> @@ -216,6 +227,10 @@ S/MIME signing, authenticode (ActiveX control signing) and SSL client authentication, however due to a bug only MSIE 5.0 and later support the use of signing only keys for SSL client authentication. +=item B<-macalg digest> + +specify the MAC digest algorithm. If not included them SHA1 will be used. + =item B<-nomaciter>, B<-noiter> these options affect the iteration counts on the MAC and key algorithms. @@ -239,6 +254,10 @@ option. This option is included for compatibility with previous versions, it used to be needed to use MAC iterations counts but they are now used by default. +=item B<-nomac> + +don't attempt to provide the MAC integrity. + =item B<-rand file(s)> a file or files containing random data used to seed the random number @@ -247,6 +266,20 @@ Multiple files can be specified separated by a OS-dependent character. The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for all others. +=item B<-CAfile file> + +CA storage as a file. + +=item B<-CApath dir> + +CA storage as a directory. This directory must be a standard certificate +directory: that is a hash of each subject name (using B) should be +linked to each certificate. + +=item B<-CSP name> + +write B as a Microsoft CSP name. + =back =head1 NOTES diff --git a/crypto/openssl/doc/apps/pkcs7.pod b/crypto/openssl/doc/apps/pkcs7.pod index a0a636328b..acfb8100f0 100644 --- a/crypto/openssl/doc/apps/pkcs7.pod +++ b/crypto/openssl/doc/apps/pkcs7.pod @@ -62,7 +62,7 @@ is B<-print_certs> is set). =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/pkcs8.pod b/crypto/openssl/doc/apps/pkcs8.pod index 68ecd65b10..84abee78f3 100644 --- a/crypto/openssl/doc/apps/pkcs8.pod +++ b/crypto/openssl/doc/apps/pkcs8.pod @@ -125,7 +125,7 @@ list of possible algorithms is included below. =item B<-engine id> -specifying an engine (by it's unique B string) will cause B +specifying an engine (by its unique B string) will cause B to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. diff --git a/crypto/openssl/doc/apps/pkey.pod b/crypto/openssl/doc/apps/pkey.pod new file mode 100644 index 0000000000..4851223f3f --- /dev/null +++ b/crypto/openssl/doc/apps/pkey.pod @@ -0,0 +1,135 @@ + +=pod + +=head1 NAME + +pkey - public or private key processing tool + +=head1 SYNOPSIS + +B B +[B<-inform PEM|DER>] +[B<-outform PEM|DER>] +[B<-in filename>] +[B<-passin arg>] +[B<-out filename>] +[B<-passout arg>] +[B<-cipher>] +[B<-text>] +[B<-text_pub>] +[B<-noout>] +[B<-pubin>] +[B<-pubout>] +[B<-engine id>] + +=head1 DESCRIPTION + +The B command processes public or private keys. They can be converted +between various forms and their components printed out. + +=head1 COMMAND OPTIONS + +=over 4 + +=item B<-inform DER|PEM> + +This specifies the input format DER or PEM. + +=item B<-outform DER|PEM> + +This specifies the output format, the options have the same meaning as the +B<-inform> option. + +=item B<-in filename> + +This specifies the input filename to read a key from or standard input if this +option is not specified. If the key is encrypted a pass phrase will be +prompted for. + +=item B<-passin arg> + +the input file password source. For more information about the format of B +see the B section in L. + +=item B<-out filename> + +This specifies the output filename to write a key to or standard output if this +option is not specified. If any encryption options are set then a pass phrase +will be prompted for. The output filename should B be the same as the input +filename. + +=item B<-passout password> + +the output file password source. For more information about the format of B +see the B section in L. + +=item B<-cipher> + +These options encrypt the private key with the supplied cipher. Any algorithm +name accepted by EVP_get_cipherbyname() is acceptable such as B. + +=item B<-text> + +prints out the various public or private key components in +plain text in addition to the encoded version. + +=item B<-text_pub> + +print out only public key components even if a private key is being processed. + +=item B<-noout> + +do not output the encoded version of the key. + +=item B<-pubin> + +by default a private key is read from the input file: with this +option a public key is read instead. + +=item B<-pubout> + +by default a private key is output: with this option a public +key will be output instead. This option is automatically set if +the input is a public key. + +=item B<-engine id> + +specifying an engine (by its unique B string) will cause B +to attempt to obtain a functional reference to the specified engine, +thus initialising it if needed. The engine will then be set as the default +for all available algorithms. + +=back + +=head1 EXAMPLES + +To remove the pass phrase on an RSA private key: + + openssl pkey -in key.pem -out keyout.pem + +To encrypt a private key using triple DES: + + openssl pkey -in key.pem -des3 -out keyout.pem + +To convert a private key from PEM to DER format: + + openssl pkey -in key.pem -outform DER -out keyout.der + +To print out the components of a private key to standard output: + + openssl pkey -in key.pem -text -noout + +To print out the public components of a private key to standard output: + + openssl pkey -in key.pem -text_pub -noout + +To just output the public part of a private key: + + openssl pkey -in key.pem -pubout -out pubkey.pem + +=head1 SEE ALSO + +L, L, L, +L, L, L + +=cut diff --git a/crypto/openssl/doc/apps/pkeyparam.pod b/crypto/openssl/doc/apps/pkeyparam.pod new file mode 100644 index 0000000000..154f6721af --- /dev/null +++ b/crypto/openssl/doc/apps/pkeyparam.pod @@ -0,0 +1,69 @@ + +=pod + +=head1 NAME + +pkeyparam - public key algorithm parameter processing tool + +=head1 SYNOPSIS + +B B +[B<-in filename>] +[B<-out filename>] +[B<-text>] +[B<-noout>] +[B<-engine id>] + +=head1 DESCRIPTION + +The B command processes public or private keys. They can be converted +between various forms and their components printed out. + +=head1 COMMAND OPTIONS + +=over 4 + +=item B<-in filename> + +This specifies the input filename to read parameters from or standard input if +this option is not specified. + +=item B<-out filename> + +This specifies the output filename to write parameters to or standard output if +this option is not specified. + +=item B<-text> + +prints out the parameters in plain text in addition to the encoded version. + +=item B<-noout> + +do not output the encoded version of the parameters. + +=item B<-engine id> + +specifying an engine (by its unique B string) will cause B +to attempt to obtain a functional reference to the specified engine, +thus initialising it if needed. The engine will then be set as the default +for all available algorithms. + +=back + +=head1 EXAMPLE + +Print out text version of parameters: + + openssl pkeyparam -in param.pem -text + +=head1 NOTES + +There are no B<-inform> or B<-outform> options for this command because only +PEM format is supported because the key type is determined by the PEM headers. + +=head1 SEE ALSO + +L, L, L, +L, L, L + +=cut diff --git a/crypto/openssl/doc/apps/pkeyutl.pod b/crypto/openssl/doc/apps/pkeyutl.pod new file mode 100644 index 0000000000..27be9a9007 --- /dev/null +++ b/crypto/openssl/doc/apps/pkeyutl.pod @@ -0,0 +1,222 @@ +=pod + +=head1 NAME + +pkeyutl - public key algorithm utility + +=head1 SYNOPSIS + +B B +[B<-in file>] +[B<-out file>] +[B<-sigfile file>] +[B<-inkey file>] +[B<-keyform PEM|DER>] +[B<-passin arg>] +[B<-peerkey file>] +[B<-peerform PEM|DER>] +[B<-pubin>] +[B<-certin>] +[B<-rev>] +[B<-sign>] +[B<-verify>] +[B<-verifyrecover>] +[B<-encrypt>] +[B<-decrypt>] +[B<-derive>] +[B<-pkeyopt opt:value>] +[B<-hexdump>] +[B<-asn1parse>] +[B<-engine id>] + +=head1 DESCRIPTION + +The B command can be used to perform public key operations using +any supported algorithm. + +=head1 COMMAND OPTIONS + +=over 4 + +=item B<-in filename> + +This specifies the input filename to read data from or standard input +if this option is not specified. + +=item B<-out filename> + +specifies the output filename to write to or standard output by +default. + +=item B<-inkey file> + +the input key file, by default it should be a private key. + +=item B<-keyform PEM|DER> + +the key format PEM, DER or ENGINE. + +=item B<-passin arg> + +the input key password source. For more information about the format of B +see the B section in L. + + +=item B<-peerkey file> + +the peer key file, used by key derivation (agreement) operations. + +=item B<-peerform PEM|DER> + +the peer key format PEM, DER or ENGINE. + +=item B<-engine id> + +specifying an engine (by its unique B string) will cause B +to attempt to obtain a functional reference to the specified engine, +thus initialising it if needed. The engine will then be set as the default +for all available algorithms. + + +=item B<-pubin> + +the input file is a public key. + +=item B<-certin> + +the input is a certificate containing a public key. + +=item B<-rev> + +reverse the order of the input buffer. This is useful for some libraries +(such as CryptoAPI) which represent the buffer in little endian format. + +=item B<-sign> + +sign the input data and output the signed result. This requires +a private key. + +=item B<-verify> + +verify the input data against the signature file and indicate if the +verification succeeded or failed. + +=item B<-verifyrecover> + +verify the input data and output the recovered data. + +=item B<-encrypt> + +encrypt the input data using a public key. + +=item B<-decrypt> + +decrypt the input data using a private key. + +=item B<-derive> + +derive a shared secret using the peer key. + +=item B<-hexdump> + +hex dump the output data. + +=item B<-asn1parse> + +asn1parse the output data, this is useful when combined with the +B<-verifyrecover> option when an ASN1 structure is signed. + +=back + +=head1 NOTES + +The operations and options supported vary according to the key algorithm +and its implementation. The OpenSSL operations and options are indicated below. + +Unless otherwise mentioned all algorithms support the B option +which specifies the digest in use for sign, verify and verifyrecover operations. +The value B should represent a digest name as used in the +EVP_get_digestbyname() function for example B. + +=head1 RSA ALGORITHM + +The RSA algorithm supports encrypt, decrypt, sign, verify and verifyrecover +operations in general. Some padding modes only support some of these +operations however. + +=over 4 + +=item -B + +This sets the RSA padding mode. Acceptable values for B are B for +PKCS#1 padding, B for SSLv23 padding, B for no padding, B +for B mode, B for X9.31 mode and B for PSS. + +In PKCS#1 padding if the message digest is not set then the supplied data is +signed or verified directly instead of using a B structure. If a +digest is set then the a B structure is used and its the length +must correspond to the digest type. + +For B mode only encryption and decryption is supported. + +For B if the digest type is set it is used to format the block data +otherwise the first byte is used to specify the X9.31 digest ID. Sign, +verify and verifyrecover are can be performed in this mode. + +For B mode only sign and verify are supported and the digest type must be +specified. + +=item B + +For B mode only this option specifies the salt length. Two special values +are supported: -1 sets the salt length to the digest length. When signing -2 +sets the salt length to the maximum permissible value. When verifying -2 causes +the salt length to be automatically determined based on the B block +structure. + +=back + +=head1 DSA ALGORITHM + +The DSA algorithm supports signing and verification operations only. Currently +there are no additional options other than B. Only the SHA1 +digest can be used and this digest is assumed by default. + +=head1 DH ALGORITHM + +The DH algorithm only supports the derivation operation and no additional +options. + +=head1 EC ALGORITHM + +The EC algorithm supports sign, verify and derive operations. The sign and +verify operations use ECDSA and derive uses ECDH. Currently there are no +additional options other than B. Only the SHA1 digest can be used and +this digest is assumed by default. + +=head1 EXAMPLES + +Sign some data using a private key: + + openssl pkeyutl -sign -in file -inkey key.pem -out sig + +Recover the signed data (e.g. if an RSA key is used): + + openssl pkeyutl -verifyrecover -in sig -inkey key.pem + +Verify the signature (e.g. a DSA key): + + openssl pkeyutl -verify -in file -sigfile sig -inkey key.pem + +Sign data using a message digest value (this is currently only valid for RSA): + + openssl pkeyutl -sign -in file -inkey key.pem -out sig -pkeyopt digest:sha256 + +Derive a shared secret value: + + openssl pkeyutl -derive -inkey key.pem -peerkey pubkey.pem -out secret + +=head1 SEE ALSO + +L, L, L +L, L, L diff --git a/crypto/openssl/doc/apps/req.pod b/crypto/openssl/doc/apps/req.pod index 82b565c9d4..ff48bbdf28 100644 --- a/crypto/openssl/doc/apps/req.pod +++ b/crypto/openssl/doc/apps/req.pod @@ -22,12 +22,13 @@ B B [B<-new>] [B<-rand file(s)>] [B<-newkey rsa:bits>] -[B<-newkey dsa:file>] +[B<-newkey alg:file>] [B<-nodes>] [B<-key filename>] [B<-keyform PEM|DER>] [B<-keyout filename>] -[B<-[md5|sha1|md2|mdc2]>] +[B<-keygen_engine id>] +[B<-[digest]>] [B<-config filename>] [B<-subj arg>] [B<-multivalue-rdn>] @@ -35,11 +36,15 @@ B B [B<-days n>] [B<-set_serial n>] [B<-asn1-kludge>] +[B<-no-asn1-kludge>] [B<-newhdr>] [B<-extensions section>] [B<-reqexts section>] [B<-utf8>] [B<-nameopt>] +[B<-reqopt>] +[B<-subject>] +[B<-subj arg>] [B<-batch>] [B<-verbose>] [B<-engine id>] @@ -91,6 +96,11 @@ see the B section in L. prints out the certificate request in text form. +=item B<-subject> + +prints out the request subject (or certificate subject if B<-x509> is +specified) + =item B<-pubkey> outputs the public key. @@ -118,6 +128,13 @@ in the configuration file and any requested extensions. If the B<-key> option is not used it will generate a new RSA private key using information specified in the configuration file. +=item B<-subj arg> + +Replaces subject field of input request with specified data and outputs +modified request. The arg must be formatted as +I, +characters may be escaped by \ (backslash), no spaces are skipped. + =item B<-rand file(s)> a file or files containing random data used to seed the random number @@ -129,10 +146,35 @@ all others. =item B<-newkey arg> this option creates a new certificate request and a new private -key. The argument takes one of two forms. B, where +key. The argument takes one of several forms. B, where B is the number of bits, generates an RSA key B -in size. B generates a DSA key using the parameters -in the file B. +in size. If B is omitted, i.e. B<-newkey rsa> specified, +the default key size, specified in the configuration file is used. + +All other algorithms support the B<-newkey alg:file> form, where file may be +an algorithm parameter file, created by the B command +or and X.509 certificate for a key with approriate algorithm. + +B generates a key using the parameter file or certificate B, +the algorithm is determined by the parameters. B use algorithm +B and parameter file B: the two algorithms must match or an +error occurs. B just uses algorithm B, and parameters, +if neccessary should be specified via B<-pkeyopt> parameter. + +B generates a DSA key using the parameters +in the file B. B generates EC key (usable both with +ECDSA or ECDH algorithms), B generates GOST R +34.10-2001 key (requires B engine configured in the configuration +file). If just B is specified a parameter set should be +specified by B<-pkeyopt paramset:X> + + +=item B<-pkeyopt opt:value> + +set the public key algorithm option B to B. The precise set of +options supported depends on the public key algorithm used and its +implementation. See B in the B manual page +for more details. =item B<-key filename> @@ -155,11 +197,15 @@ configuration file is used. if this option is specified then if a private key is created it will not be encrypted. -=item B<-[md5|sha1|md2|mdc2]> +=item B<-[digest]> + +this specifies the message digest to sign the request with (such as +B<-md5>, B<-sha1>). This overrides the digest algorithm specified in +the configuration file. -this specifies the message digest to sign the request with. This -overrides the digest algorithm specified in the configuration file. -This option is ignored for DSA requests: they always use SHA1. +Some public key algorithms may override this choice. For instance, DSA +signatures always use SHA1, GOST R 34.10 signatures always use +GOST R 34.11-94 (B<-md_gost94>). =item B<-config filename> @@ -227,6 +273,15 @@ B

for DH parameter generation. If this macro is not called +then 1024 is used. + +The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B +for DH parameter generation. If not specified 2 is used. + +The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter +generation to B. For EC parameter generation this macro must be called +or an error occurs because there is no default curve. + +=head1 RETURN VALUES + +EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0 +or a negative value for failure. In particular a return value of -2 +indicates the operation is not supported by the public key algorithm. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_CTX_new.pod b/crypto/openssl/doc/crypto/EVP_PKEY_CTX_new.pod new file mode 100644 index 0000000000..a9af867580 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_CTX_new.pod @@ -0,0 +1,52 @@ +=pod + +=head1 NAME + +EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - public key algorithm context functions. + +=head1 SYNOPSIS + + #include + + EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); + EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); + EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); + void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +=head1 DESCRIPTION + +The EVP_PKEY_CTX_new() function allocates public key algorithm context using +the algorithm specified in B and ENGINE B. + +The EVP_PKEY_CTX_new_id() function allocates public key algorithm context +using the algorithm specified by B and ENGINE B. It is normally used +when no B structure is associated with the operations, for example +during parameter generation of key genration for some algorithms. + +EVP_PKEY_CTX_dup() duplicates the context B. + +EVP_PKEY_CTX_free() frees up the context B. + +=head1 NOTES + +The B structure is an opaque public key algorithm context used +by the OpenSSL high level public key API. Contexts B be shared between +threads: that is it is not permissible to use the same context simultaneously +in two threads. + +=head1 RETURN VALUES + +EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() returns either +the newly allocated B structure of B if an error occurred. + +EVP_PKEY_CTX_free() does not return a value. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod b/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod new file mode 100644 index 0000000000..4f8185e36c --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod @@ -0,0 +1,61 @@ +=pod + +=head1 NAME + +EVP_PKEY_copy_parameters, EVP_PKEY_missing_parameters, EVP_PKEY_cmp_parameters, EVP_PKEY_cmp - public key parameter and comparison functions + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); + int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); + + int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +=head1 DESCRIPTION + +The function EVP_PKEY_missing_parameters() returns 1 if the public key +parameters of B are missing and 0 if they are present or the algorithm +doesn't use parameters. + +The function EVP_PKEY_copy_parameters() copies the parameters from key +B to key B. + +The funcion EVP_PKEY_cmp_parameters() compares the parameters of keys +B and B. + +The funcion EVP_PKEY_cmp() compares the public key components and paramters +(if present) of keys B and B. + +=head1 NOTES + +The main purpose of the functions EVP_PKEY_missing_parameters() and +EVP_PKEY_copy_parameters() is to handle public keys in certificates where the +parameters are sometimes omitted from a public key if they are inherited from +the CA that signed it. + +Since OpenSSL private keys contain public key components too the function +EVP_PKEY_cmp() can also be used to determine if a private key matches +a public key. + +=head1 RETURN VALUES + +The function EVP_PKEY_missing_parameters() returns 1 if the public key +parameters of B are missing and 0 if they are present or the algorithm +doesn't use parameters. + +These functions EVP_PKEY_copy_parameters() returns 1 for success and 0 for +failure. + +The function EVP_PKEY_cmp_parameters() and EVP_PKEY_cmp() return 1 if the +keys match, 0 if they don't match, -1 if the key types are different and +-2 if the operation is not supported. + +=head1 SEE ALSO + +L, +L + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_decrypt.pod b/crypto/openssl/doc/crypto/EVP_PKEY_decrypt.pod new file mode 100644 index 0000000000..42b2a8c44e --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_decrypt.pod @@ -0,0 +1,93 @@ +=pod + +=head1 NAME + +EVP_PKEY_decrypt_init, EVP_PKEY_decrypt - decrypt using a public key algorithm + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +=head1 DESCRIPTION + +The EVP_PKEY_decrypt_init() function initializes a public key algorithm +context using key B for a decryption operation. + +The EVP_PKEY_decrypt() function performs a public key decryption operation +using B. The data to be decrypted is specified using the B and +B parameters. If B is B then the maximum size of the output +buffer is written to the B parameter. If B is not B then +before the call the B parameter should contain the length of the +B buffer, if the call is successful the decrypted data is written to +B and the amount of data written to B. + +=head1 NOTES + +After the call to EVP_PKEY_decrypt_init() algorithm specific control +operations can be performed to set any appropriate parameters for the +operation. + +The function EVP_PKEY_decrypt() can be called more than once on the same +context if several operations are performed using the same parameters. + +=head1 RETURN VALUES + +EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0 +or a negative value for failure. In particular a return value of -2 +indicates the operation is not supported by the public key algorithm. + +=head1 EXAMPLE + +Decrypt data using OAEP (for RSA keys): + + #include + #include + + EVP_PKEY_CTX *ctx; + unsigned char *out, *in; + size_t outlen, inlen; + EVP_PKEY *key; + /* NB: assumes key in, inlen are already set up + * and that key is an RSA private key + */ + ctx = EVP_PKEY_CTX_new(key); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_decrypt_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0) + /* Error */ + + /* Determine buffer length */ + if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0) + /* Error */ + + out = OPENSSL_malloc(outlen); + + if (!out) + /* malloc failure */ + + if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0) + /* Error */ + + /* Decrypted data is outlen bytes written to buffer out */ + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_derive.pod b/crypto/openssl/doc/crypto/EVP_PKEY_derive.pod new file mode 100644 index 0000000000..d9d6d76c72 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_derive.pod @@ -0,0 +1,93 @@ +=pod + +=head1 NAME + +EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_derive - derive public key algorithm shared secret. + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); + int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +=head1 DESCRIPTION + +The EVP_PKEY_derive_init() function initializes a public key algorithm +context using key B for shared secret derivation. + +The EVP_PKEY_derive_set_peer() function sets the peer key: this will normally +be a public key. + +The EVP_PKEY_derive() derives a shared secret using B. +If B is B then the maximum size of the output buffer is written to +the B parameter. If B is not B then before the call the +B parameter should contain the length of the B buffer, if the call +is successful the shared secret is written to B and the amount of data +written to B. + +=head1 NOTES + +After the call to EVP_PKEY_derive_init() algorithm specific control +operations can be performed to set any appropriate parameters for the +operation. + +The function EVP_PKEY_derive() can be called more than once on the same +context if several operations are performed using the same parameters. + +=head1 RETURN VALUES + +EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0 +or a negative value for failure. In particular a return value of -2 +indicates the operation is not supported by the public key algorithm. + +=head1 EXAMPLE + +Derive shared secret (for example DH or EC keys): + + #include + #include + + EVP_PKEY_CTX *ctx; + unsigned char *skey; + size_t skeylen; + EVP_PKEY *pkey, *peerkey; + /* NB: assumes pkey, peerkey have been already set up */ + + ctx = EVP_PKEY_CTX_new(pkey); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_derive_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0) + /* Error */ + + /* Determine buffer length */ + if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0) + /* Error */ + + skey = OPENSSL_malloc(skeylen); + + if (!skey) + /* malloc failure */ + + if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0) + /* Error */ + + /* Shared secret is skey bytes written to buffer skey */ + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_encrypt.pod b/crypto/openssl/doc/crypto/EVP_PKEY_encrypt.pod new file mode 100644 index 0000000000..91c9c5d0a5 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_encrypt.pod @@ -0,0 +1,93 @@ +=pod + +=head1 NAME + +EVP_PKEY_encrypt_init, EVP_PKEY_encrypt - encrypt using a public key algorithm + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +=head1 DESCRIPTION + +The EVP_PKEY_encrypt_init() function initializes a public key algorithm +context using key B for an encryption operation. + +The EVP_PKEY_encrypt() function performs a public key encryption operation +using B. The data to be encrypted is specified using the B and +B parameters. If B is B then the maximum size of the output +buffer is written to the B parameter. If B is not B then +before the call the B parameter should contain the length of the +B buffer, if the call is successful the encrypted data is written to +B and the amount of data written to B. + +=head1 NOTES + +After the call to EVP_PKEY_encrypt_init() algorithm specific control +operations can be performed to set any appropriate parameters for the +operation. + +The function EVP_PKEY_encrypt() can be called more than once on the same +context if several operations are performed using the same parameters. + +=head1 RETURN VALUES + +EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0 +or a negative value for failure. In particular a return value of -2 +indicates the operation is not supported by the public key algorithm. + +=head1 EXAMPLE + +Encrypt data using OAEP (for RSA keys): + + #include + #include + + EVP_PKEY_CTX *ctx; + unsigned char *out, *in; + size_t outlen, inlen; + EVP_PKEY *key; + /* NB: assumes key in, inlen are already set up + * and that key is an RSA public key + */ + ctx = EVP_PKEY_CTX_new(key); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_encrypt_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0) + /* Error */ + + /* Determine buffer length */ + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0) + /* Error */ + + out = OPENSSL_malloc(outlen); + + if (!out) + /* malloc failure */ + + if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0) + /* Error */ + + /* Encrypted data is outlen bytes written to buffer out */ + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod b/crypto/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod new file mode 100644 index 0000000000..1a9c7954c5 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod @@ -0,0 +1,41 @@ +=pod + +=head1 NAME + +EVP_PKEY_get_default_digest_nid - get default signature digest + +=head1 SYNOPSIS + + #include + int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +=head1 DESCRIPTION + +The EVP_PKEY_get_default_digest_nid() function sets B to the default +message digest NID for the public key signature operations associated with key +B. + +=head1 NOTES + +For all current standard OpenSSL public key algorithms SHA1 is returned. + +=head1 RETURN VALUES + +The EVP_PKEY_get_default_digest_nid() function returns 1 if the message digest +is advisory (that is other digests can be used) and 2 if it is mandatory (other +digests can not be used). It returns 0 or a negative value for failure. In +particular a return value of -2 indicates the operation is not supported by the +public key algorithm. + +=head1 SEE ALSO + +L, +L, +L, +L, + +=head1 HISTORY + +This function was first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_keygen.pod b/crypto/openssl/doc/crypto/EVP_PKEY_keygen.pod new file mode 100644 index 0000000000..37c6fe9503 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_keygen.pod @@ -0,0 +1,161 @@ +=pod + +=head1 NAME + +EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init, EVP_PKEY_paramgen, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb, EVP_PKEY_CTX_get_keygen_info, EVP_PKEVP_PKEY_CTX_set_app_data, EVP_PKEY_CTX_get_app_data - key and parameter generation functions + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + + typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + + void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); + EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + + int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + + void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); + void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +=head1 DESCRIPTION + +The EVP_PKEY_keygen_init() function initializes a public key algorithm +context using key B for a key genration operation. + +The EVP_PKEY_keygen() function performs a key generation operation, the +generated key is written to B. + +The functions EVP_PKEY_paramgen_init() and EVP_PKEY_paramgen() are similar +except parameters are generated. + +The function EVP_PKEY_set_cb() sets the key or parameter generation callback +to B. The function EVP_PKEY_CTX_get_cb() returns the key or parameter +generation callback. + +The function EVP_PKEY_CTX_get_keygen_info() returns parameters associated +with the generation operation. If B is -1 the total number of +parameters available is returned. Any non negative value returns the value of +that parameter. EVP_PKEY_CTX_gen_keygen_info() with a non-negative value for +B should only be called within the generation callback. + +If the callback returns 0 then the key genration operation is aborted and an +error occurs. This might occur during a time consuming operation where +a user clicks on a "cancel" button. + +The functions EVP_PKEY_CTX_set_app_data() and EVP_PKEY_CTX_get_app_data() set +and retrieve an opaque pointer. This can be used to set some application +defined value which can be retrieved in the callback: for example a handle +which is used to update a "progress dialog". + +=head1 NOTES + +After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init() algorithm +specific control operations can be performed to set any appropriate parameters +for the operation. + +The functions EVP_PKEY_keygen() and EVP_PKEY_paramgen() can be called more than +once on the same context if several operations are performed using the same +parameters. + +The meaning of the parameters passed to the callback will depend on the +algorithm and the specifiic implementation of the algorithm. Some might not +give any useful information at all during key or parameter generation. Others +might not even call the callback. + +The operation performed by key or parameter generation depends on the algorithm +used. In some cases (e.g. EC with a supplied named curve) the "generation" +option merely sets the appropriate fields in an EVP_PKEY structure. + +In OpenSSL an EVP_PKEY structure containing a private key also contains the +public key components and parameters (if any). An OpenSSL private key is +equivalent to what some libraries call a "key pair". A private key can be used +in functions which require the use of a public key or parameters. + +=head1 RETURN VALUES + +EVP_PKEY_keygen_init(), EVP_PKEY_paramgen_init(), EVP_PKEY_keygen() and +EVP_PKEY_paramgen() return 1 for success and 0 or a negative value for failure. +In particular a return value of -2 indicates the operation is not supported by +the public key algorithm. + +=head1 EXAMPLES + +Generate a 2048 bit RSA key: + + #include + #include + + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_keygen_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) + /* Error */ + + /* Generate key */ + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + /* Error */ + +Generate a key from a set of parameters: + + #include + #include + + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL, *param; + /* Assumed param is set up already */ + ctx = EVP_PKEY_CTX_new(param); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_keygen_init(ctx) <= 0) + /* Error */ + + /* Generate key */ + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + /* Error */ + +Example of generation callback for OpenSSL public key implementations: + + /* Application data is a BIO to output status to */ + + EVP_PKEY_CTX_set_app_data(ctx, status_bio); + + static int genpkey_cb(EVP_PKEY_CTX *ctx) + { + char c='*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p; + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (p == 0) c='.'; + if (p == 1) c='+'; + if (p == 2) c='*'; + if (p == 3) c='\n'; + BIO_write(b,&c,1); + (void)BIO_flush(b); + return 1; + } + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_print_private.pod b/crypto/openssl/doc/crypto/EVP_PKEY_print_private.pod new file mode 100644 index 0000000000..ce9d70d7a7 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_print_private.pod @@ -0,0 +1,53 @@ +=pod + +=head1 NAME + +EVP_PKEY_print_public, EVP_PKEY_print_private, EVP_PKEY_print_params - public key algorithm printing routines. + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +=head1 DESCRIPTION + +The functions EVP_PKEY_print_public(), EVP_PKEY_print_private() and +EVP_PKEY_print_params() print out the public, private or parameter components +of key B respectively. The key is sent to BIO B in human readable +form. The parameter B indicated how far the printout should be indented. + +The B parameter allows the print output to be finely tuned by using +ASN1 printing options. If B is set to NULL then default values will +be used. + +=head1 NOTES + +Currently no public key algorithms include any options in the B parameter +parameter. + +If the key does not include all the components indicated by the function then +only those contained in the key will be printed. For example passing a public +key to EVP_PKEY_print_private() will only print the public components. + +=head1 RETURN VALUES + +These functions all return 1 for success and 0 or a negative value for failure. +In particular a return value of -2 indicates the operation is not supported by +the public key algorithm. + +=head1 SEE ALSO + +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_sign.pod b/crypto/openssl/doc/crypto/EVP_PKEY_sign.pod new file mode 100644 index 0000000000..2fb52c3486 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_sign.pod @@ -0,0 +1,96 @@ +=pod + +=head1 NAME + +EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + +=head1 DESCRIPTION + +The EVP_PKEY_sign_init() function initializes a public key algorithm +context using key B for a signing operation. + +The EVP_PKEY_sign() function performs a public key signing operation +using B. The data to be signed is specified using the B and +B parameters. If B is B then the maximum size of the output +buffer is written to the B parameter. If B is not B then +before the call the B parameter should contain the length of the +B buffer, if the call is successful the signature is written to +B and the amount of data written to B. + +=head1 NOTES + +After the call to EVP_PKEY_sign_init() algorithm specific control +operations can be performed to set any appropriate parameters for the +operation. + +The function EVP_PKEY_sign() can be called more than once on the same +context if several operations are performed using the same parameters. + +=head1 RETURN VALUES + +EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0 +or a negative value for failure. In particular a return value of -2 +indicates the operation is not supported by the public key algorithm. + +=head1 EXAMPLE + +Sign data using RSA with PKCS#1 padding and SHA256 digest: + + #include + #include + + EVP_PKEY_CTX *ctx; + unsigned char *md, *sig; + size_t mdlen, siglen; + EVP_PKEY *signing_key; + /* NB: assumes signing_key, md and mdlen are already set up + * and that signing_key is an RSA private key + */ + ctx = EVP_PKEY_CTX_new(signing_key); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_sign_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + /* Error */ + + /* Determine buffer length */ + if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0) + /* Error */ + + sig = OPENSSL_malloc(siglen); + + if (!sig) + /* malloc failure */ + + if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0) + /* Error */ + + /* Signature is siglen bytes written to buffer sig */ + + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_verify.pod b/crypto/openssl/doc/crypto/EVP_PKEY_verify.pod new file mode 100644 index 0000000000..10633da3f2 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_verify.pod @@ -0,0 +1,91 @@ +=pod + +=head1 NAME + +EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public key algorithm + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + +=head1 DESCRIPTION + +The EVP_PKEY_verify_init() function initializes a public key algorithm +context using key B for a signature verification operation. + +The EVP_PKEY_verify() function performs a public key verification operation +using B. The signature is specified using the B and +B parameters. The verified data (i.e. the data believed originally +signed) is specified using the B and B parameters. + +=head1 NOTES + +After the call to EVP_PKEY_verify_init() algorithm specific control +operations can be performed to set any appropriate parameters for the +operation. + +The function EVP_PKEY_verify() can be called more than once on the same +context if several operations are performed using the same parameters. + +=head1 RETURN VALUES + +EVP_PKEY_verify_init() and EVP_PKEY_verify() return 1 if the verification was +successful and 0 if it failed. Unlike other functions the return value 0 from +EVP_PKEY_verify() only indicates that the signature did not not verify +successfully (that is tbs did not match the original data or the signature was +of invalid form) it is not an indication of a more serious error. + +A negative value indicates an error other that signature verification failure. +In particular a return value of -2 indicates the operation is not supported by +the public key algorithm. + +=head1 EXAMPLE + +Verify signature using PKCS#1 and SHA256 digest: + + #include + #include + + EVP_PKEY_CTX *ctx; + unsigned char *md, *sig; + size_t mdlen, siglen; + EVP_PKEY *verify_key; + /* NB: assumes verify_key, sig, siglen md and mdlen are already set up + * and that verify_key is an RSA public key + */ + ctx = EVP_PKEY_CTX_new(verify_key); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_verify_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + /* Error */ + + /* Perform operation */ + ret = EVP_PKEY_verify(ctx, md, mdlen, sig, siglen); + + /* ret == 1 indicates success, 0 verify failure and < 0 for some + * other error. + */ + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod b/crypto/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod new file mode 100644 index 0000000000..e2a2a8c6f8 --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod @@ -0,0 +1,103 @@ +=pod + +=head1 NAME + +EVP_PKEY_verifyrecover_init, EVP_PKEY_verifyrecover - recover signature using a public key algorithm + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_verifyrecover_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_verifyrecover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + +=head1 DESCRIPTION + +The EVP_PKEY_verifyrecover_init() function initializes a public key algorithm +context using key B for a verify recover operation. + +The EVP_PKEY_verifyrecover() function recovers signed data +using B. The signature is specified using the B and +B parameters. If B is B then the maximum size of the output +buffer is written to the B parameter. If B is not B then +before the call the B parameter should contain the length of the +B buffer, if the call is successful recovered data is written to +B and the amount of data written to B. + +=head1 NOTES + +Normally an application is only interested in whether a signature verification +operation is successful in those cases the EVP_verify() function should be +used. + +Sometimes however it is useful to obtain the data originally signed using a +signing operation. Only certain public key algorithms can recover a signature +in this way (for example RSA in PKCS padding mode). + +After the call to EVP_PKEY_verifyrecover_init() algorithm specific control +operations can be performed to set any appropriate parameters for the +operation. + +The function EVP_PKEY_verifyrecover() can be called more than once on the same +context if several operations are performed using the same parameters. + +=head1 RETURN VALUES + +EVP_PKEY_verifyrecover_init() and EVP_PKEY_verifyrecover() return 1 for success +and 0 or a negative value for failure. In particular a return value of -2 +indicates the operation is not supported by the public key algorithm. + +=head1 EXAMPLE + +Recover digest originally signed using PKCS#1 and SHA256 digest: + + #include + #include + + EVP_PKEY_CTX *ctx; + unsigned char *rout, *sig; + size_t routlen, siglen; + EVP_PKEY *verify_key; + /* NB: assumes verify_key, sig and siglen are already set up + * and that verify_key is an RSA public key + */ + ctx = EVP_PKEY_CTX_new(verify_key); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_verifyrecover_init(ctx) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + /* Error */ + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + /* Error */ + + /* Determine buffer length */ + if (EVP_PKEY_verifyrecover(ctx, rout, &routlen, sig, siglen) <= 0) + /* Error */ + + rout = OPENSSL_malloc(routlen); + + if (!rout) + /* malloc failure */ + + if (EVP_PKEY_verifyrecover(ctx, rout, &routlen, sig, siglen) <= 0) + /* Error */ + + /* Recovered data is routlen bytes written to buffer rout */ + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/EVP_SignInit.pod b/crypto/openssl/doc/crypto/EVP_SignInit.pod index b6e62ce7f6..620a623ab6 100644 --- a/crypto/openssl/doc/crypto/EVP_SignInit.pod +++ b/crypto/openssl/doc/crypto/EVP_SignInit.pod @@ -77,6 +77,15 @@ will occur. Older versions of this documentation wrongly stated that calls to EVP_SignUpdate() could not be made after calling EVP_SignFinal(). +Since the private key is passed in the call to EVP_SignFinal() any error +relating to the private key (for example an unsuitable key and digest +combination) will not be indicated until after potentially large amounts of +data have been passed through EVP_SignUpdate(). + +It is not possible to change the signing parameters using these function. + +The previous two bugs are fixed in the newer EVP_SignDigest*() function. + =head1 SEE ALSO L, diff --git a/crypto/openssl/doc/crypto/EVP_VerifyInit.pod b/crypto/openssl/doc/crypto/EVP_VerifyInit.pod index b6afaedee5..9097f09410 100644 --- a/crypto/openssl/doc/crypto/EVP_VerifyInit.pod +++ b/crypto/openssl/doc/crypto/EVP_VerifyInit.pod @@ -67,6 +67,15 @@ will occur. Older versions of this documentation wrongly stated that calls to EVP_VerifyUpdate() could not be made after calling EVP_VerifyFinal(). +Since the public key is passed in the call to EVP_SignFinal() any error +relating to the private key (for example an unsuitable key and digest +combination) will not be indicated until after potentially large amounts of +data have been passed through EVP_SignUpdate(). + +It is not possible to change the signing parameters using these function. + +The previous two bugs are fixed in the newer EVP_VerifyDigest*() function. + =head1 SEE ALSO L, diff --git a/crypto/openssl/doc/crypto/OBJ_nid2obj.pod b/crypto/openssl/doc/crypto/OBJ_nid2obj.pod index 7dcc07923f..1e45dd40f6 100644 --- a/crypto/openssl/doc/crypto/OBJ_nid2obj.pod +++ b/crypto/openssl/doc/crypto/OBJ_nid2obj.pod @@ -8,6 +8,8 @@ functions =head1 SYNOPSIS + #include + ASN1_OBJECT * OBJ_nid2obj(int n); const char * OBJ_nid2ln(int n); const char * OBJ_nid2sn(int n); diff --git a/crypto/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod b/crypto/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod new file mode 100644 index 0000000000..e070c45c2e --- /dev/null +++ b/crypto/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod @@ -0,0 +1,41 @@ +=pod + +=head1 NAME + + PEM_write_bio_CMS_stream - output CMS_ContentInfo structure in PEM format. + +=head1 SYNOPSIS + + #include + #include + + int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); + +=head1 DESCRIPTION + +PEM_write_bio_CMS_stream() outputs a CMS_ContentInfo structure in PEM format. + +It is otherwise identical to the function SMIME_write_CMS(). + +=head1 NOTES + +This function is effectively a version of the PEM_write_bio_CMS() supporting +streaming. + +=head1 RETURN VALUES + +PEM_write_bio_CMS_stream() returns 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, +L, L +L, +L, +L + +=head1 HISTORY + +PEM_write_bio_CMS_stream() was added to OpenSSL 1.0.0 + +=cut diff --git a/crypto/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod b/crypto/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod new file mode 100644 index 0000000000..16fc9b6845 --- /dev/null +++ b/crypto/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod @@ -0,0 +1,41 @@ +=pod + +=head1 NAME + +PEM_write_bio_PKCS7_stream - output PKCS7 structure in PEM format. + +=head1 SYNOPSIS + + #include + #include + + int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *data, int flags); + +=head1 DESCRIPTION + +PEM_write_bio_PKCS7_stream() outputs a PKCS7 structure in PEM format. + +It is otherwise identical to the function SMIME_write_PKCS7(). + +=head1 NOTES + +This function is effectively a version of the PEM_write_bio_PKCS7() supporting +streaming. + +=head1 RETURN VALUES + +PEM_write_bio_PKCS7_stream() returns 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, +L, L +L, +L, +L + +=head1 HISTORY + +PEM_write_bio_PKCS7_stream() was added to OpenSSL 1.0.0 + +=cut diff --git a/crypto/openssl/doc/crypto/PKCS7_decrypt.pod b/crypto/openssl/doc/crypto/PKCS7_decrypt.pod index b0ca067b89..325699d0b6 100644 --- a/crypto/openssl/doc/crypto/PKCS7_decrypt.pod +++ b/crypto/openssl/doc/crypto/PKCS7_decrypt.pod @@ -6,7 +6,9 @@ PKCS7_decrypt - decrypt content from a PKCS#7 envelopedData structure =head1 SYNOPSIS -int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); + #include + + int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/PKCS7_encrypt.pod b/crypto/openssl/doc/crypto/PKCS7_encrypt.pod index 1a507b22a2..2cd925a7e0 100644 --- a/crypto/openssl/doc/crypto/PKCS7_encrypt.pod +++ b/crypto/openssl/doc/crypto/PKCS7_encrypt.pod @@ -6,7 +6,9 @@ PKCS7_encrypt - create a PKCS#7 envelopedData structure =head1 SYNOPSIS -PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); + #include + + PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); =head1 DESCRIPTION @@ -16,43 +18,55 @@ B is the symmetric cipher to use. B is an optional set of flags. =head1 NOTES -Only RSA keys are supported in PKCS#7 and envelopedData so the recipient certificates -supplied to this function must all contain RSA public keys, though they do not have to -be signed using the RSA algorithm. +Only RSA keys are supported in PKCS#7 and envelopedData so the recipient +certificates supplied to this function must all contain RSA public keys, though +they do not have to be signed using the RSA algorithm. -EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use because -most clients will support it. +EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use +because most clients will support it. -Some old "export grade" clients may only support weak encryption using 40 or 64 bit -RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() respectively. +Some old "export grade" clients may only support weak encryption using 40 or 64 +bit RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() +respectively. -The algorithm passed in the B parameter must support ASN1 encoding of its -parameters. +The algorithm passed in the B parameter must support ASN1 encoding of +its parameters. -Many browsers implement a "sign and encrypt" option which is simply an S/MIME +Many browsers implement a "sign and encrypt" option which is simply an S/MIME envelopedData containing an S/MIME signed message. This can be readily produced by storing the S/MIME signed message in a memory BIO and passing it to PKCS7_encrypt(). The following flags can be passed in the B parameter. -If the B flag is set MIME headers for type B are prepended -to the data. +If the B flag is set MIME headers for type B are +prepended to the data. -Normally the supplied content is translated into MIME canonical format (as required -by the S/MIME specifications) if B is set no translation occurs. This -option should be used if the supplied data is in binary format otherwise the translation -will corrupt it. If B is set then B is ignored. +Normally the supplied content is translated into MIME canonical format (as +required by the S/MIME specifications) if B is set no translation +occurs. This option should be used if the supplied data is in binary format +otherwise the translation will corrupt it. If B is set then +B is ignored. -=head1 RETURN VALUES +If the B flag is set a partial B structure is output +suitable for streaming I/O: no data is read from the BIO B. -PKCS7_encrypt() returns either a valid PKCS7 structure or NULL if an error occurred. -The error can be obtained from ERR_get_error(3). +=head1 NOTES -=head1 BUGS +If the flag B is set the returned B structure is B +complete and outputting its contents via a function that does not +properly finalize the B structure will give unpredictable +results. -The lack of single pass processing and need to hold all data in memory as -mentioned in PKCS7_sign() also applies to PKCS7_verify(). +Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(), +PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization +can be performed by obtaining the streaming ASN1 B directly using +BIO_new_PKCS7(). + +=head1 RETURN VALUES + +PKCS7_encrypt() returns either a PKCS7 structure or NULL if an error occurred. +The error can be obtained from ERR_get_error(3). =head1 SEE ALSO @@ -61,5 +75,6 @@ L, L =head1 HISTORY PKCS7_decrypt() was added to OpenSSL 0.9.5 +The B flag was first supported in OpenSSL 1.0.0. =cut diff --git a/crypto/openssl/doc/crypto/PKCS7_sign.pod b/crypto/openssl/doc/crypto/PKCS7_sign.pod index ffd0c734b0..64a35144f8 100644 --- a/crypto/openssl/doc/crypto/PKCS7_sign.pod +++ b/crypto/openssl/doc/crypto/PKCS7_sign.pod @@ -6,14 +6,16 @@ PKCS7_sign - create a PKCS#7 signedData structure =head1 SYNOPSIS -PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); + #include + + PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); =head1 DESCRIPTION -PKCS7_sign() creates and returns a PKCS#7 signedData structure. B -is the certificate to sign with, B is the corresponsding private key. -B is an optional additional set of certificates to include in the -PKCS#7 structure (for example any intermediate CAs in the chain). +PKCS7_sign() creates and returns a PKCS#7 signedData structure. B is +the certificate to sign with, B is the corresponsding private key. +B is an optional additional set of certificates to include in the PKCS#7 +structure (for example any intermediate CAs in the chain). The data to be signed is read from BIO B. @@ -21,72 +23,83 @@ B is an optional set of flags. =head1 NOTES -Any of the following flags (ored together) can be passed in the B parameter. +Any of the following flags (ored together) can be passed in the B +parameter. Many S/MIME clients expect the signed content to include valid MIME headers. If the B flag is set MIME headers for type B are prepended to the data. If B is set the signer's certificate will not be included in the -PKCS7 structure, the signer's certificate must still be supplied in the B -parameter though. This can reduce the size of the signature if the signers certificate -can be obtained by other means: for example a previously signed message. - -The data being signed is included in the PKCS7 structure, unless B -is set in which case it is omitted. This is used for PKCS7 detached signatures -which are used in S/MIME plaintext signed messages for example. +PKCS7 structure, the signer's certificate must still be supplied in the +B parameter though. This can reduce the size of the signature if the +signers certificate can be obtained by other means: for example a previously +signed message. + +The data being signed is included in the PKCS7 structure, unless +B is set in which case it is omitted. This is used for PKCS7 +detached signatures which are used in S/MIME plaintext signed messages for +example. + +Normally the supplied content is translated into MIME canonical format (as +required by the S/MIME specifications) if B is set no translation +occurs. This option should be used if the supplied data is in binary format +otherwise the translation will corrupt it. + +The signedData structure includes several PKCS#7 autenticatedAttributes +including the signing time, the PKCS#7 content type and the supported list of +ciphers in an SMIMECapabilities attribute. If B is set then no +authenticatedAttributes will be used. If B is set then just +the SMIMECapabilities are omitted. -Normally the supplied content is translated into MIME canonical format (as required -by the S/MIME specifications) if B is set no translation occurs. This -option should be used if the supplied data is in binary format otherwise the translation -will corrupt it. +If present the SMIMECapabilities attribute indicates support for the following +algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of +these algorithms is disabled then it will not be included. -The signedData structure includes several PKCS#7 autenticatedAttributes including -the signing time, the PKCS#7 content type and the supported list of ciphers in -an SMIMECapabilities attribute. If B is set then no authenticatedAttributes -will be used. If B is set then just the SMIMECapabilities are -omitted. +If the flags B is set then the returned B structure is +just initialized ready to perform the signing operation. The signing is however +B performed and the data to be signed is not read from the B +parameter. Signing is deferred until after the data has been written. In this +way data can be signed in a single pass. -If present the SMIMECapabilities attribute indicates support for the following -algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any -of these algorithms is disabled then it will not be included. +If the B flag is set a partial B structure is output to +which additional signers and capabilities can be added before finalization. -If the flags B is set then the returned B structure -is just initialized ready to perform the signing operation. The signing -is however B performed and the data to be signed is not read from -the B parameter. Signing is deferred until after the data has been -written. In this way data can be signed in a single pass. Currently the -flag B B also be set. =head1 NOTES -Currently the flag B is only supported for detached -data. If this flag is set the returned B structure is B -complete and outputting its contents via a function that does not -properly finalize the B structure will give unpredictable -results. +If the flag B is set the returned B structure is B +complete and outputting its contents via a function that does not properly +finalize the B structure will give unpredictable results. -At present only the SMIME_write_PKCS7() function properly finalizes the -structure. +Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(), +PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization +can be performed by obtaining the streaming ASN1 B directly using +BIO_new_PKCS7(). -=head1 BUGS +If a signer is specified it will use the default digest for the signing +algorithm. This is B for both RSA and DSA keys. + +In OpenSSL 1.0.0 the B, B and B parameters can all be +B if the B flag is set. One or more signers can be added +using the function B. B must also be +called to finalize the structure if streaming is not enabled. Alternative +signing digests can also be specified using this method. -PKCS7_sign() is somewhat limited. It does not support multiple signers, some -advanced attributes such as counter signatures are not supported. +In OpenSSL 1.0.0 if B and B are NULL then a certificates only +PKCS#7 structure is output. -The SHA1 digest algorithm is currently always used. +In versions of OpenSSL before 1.0.0 the B and B parameters must +B be NULL. -When the signed data is not detached it will be stored in memory within the -B structure. This effectively limits the size of messages which can be -signed due to memory restraints. There should be a way to sign data without -having to hold it all in memory, this would however require fairly major -revisions of the OpenSSL ASN1 code. +=head1 BUGS +Some advanced attributes such as counter signatures are not supported. =head1 RETURN VALUES -PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error occurred. -The error can be obtained from ERR_get_error(3). +PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error +occurred. The error can be obtained from ERR_get_error(3). =head1 SEE ALSO @@ -96,6 +109,8 @@ L, L PKCS7_sign() was added to OpenSSL 0.9.5 -The B flag was added in OpenSSL 0.9.8 +The B flag was added in OpenSSL 1.0.0 + +The B flag was added in OpenSSL 1.0.0 =cut diff --git a/crypto/openssl/doc/crypto/PKCS7_sign_add_signer.pod b/crypto/openssl/doc/crypto/PKCS7_sign_add_signer.pod new file mode 100644 index 0000000000..ebec4d57de --- /dev/null +++ b/crypto/openssl/doc/crypto/PKCS7_sign_add_signer.pod @@ -0,0 +1,87 @@ +=pod + +=head1 NAME + +PKCS7_sign_add_signer - add a signer PKCS7 signed data structure. + +=head1 SYNOPSIS + + #include + + PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, int flags); + + +=head1 DESCRIPTION + +PKCS7_sign_add_signer() adds a signer with certificate B and private +key B using message digest B to a PKCS7 signed data structure +B. + +The PKCS7 structure should be obtained from an initial call to PKCS7_sign() +with the flag B set or in the case or re-signing a valid PKCS7 +signed data structure. + +If the B parameter is B then the default digest for the public +key algorithm will be used. + +Unless the B flag is set the returned PKCS7 structure +is not complete and must be finalized either by streaming (if applicable) or +a call to PKCS7_final(). + + +=head1 NOTES + +The main purpose of this function is to provide finer control over a PKCS#7 +signed data structure where the simpler PKCS7_sign() function defaults are +not appropriate. For example if multiple signers or non default digest +algorithms are needed. + +Any of the following flags (ored together) can be passed in the B +parameter. + +If B is set then an attempt is made to copy the content +digest value from the PKCS7 struture: to add a signer to an existing structure. +An error occurs if a matching digest value cannot be found to copy. The +returned PKCS7 structure will be valid and finalized when this flag is set. + +If B is set in addition to B then the +B structure will not be finalized so additional attributes +can be added. In this case an explicit call to PKCS7_SIGNER_INFO_sign() is +needed to finalize it. + +If B is set the signer's certificate will not be included in the +PKCS7 structure, the signer's certificate must still be supplied in the +B parameter though. This can reduce the size of the signature if the +signers certificate can be obtained by other means: for example a previously +signed message. + +The signedData structure includes several PKCS#7 autenticatedAttributes +including the signing time, the PKCS#7 content type and the supported list of +ciphers in an SMIMECapabilities attribute. If B is set then no +authenticatedAttributes will be used. If B is set then just +the SMIMECapabilities are omitted. + +If present the SMIMECapabilities attribute indicates support for the following +algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of +these algorithms is disabled then it will not be included. + + +PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO +structure just added, this can be used to set additional attributes +before it is finalized. + +=head1 RETURN VALUES + +PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO +structure just added or NULL if an error occurs. + +=head1 SEE ALSO + +L, L, +L, + +=head1 HISTORY + +PPKCS7_sign_add_signer() was added to OpenSSL 1.0.0 + +=cut diff --git a/crypto/openssl/doc/crypto/PKCS7_verify.pod b/crypto/openssl/doc/crypto/PKCS7_verify.pod index 3490b5dc82..7c10a4cc3c 100644 --- a/crypto/openssl/doc/crypto/PKCS7_verify.pod +++ b/crypto/openssl/doc/crypto/PKCS7_verify.pod @@ -6,9 +6,11 @@ PKCS7_verify - verify a PKCS#7 signedData structure =head1 SYNOPSIS -int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); + #include -STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); + int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); + + STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/SMIME_read_CMS.pod b/crypto/openssl/doc/crypto/SMIME_read_CMS.pod new file mode 100644 index 0000000000..acc5524c14 --- /dev/null +++ b/crypto/openssl/doc/crypto/SMIME_read_CMS.pod @@ -0,0 +1,70 @@ +=pod + +=head1 NAME + + SMIME_read_CMS - parse S/MIME message. + +=head1 SYNOPSIS + + #include + + CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont); + +=head1 DESCRIPTION + +SMIME_read_CMS() parses a message in S/MIME format. + +B is a BIO to read the message from. + +If cleartext signing is used then the content is saved in a memory bio which is +written to B<*bcont>, otherwise B<*bcont> is set to NULL. + +The parsed CMS_ContentInfo structure is returned or NULL if an +error occurred. + +=head1 NOTES + +If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can +then be passed to CMS_verify() with the B flag set. + +Otherwise the type of the returned structure can be determined +using CMS_get0_type(). + +To support future functionality if B is not NULL B<*bcont> should be +initialized to NULL. For example: + + BIO *cont = NULL; + CMS_ContentInfo *cms; + + cms = SMIME_read_CMS(in, &cont); + +=head1 BUGS + +The MIME parser used by SMIME_read_CMS() is somewhat primitive. While it will +handle most S/MIME messages more complex compound formats may not work. + +The parser assumes that the CMS_ContentInfo structure is always base64 encoded +and will not handle the case where it is in binary format or uses quoted +printable format. + +The use of a memory BIO to hold the signed content limits the size of message +which can be processed due to memory restraints: a streaming single pass option +should be available. + +=head1 RETURN VALUES + +SMIME_read_CMS() returns a valid B structure or B +if an error occurred. The error can be obtained from ERR_get_error(3). + +=head1 SEE ALSO + +L, L +L, L, +L, L +L + +=head1 HISTORY + +SMIME_read_CMS() was added to OpenSSL 0.9.8 + +=cut diff --git a/crypto/openssl/doc/crypto/SMIME_read_PKCS7.pod b/crypto/openssl/doc/crypto/SMIME_read_PKCS7.pod index ffafa37887..9d46715941 100644 --- a/crypto/openssl/doc/crypto/SMIME_read_PKCS7.pod +++ b/crypto/openssl/doc/crypto/SMIME_read_PKCS7.pod @@ -6,7 +6,9 @@ SMIME_read_PKCS7 - parse S/MIME message. =head1 SYNOPSIS -PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont); + #include + + PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/SMIME_write_CMS.pod b/crypto/openssl/doc/crypto/SMIME_write_CMS.pod new file mode 100644 index 0000000000..04bedfb429 --- /dev/null +++ b/crypto/openssl/doc/crypto/SMIME_write_CMS.pod @@ -0,0 +1,64 @@ +=pod + +=head1 NAME + + SMIME_write_CMS - convert CMS structure to S/MIME format. + +=head1 SYNOPSIS + + #include + + int SMIME_write_CMS(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); + +=head1 DESCRIPTION + +SMIME_write_CMS() adds the appropriate MIME headers to a CMS +structure to produce an S/MIME message. + +B is the BIO to write the data to. B is the appropriate +B structure. If streaming is enabled then the content must be +supplied in the B argument. B is an optional set of flags. + +=head1 NOTES + +The following flags can be passed in the B parameter. + +If B is set then cleartext signing will be used, this option only +makes sense for SignedData where B is also set when CMS_sign() is +called. + +If the B flag is set MIME headers for type B are added to +the content, this only makes sense if B is also set. + +If the B flag is set streaming is performed. This flag should only +be set if B was also set in the previous call to a CMS_ContentInfo +creation function. + +If cleartext signing is being used and B not set then the data must +be read twice: once to compute the signature in CMS_sign() and once to output +the S/MIME message. + +If streaming is performed the content is output in BER format using indefinite +length constructed encoding except in the case of signed data with detached +content where the content is absent and DER format is used. + +=head1 BUGS + +SMIME_write_CMS() always base64 encodes CMS structures, there should be an +option to disable this. + +=head1 RETURN VALUES + +SMIME_write_CMS() returns 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, +L, L +L + +=head1 HISTORY + +SMIME_write_CMS() was added to OpenSSL 0.9.8 + +=cut diff --git a/crypto/openssl/doc/crypto/SMIME_write_PKCS7.pod b/crypto/openssl/doc/crypto/SMIME_write_PKCS7.pod index 61945b3887..ca6bd02763 100644 --- a/crypto/openssl/doc/crypto/SMIME_write_PKCS7.pod +++ b/crypto/openssl/doc/crypto/SMIME_write_PKCS7.pod @@ -6,17 +6,18 @@ SMIME_write_PKCS7 - convert PKCS#7 structure to S/MIME format. =head1 SYNOPSIS -int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags); + #include + + int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags); =head1 DESCRIPTION SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7 structure to produce an S/MIME message. -B is the BIO to write the data to. B is the appropriate -B structure. If cleartext signing (B) is -being used then the signed data must be supplied in the B -argument. B is an optional set of flags. +B is the BIO to write the data to. B is the appropriate B +structure. If streaming is enabled then the content must be supplied in the +B argument. B is an optional set of flags. =head1 NOTES @@ -30,15 +31,18 @@ If the B flag is set MIME headers for type B are added to the content, this only makes sense if B is also set. -If the B flag is set the signed data is finalized -and output along with the content. This flag should only be set -if B is also set and the previous call to PKCS7_sign() -also set these flags. +If the B flag is set streaming is performed. This flag should +only be set if B was also set in the previous call to +PKCS7_sign() or B. -If cleartext signing is being used and B not set then +If cleartext signing is being used and B not set then the data must be read twice: once to compute the signature in PKCS7_sign() and once to output the S/MIME message. +If streaming is performed the content is output in BER format using indefinite +length constructuted encoding except in the case of signed data with detached +content where the content is absent and DER format is used. + =head1 BUGS SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there diff --git a/crypto/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod b/crypto/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod index 11b35f6fd3..41902c0d45 100644 --- a/crypto/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod +++ b/crypto/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod @@ -9,15 +9,17 @@ X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions =head1 SYNOPSIS -ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); -ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + #include -int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); -int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len); + ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); + ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); + int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); + int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len); + + X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len); + X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len); + X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod b/crypto/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod index e2ab4b0d2b..1afd008cb3 100644 --- a/crypto/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod +++ b/crypto/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod @@ -7,15 +7,17 @@ X509_NAME_add_entry, X509_NAME_delete_entry - X509_NAME modification functions =head1 SYNOPSIS -int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set); + #include -int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set); + int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set); -int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set); + int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set); -int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set); + int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set); -X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); + int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set); + + X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod b/crypto/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod index 333323d734..3b1f9ff43b 100644 --- a/crypto/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod +++ b/crypto/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod @@ -8,14 +8,16 @@ X509_NAME lookup and enumeration functions =head1 SYNOPSIS -int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); -int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos); + #include -int X509_NAME_entry_count(X509_NAME *name); -X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); + int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); + int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos); -int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len); -int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len); + int X509_NAME_entry_count(X509_NAME *name); + X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); + + int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len); + int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/X509_STORE_CTX_get_error.pod b/crypto/openssl/doc/crypto/X509_STORE_CTX_get_error.pod new file mode 100644 index 0000000000..a883f6c097 --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_STORE_CTX_get_error.pod @@ -0,0 +1,303 @@ +=pod + +=head1 NAME + +X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information + +=head1 SYNOPSIS + + #include + #include + + int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); + void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); + int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); + X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); + + STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); + + const char *X509_verify_cert_error_string(long n); + +=head1 DESCRIPTION + +These functions are typically called after X509_verify_cert() has indicated +an error or in a verification callback to determine the nature of an error. + +X509_STORE_CTX_get_error() returns the error code of B, see +the B section for a full description of all error codes. + +X509_STORE_CTX_set_error() sets the error code of B to B. For example +it might be used in a verification callback to set an error based on additional +checks. + +X509_STORE_CTX_get_error_depth() returns the B of the error. This is a +non-negative integer representing where in the certificate chain the error +occurred. If it is zero it occured in the end entity certificate, one if +it is the certificate which signed the end entity certificate and so on. + +X509_STORE_CTX_get_current_cert() returns the certificate in B which +caused the error or B if no certificate is relevant. + +X509_STORE_CTX_get1_chain() returns a complete validate chain if a previous +call to X509_verify_cert() is successful. If the call to X509_verify_cert() +is B successful the returned chain may be incomplete or invalid. The +returned chain persists after the B structure is freed, when it is +no longer needed it should be free up using: + + sk_X509_pop_free(chain, X509_free); + +X509_verify_cert_error_string() returns a human readable error string for +verification error B. + +=head1 RETURN VALUES + +X509_STORE_CTX_get_error() returns B or an error code. + +X509_STORE_CTX_get_error_depth() returns a non-negative error depth. + +X509_STORE_CTX_get_current_cert() returns the cerificate which caused the +error or B if no certificate is relevant to the error. + +X509_verify_cert_error_string() returns a human readable error string for +verification error B. + +=head1 ERROR CODES + +A list of error codes and messages is shown below. Some of the +error codes are defined but currently never returned: these are described as +"unused". + +=over 4 + +=item B + +the operation was successful. + +=item B + +the issuer certificate could not be found: this occurs if the issuer certificate +of an untrusted certificate cannot be found. + +=item B + +the CRL of a certificate could not be found. + +=item B + +the certificate signature could not be decrypted. This means that the actual +signature value could not be determined rather than it not matching the +expected value, this is only meaningful for RSA keys. + +=item B + +the CRL signature could not be decrypted: this means that the actual signature +value could not be determined rather than it not matching the expected value. +Unused. + +=item B + +the public key in the certificate SubjectPublicKeyInfo could not be read. + +=item B + +the signature of the certificate is invalid. + +=item B + +the signature of the certificate is invalid. + +=item B + +the certificate is not yet valid: the notBefore date is after the current time. + +=item B + +the certificate has expired: that is the notAfter date is before the current time. + +=item B + +the CRL is not yet valid. + +=item B + +the CRL has expired. + +=item B + +the certificate notBefore field contains an invalid time. + +=item B + +the certificate notAfter field contains an invalid time. + +=item B + +the CRL lastUpdate field contains an invalid time. + +=item B + +the CRL nextUpdate field contains an invalid time. + +=item B + +an error occurred trying to allocate memory. This should never happen. + +=item B + +the passed certificate is self signed and the same certificate cannot be found +in the list of trusted certificates. + +=item B + +the certificate chain could be built up using the untrusted certificates but +the root could not be found locally. + +=item B + +the issuer certificate of a locally looked up certificate could not be found. +This normally means the list of trusted certificates is not complete. + +=item B + +no signatures could be verified because the chain contains only one certificate +and it is not self signed. + +=item B + +the certificate chain length is greater than the supplied maximum depth. Unused. + +=item B + +the certificate has been revoked. + +=item B + +a CA certificate is invalid. Either it is not a CA or its extensions are not +consistent with the supplied purpose. + +=item B + +the basicConstraints pathlength parameter has been exceeded. + +=item B + +the supplied certificate cannot be used for the specified purpose. + +=item B + +the root CA is not marked as trusted for the specified purpose. + +=item B + +the root CA is marked to reject the specified purpose. + +=item B + +the current candidate issuer certificate was rejected because its subject name +did not match the issuer name of the current certificate. This is only set +if issuer check debugging is enabled it is used for status notification and +is B in itself an error. + +=item B + +the current candidate issuer certificate was rejected because its subject key +identifier was present and did not match the authority key identifier current +certificate. This is only set if issuer check debugging is enabled it is used +for status notification and is B in itself an error. + +=item B + +the current candidate issuer certificate was rejected because its issuer name +and serial number was present and did not match the authority key identifier of +the current certificate. This is only set if issuer check debugging is enabled +it is used for status notification and is B in itself an error. + +=item B + +the current candidate issuer certificate was rejected because its keyUsage +extension does not permit certificate signing. This is only set if issuer check +debugging is enabled it is used for status notification and is B in itself +an error. + +=item B + +A certificate extension had an invalid value (for example an incorrect +encoding) or some value inconsistent with other extensions. + + +=item B + +A certificate policies extension had an invalid value (for example an incorrect +encoding) or some value inconsistent with other extensions. This error only +occurs if policy processing is enabled. + +=item B + +The verification flags were set to require and explicit policy but none was +present. + +=item B + +The only CRLs that could be found did not match the scope of the certificate. + +=item B + +Some feature of a certificate extension is not supported. Unused. + +=item B + +A name constraint violation occured in the permitted subtrees. + +=item B + +A name constraint violation occured in the excluded subtrees. + +=item B + +A certificate name constraints extension included a minimum or maximum field: +this is not supported. + +=item B + +An unsupported name constraint type was encountered. OpenSSL currently only +supports directory name, DNS name, email and URI types. + +=item B + +The format of the name constraint is not recognised: for example an email +address format of a form not mentioned in RFC3280. This could be caused by +a garbage extension or some new feature not currently supported. + +=item B + +An error occured when attempting to verify the CRL path. This error can only +happen if extended CRL checking is enabled. + +=item B + +an application specific error. This will never be returned unless explicitly +set by an application. + +=head1 NOTES + +The above functions should be used instead of directly referencing the fields +in the B structure. + +In versions of OpenSSL before 1.0 the current certificate returned by +X509_STORE_CTX_get_current_cert() was never B. Applications should +check the return value before printing out any debugging information relating +to the current certificate. + +If an unrecognised error code is passed to X509_verify_cert_error_string() the +numerical value of the unknown code is returned in a static buffer. This is not +thread safe but will never happen unless an invalid code is passed. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/crypto/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod b/crypto/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod new file mode 100644 index 0000000000..8d6b9dda47 --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod @@ -0,0 +1,41 @@ +=pod + +=head1 NAME + +X509_STORE_CTX_get_ex_new_index, X509_STORE_CTX_set_ex_data, X509_STORE_CTX_get_ex_data - add application specific data to X509_STORE_CTX structures + +=head1 SYNOPSIS + + #include + + int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + + int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *d, int idx, void *arg); + + char *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *d, int idx); + +=head1 DESCRIPTION + +These functions handle application specific data in X509_STORE_CTX structures. +Their usage is identical to that of RSA_get_ex_new_index(), RSA_set_ex_data() +and RSA_get_ex_data() as described in L. + +=head1 NOTES + +This mechanism is used internally by the B library to store the B +structure associated with a verification operation in an B +structure. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +X509_STORE_CTX_get_ex_new_index(), X509_STORE_CTX_set_ex_data() and +X509_STORE_CTX_get_ex_data() are available since OpenSSL 0.9.5. + +=cut diff --git a/crypto/openssl/doc/crypto/X509_STORE_CTX_new.pod b/crypto/openssl/doc/crypto/X509_STORE_CTX_new.pod new file mode 100644 index 0000000000..b17888f149 --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_STORE_CTX_new.pod @@ -0,0 +1,122 @@ +=pod + +=head1 NAME + +X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_init, X509_STORE_CTX_trusted_stack, X509_STORE_CTX_set_cert, X509_STORE_CTX_set_chain, X509_STORE_CTX_set0_crls, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default - X509_STORE_CTX initialisation + +=head1 SYNOPSIS + + #include + + X509_STORE_CTX *X509_STORE_CTX_new(void); + void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + void X509_STORE_CTX_free(X509_STORE_CTX *ctx); + + int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); + + void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); + + void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x); + void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx,STACK_OF(X509) *sk); + void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); + + X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); + void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); + int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +=head1 DESCRIPTION + +These functions initialise an B structure for subsequent use +by X509_verify_cert(). + +X509_STORE_CTX_new() returns a newly initialised B structure. + +X509_STORE_CTX_cleanup() internally cleans up an B structure. +The context can then be reused with an new call to X509_STORE_CTX_init(). + +X509_STORE_CTX_free() completely frees up B. After this call B +is no longer valid. + +X509_STORE_CTX_init() sets up B for a subsequent verification operation. +The trusted certificate store is set to B, the end entity certificate +to be verified is set to B and a set of additional certificates (which +will be untrusted but may be used to build the chain) in B. Any or +all of the B, B and B parameters can be B. + +X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B +to B. This is an alternative way of specifying trusted certificates +instead of using an B. + +X509_STORE_CTX_set_cert() sets the certificate to be vertified in B to +B. + +X509_STORE_CTX_set_chain() sets the additional certificate chain used by B +to B. + +X509_STORE_CTX_set0_crls() sets a set of CRLs to use to aid certificate +verification to B. These CRLs will only be used if CRL verification is +enabled in the associated B structure. This might be +used where additional "useful" CRLs are supplied as part of a protocol, +for example in a PKCS#7 structure. + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param() retrieves an intenal pointer +to the verification parameters associated with B. + +X509_STORE_CTX_set0_param() sets the intenal verification parameter pointer +to B. After this call B should not be used. + +X509_STORE_CTX_set_default() looks up and sets the default verification +method to B. This uses the function X509_VERIFY_PARAM_lookup() to +find an appropriate set of parameters from B. + +=head1 NOTES + +The certificates and CRLs in a store are used internally and should B +be freed up until after the associated B is freed. Legacy +applications might implicitly use an B like this: + + X509_STORE_CTX ctx; + X509_STORE_CTX_init(&ctx, store, cert, chain); + +this is B recommended in new applications they should instead do: + + X509_STORE_CTX *ctx; + ctx = X509_STORE_CTX_new(); + if (ctx == NULL) + /* Bad error */ + X509_STORE_CTX_init(ctx, store, cert, chain); + +=head1 BUGS + +The certificates and CRLs in a context are used internally and should B +be freed up until after the associated B is freed. Copies +should be made or reference counts increased instead. + +=head1 RETURN VALUES + +X509_STORE_CTX_new() returns an newly allocates context or B is an +error occurred. + +X509_STORE_CTX_init() returns 1 for success or 0 if an error occurred. + +X509_STORE_CTX_get0_param() returns a pointer to an B +structure or B if an error occurred. + +X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), X509_STORE_CTX_trusted_stack(), +X509_STORE_CTX_set_cert(), X509_STORE_CTX_set_chain(), +X509_STORE_CTX_set0_crls() and X509_STORE_CTX_set0_param() do not return +values. + +X509_STORE_CTX_set_default() returns 1 for success or 0 if an error occurred. + +=head1 SEE ALSO + +L +L + +=head1 HISTORY + +X509_STORE_CTX_set0_crls() was first added to OpenSSL 1.0.0 + +=cut diff --git a/crypto/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod b/crypto/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod new file mode 100644 index 0000000000..b9787a6ca6 --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod @@ -0,0 +1,161 @@ +=pod + +=head1 NAME + +X509_STORE_CTX_set_verify_cb - set verification callback + +=head1 SYNOPSIS + + #include + + void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); + +=head1 DESCRIPTION + +X509_STORE_CTX_set_verify_cb() sets the verification callback of B to +B overwriting any existing callback. + +The verification callback can be used to customise the operation of certificate +verification, either by overriding error conditions or logging errors for +debugging purposes. + +However a verification callback is B essential and the default operation +is often sufficient. + +The B parameter to the callback indicates the value the callback should +return to retain the default behaviour. If it is zero then and error condition +is indicated. If it is 1 then no error occurred. If the flag +B is set then B is set to 2 to indicate the +policy checking is complete. + +The B parameter to the callback is the B structure that +is performing the verification operation. A callback can examine this +structure and receive additional information about the error, for example +by calling X509_STORE_CTX_get_current_cert(). Additional application data can +be passed to the callback via the B mechanism. + +=head1 WARNING + +In general a verification callback should B unconditionally return 1 in +all circumstances because this will allow verification to succeed no matter +what the error. This effectively removes all security from the application +because B certificate (including untrusted generated ones) will be +accepted. + +=head1 NOTES + +The verification callback can be set and inherited from the parent structure +performing the operation. In some cases (such as S/MIME verification) the +B structure is created and destroyed internally and the +only way to set a custom verification callback is by inheriting it from the +associated B. + +=head1 RETURN VALUES + +X509_STORE_CTX_set_verify_cb() does not return a value. + +=head1 EXAMPLES + +Default callback operation: + + int verify_callback(int ok, X509_STORE_CTX *ctx) + { + return ok; + } + +Simple example, suppose a certificate in the chain is expired and we wish +to continue after this error: + + int verify_callback(int ok, X509_STORE_CTX *ctx) + { + /* Tolerate certificate expiration */ + if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED) + return 1; + /* Otherwise don't override */ + return ok; + } + +More complex example, we don't wish to continue after B certificate has +expired just one specific case: + + int verify_callback(int ok, X509_STORE_CTX *ctx) + { + int err = X509_STORE_CTX_get_error(ctx); + X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx); + if (err == X509_V_ERR_CERT_HAS_EXPIRED) + { + if (check_is_acceptable_expired_cert(err_cert) + return 1; + } + return ok; + } + +Full featured logging callback. In this case the B is assumed to be +a global logging B, an alternative would to store a BIO in B using +B. + + int verify_callback(int ok, X509_STORE_CTX *ctx) + { + X509 *err_cert; + int err,depth; + + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); + + BIO_printf(bio_err,"depth=%d ",depth); + if (err_cert) + { + X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); + } + else + BIO_puts(bio_err, "\n"); + if (!ok) + BIO_printf(bio_err,"verify error:num=%d:%s\n",err, + X509_verify_cert_error_string(err)); + switch (err) + { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + BIO_puts(bio_err,"issuer= "); + X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + BIO_printf(bio_err,"notBefore="); + ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); + BIO_printf(bio_err,"\n"); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + BIO_printf(bio_err,"notAfter="); + ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); + BIO_printf(bio_err,"\n"); + break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(bio_err, ctx); + break; + } + if (err == X509_V_OK && ok == 2) + /* print out policies */ + + BIO_printf(bio_err,"verify return:%d\n",ok); + return(ok); + } + +=head1 SEE ALSO + +L +L +L + +=head1 HISTORY + +X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and +OpenSSL. + +=cut diff --git a/crypto/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod b/crypto/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod new file mode 100644 index 0000000000..29e3bbe3bc --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +X509_STORE_set_verify_cb_func, X509_STORE_set_verify_cb - set verification callback + +=head1 SYNOPSIS + + #include + + void X509_STORE_set_verify_cb(X509_STORE *st, + int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); + + void X509_STORE_set_verify_cb_func(X509_STORE *st, + int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); + +=head1 DESCRIPTION + +X509_STORE_set_verify_cb() sets the verification callback of B to +B overwriting any existing callback. + +X509_STORE_set_verify_cb_func() also sets the verification callback but it +is implemented as a macro. + +=head1 NOTES + +The verification callback from an B is inherited by +the corresponding B structure when it is initialized. This can +be used to set the verification callback when the B is +otherwise inaccessible (for example during S/MIME verification). + +=head1 BUGS + +The macro version of this function was the only one available before +OpenSSL 1.0.0. + +=head1 RETURN VALUES + +X509_STORE_set_verify_cb() and X509_STORE_set_verify_cb_func() do not return +a value. + +=head1 SEE ALSO + +L +L + +=head1 HISTORY + +X509_STORE_set_verify_cb_func() is available in all versions of SSLeay and +OpenSSL. + +X509_STORE_set_verify_cb() was added to OpenSSL 1.0.0. + +=cut diff --git a/crypto/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/crypto/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod new file mode 100644 index 0000000000..b68eece033 --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod @@ -0,0 +1,171 @@ +=pod + +=head1 NAME + +X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies - X509 verification parameters + +=head1 SYNOPSIS + + #include + + int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); + int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); + unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); + + int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); + int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); + + void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); + + int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); + int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + + void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); + int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); + +=head1 DESCRIPTION + +These functions manipulate the B structure associated with +a certificate verification operation. + +The X509_VERIFY_PARAM_set_flags() function sets the flags in B by oring +it with B. See the B section for a complete +description of values the B parameter can take. + +X509_VERIFY_PARAM_get_flags() returns the flags in B. + +X509_VERIFY_PARAM_clear_flags() clears the flags B in B. + +X509_VERIFY_PARAM_set_purpose() sets the verification purpose in B +to B. This determines the acceptable purpose of the certificate +chain, for example SSL client or SSL server. + +X509_VERIFY_PARAM_set_trust() sets the trust setting in B to +B. + +X509_VERIFY_PARAM_set_time() sets the verification time in B to +B. Normally the current time is used. + +X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled +by default) and adds B to the acceptable policy set. + +X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled +by default) and sets the acceptable policy set to B. Any existing +policy set is cleared. The B parameter can be B to clear +an existing policy set. + +X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to B. +That is the maximum number of untrusted CA certificates that can appear in a +chain. + +=head1 RETURN VALUES + +X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(), +X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(), +X509_VERIFY_PARAM_add0_policy() and X509_VERIFY_PARAM_set1_policies() return 1 +for success and 0 for failure. + +X509_VERIFY_PARAM_get_flags() returns the current verification flags. + +X509_VERIFY_PARAM_set_time() and X509_VERIFY_PARAM_set_depth() do not return +values. + +X509_VERIFY_PARAM_get_depth() returns the current verification depth. + +=head1 VERIFICATION FLAGS + +The verification flags consists of zero or more of the following flags +ored together. + +B enables CRL checking for the certificate chain leaf +certificate. An error occurs if a suitable CRL cannot be found. + +B enables CRL checking for the entire certificate +chain. + +B disabled critical extension checking. By default +any unhandled critical extensions in certificates or (if checked) CRLs results +in a fatal error. If this flag is set unhandled critical extensions are +ignored. B setting this option for anything other than debugging +purposes can be a security risk. Finer control over which extensions are +supported can be performed in the verification callback. + +THe B flag disables workarounds for some broken +certificates and makes the verification strictly apply B rules. + +B enables proxy certificate verification. + +B enables certificate policy checking, by default +no policy checking is peformed. Additional information is sent to the +verification callback relating to policy checking. + +B, B and +B set the B, B and B flags respectively as defined in +B. Policy checking is automatically enabled if any of these flags +are set. + +If B is set and the policy checking is successful +a special status code is set to the verification callback. This permits it +to examine the valid policy tree and perform additional checks or simply +log it for debugging purposes. + +By default some addtional features such as indirect CRLs and CRLs signed by +different keys are disabled. If B is set +they are enabled. + +If B ise set delta CRLs (if present) are used to +determine certificate status. If not set deltas are ignored. + +B enables checking of the root CA self signed +cerificate signature. By default this check is disabled because it doesn't +add any additional security but in some cases applications might want to +check the signature anyway. A side effect of not checking the root CA +signature is that disabled or unsupported message digests on the root CA +are not treated as fatal errors. + +The B flag enables debugging of certificate +issuer checks. It is B needed unless you are logging certificate +verification. If this flag is set then additional status codes will be sent +to the verification callback and it B be prepared to handle such cases +without assuming they are hard errors. + +=head1 NOTES + +The above functions should be used to manipulate verification parameters +instead of legacy functions which work in specific structures such as +X509_STORE_CTX_set_flags(). + +=head1 BUGS + +Delta CRL checking is currently primitive. Only a single delta can be used and +(partly due to limitations of B) constructed CRLs are not +maintained. + +If CRLs checking is enable CRLs are expected to be available in the +corresponding B structure. No attempt is made to download +CRLs from the CRL distribution points extension. + +=head1 EXAMPLE + +Enable CRL checking when performing certificate verification during SSL +connections associated with an B structure B: + + X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_new(); + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); + SSL_CTX_set1_param(ctx, param); + X509_VERIFY_PARAM_free(param); + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/crypto/openssl/doc/crypto/X509_new.pod b/crypto/openssl/doc/crypto/X509_new.pod index fd5fc65ce1..d38872335f 100644 --- a/crypto/openssl/doc/crypto/X509_new.pod +++ b/crypto/openssl/doc/crypto/X509_new.pod @@ -6,6 +6,8 @@ X509_new, X509_free - X509 certificate ASN1 allocation functions =head1 SYNOPSIS + #include + X509 *X509_new(void); void X509_free(X509 *a); diff --git a/crypto/openssl/doc/crypto/X509_verify_cert.pod b/crypto/openssl/doc/crypto/X509_verify_cert.pod new file mode 100644 index 0000000000..5253bdcd70 --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_verify_cert.pod @@ -0,0 +1,53 @@ +=pod + +=head1 NAME + +X509_verify_cert - discover and verify X509 certificte chain + +=head1 SYNOPSIS + + #include + + int X509_verify_cert(X509_STORE_CTX *ctx); + +=head1 DESCRIPTION + +The X509_verify_cert() function attempts to discover and validate a +certificate chain based on parameters in B. A complete description of +the process is contained in the L manual page. + +=head1 RETURN VALUES + +If a complete chain can be built and validated this function returns 1, +otherwise it return zero, in exceptional circumstances it can also +return a negative code. + +If the function fails additional error information can be obtained by +examining B using, for example X509_STORE_CTX_get_error(). + +=head1 NOTES + +Applications rarely call this function directly but it is used by +OpenSSL internally for certificate validation, in both the S/MIME and +SSL/TLS code. + +The negative return value from X509_verify_cert() can only occur if no +certificate is set in B (due to a programming error) or if a retry +operation is requested during internal lookups (which never happens with +standard lookup methods). It is however recommended that application check +for <= 0 return value on error. + +=head1 BUGS + +This function uses the header B as opposed to most chain verification +functiosn which use B. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +X509_verify_cert() is available in all versions of SSLeay and OpenSSL. + +=cut diff --git a/crypto/openssl/doc/crypto/bn_internal.pod b/crypto/openssl/doc/crypto/bn_internal.pod index d39ce90939..91840b0f0d 100644 --- a/crypto/openssl/doc/crypto/bn_internal.pod +++ b/crypto/openssl/doc/crypto/bn_internal.pod @@ -13,6 +13,8 @@ library internal functions =head1 SYNOPSIS + #include + BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); diff --git a/crypto/openssl/doc/crypto/d2i_RSAPublicKey.pod b/crypto/openssl/doc/crypto/d2i_RSAPublicKey.pod index 279b29c873..aa6078bcf6 100644 --- a/crypto/openssl/doc/crypto/d2i_RSAPublicKey.pod +++ b/crypto/openssl/doc/crypto/d2i_RSAPublicKey.pod @@ -11,21 +11,21 @@ d2i_Netscape_RSA - RSA public and private key encoding functions. #include #include - RSA * d2i_RSAPublicKey(RSA **a, unsigned char **pp, long length); + RSA * d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length); int i2d_RSAPublicKey(RSA *a, unsigned char **pp); - RSA * d2i_RSA_PUBKEY(RSA **a, unsigned char **pp, long length); + RSA * d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); - RSA * d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length); + RSA * d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length); int i2d_RSAPrivateKey(RSA *a, unsigned char **pp); int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)()); - RSA * d2i_Netscape_RSA(RSA **a, unsigned char **pp, long length, int (*cb)()); + RSA * d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)()); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/evp.pod b/crypto/openssl/doc/crypto/evp.pod index b3ca14314f..9faa349243 100644 --- a/crypto/openssl/doc/crypto/evp.pod +++ b/crypto/openssl/doc/crypto/evp.pod @@ -22,14 +22,24 @@ digital signatures. Symmetric encryption is available with the BI<...> functions. The BI<...> functions provide message digests. +The BI<...> functions provide a high level interface to +asymmetric algorithms. + Algorithms are loaded with OpenSSL_add_all_algorithms(3). -All the symmetric algorithms (ciphers) and digests can be replaced by ENGINE -modules providing alternative implementations. If ENGINE implementations of -ciphers or digests are registered as defaults, then the various EVP functions -will automatically use those implementations automatically in preference to -built in software implementations. For more information, consult the engine(3) -man page. +All the symmetric algorithms (ciphers), digests and asymmetric algorithms +(public key algorithms) can be replaced by ENGINE modules providing alternative +implementations. If ENGINE implementations of ciphers or digests are registered +as defaults, then the various EVP functions will automatically use those +implementations automatically in preference to built in software +implementations. For more information, consult the engine(3) man page. + +Although low level algorithm specific functions exist for many algorithms +their use is discouraged. They cannot be used with an ENGINE and ENGINE +versions of new algorithms cannot be accessed using the low level functions. +Also makes code harder to adapt to new algorithms and some options are not +cleanly supported at the low level and some operations are more efficient +using the high level interface. =head1 SEE ALSO diff --git a/crypto/openssl/doc/crypto/hmac.pod b/crypto/openssl/doc/crypto/hmac.pod index 484e349fd1..d92138d273 100644 --- a/crypto/openssl/doc/crypto/hmac.pod +++ b/crypto/openssl/doc/crypto/hmac.pod @@ -15,12 +15,12 @@ authentication code void HMAC_CTX_init(HMAC_CTX *ctx); - void HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, + int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md); - void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, + int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl); - void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len); - void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); + int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len); + int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); void HMAC_CTX_cleanup(HMAC_CTX *ctx); void HMAC_cleanup(HMAC_CTX *ctx); @@ -76,10 +76,13 @@ must have space for the hash function output. =head1 RETURN VALUES -HMAC() returns a pointer to the message authentication code. +HMAC() returns a pointer to the message authentication code or NULL if +an error occurred. -HMAC_CTX_init(), HMAC_Init_ex(), HMAC_Update(), HMAC_Final() and -HMAC_CTX_cleanup() do not return values. +HMAC_Init_ex(), HMAC_Update() and HMAC_Final() return 1 for success or 0 if +an error occurred. + +HMAC_CTX_init() and HMAC_CTX_cleanup() do not return values. =head1 CONFORMING TO @@ -97,4 +100,7 @@ are available since SSLeay 0.9.0. HMAC_CTX_init(), HMAC_Init_ex() and HMAC_CTX_cleanup() are available since OpenSSL 0.9.7. +HMAC_Init_ex(), HMAC_Update() and HMAC_Final() did not return values in +versions of OpenSSL before 1.0.0. + =cut diff --git a/crypto/openssl/doc/crypto/i2d_CMS_bio_stream.pod b/crypto/openssl/doc/crypto/i2d_CMS_bio_stream.pod new file mode 100644 index 0000000000..558bdd0812 --- /dev/null +++ b/crypto/openssl/doc/crypto/i2d_CMS_bio_stream.pod @@ -0,0 +1,44 @@ +=pod + +=head1 NAME + + i2d_CMS_bio_stream - output CMS_ContentInfo structure in BER format. + +=head1 SYNOPSIS + + #include + + int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); + +=head1 DESCRIPTION + +i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format. + +It is otherwise identical to the function SMIME_write_CMS(). + +=head1 NOTES + +This function is effectively a version of the i2d_CMS_bio() supporting +streaming. + +=head1 BUGS + +The prefix "i2d" is arguably wrong because the function outputs BER format. + +=head1 RETURN VALUES + +i2d_CMS_bio_stream() returns 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, +L, L +L, +L, +L + +=head1 HISTORY + +i2d_CMS_bio_stream() was added to OpenSSL 1.0.0 + +=cut diff --git a/crypto/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod b/crypto/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod new file mode 100644 index 0000000000..dc4d884c59 --- /dev/null +++ b/crypto/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod @@ -0,0 +1,44 @@ +=pod + +=head1 NAME + +i2d_PKCS7_bio_stream - output PKCS7 structure in BER format. + +=head1 SYNOPSIS + + #include + + int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags); + +=head1 DESCRIPTION + +i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format. + +It is otherwise identical to the function SMIME_write_PKCS7(). + +=head1 NOTES + +This function is effectively a version of the d2i_PKCS7_bio() supporting +streaming. + +=head1 BUGS + +The prefix "d2i" is arguably wrong because the function outputs BER format. + +=head1 RETURN VALUES + +i2d_PKCS7_bio_stream() returns 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, +L, L +L, +L, +L + +=head1 HISTORY + +i2d_PKCS7_bio_stream() was added to OpenSSL 1.0.0 + +=cut diff --git a/crypto/openssl/doc/crypto/lhash.pod b/crypto/openssl/doc/crypto/lhash.pod index dcdbb43a8e..73a19b6c7e 100644 --- a/crypto/openssl/doc/crypto/lhash.pod +++ b/crypto/openssl/doc/crypto/lhash.pod @@ -8,18 +8,20 @@ lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_e #include - LHASH *lh_new(LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE compare); - void lh_free(LHASH *table); + DECLARE_LHASH_OF(); - void *lh_insert(LHASH *table, void *data); - void *lh_delete(LHASH *table, void *data); - void *lh_retrieve(LHASH *table, void *data); + LHASH *lh__new(); + void lh__free(LHASH_OF( *table); - void lh_doall(LHASH *table, LHASH_DOALL_FN_TYPE func); - void lh_doall_arg(LHASH *table, LHASH_DOALL_ARG_FN_TYPE func, - void *arg); + *lh__insert(LHASH_OF( *table, *data); + *lh__delete(LHASH_OF( *table, *data); + *lh_retrieve(LHASH_OF *table, *data); - int lh_error(LHASH *table); + void lh__doall(LHASH_OF( *table, LHASH_DOALL_FN_TYPE func); + void lh__doall_arg(LHASH_OF( *table, LHASH_DOALL_ARG_FN_TYPE func, + , *arg); + + int lh__error(LHASH_OF( *table); typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); @@ -28,113 +30,115 @@ lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_e =head1 DESCRIPTION -This library implements dynamic hash tables. The hash table entries -can be arbitrary structures. Usually they consist of key and value -fields. - -lh_new() creates a new B structure to store arbitrary data -entries, and provides the 'hash' and 'compare' callbacks to be used in -organising the table's entries. The B callback takes a pointer -to a table entry as its argument and returns an unsigned long hash -value for its key field. The hash value is normally truncated to a -power of 2, so make sure that your hash function returns well mixed -low order bits. The B callback takes two arguments (pointers -to two hash table entries), and returns 0 if their keys are equal, -non-zero otherwise. If your hash table will contain items of some -particular type and the B and B callbacks hash/compare -these types, then the B and -B macros can be used to create callback -wrappers of the prototypes required by lh_new(). These provide -per-variable casts before calling the type-specific callbacks written -by the application author. These macros, as well as those used for -the "doall" callbacks, are defined as; - - #define DECLARE_LHASH_HASH_FN(f_name,o_type) \ - unsigned long f_name##_LHASH_HASH(const void *); - #define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \ - unsigned long f_name##_LHASH_HASH(const void *arg) { \ - o_type a = (o_type)arg; \ - return f_name(a); } - #define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH - - #define DECLARE_LHASH_COMP_FN(f_name,o_type) \ - int f_name##_LHASH_COMP(const void *, const void *); - #define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \ - int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \ - o_type a = (o_type)arg1; \ - o_type b = (o_type)arg2; \ - return f_name(a,b); } - #define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP - - #define DECLARE_LHASH_DOALL_FN(f_name,o_type) \ - void f_name##_LHASH_DOALL(const void *); - #define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \ - void f_name##_LHASH_DOALL(const void *arg) { \ - o_type a = (o_type)arg; \ - f_name(a); } - #define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL - - #define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ - void f_name##_LHASH_DOALL_ARG(const void *, const void *); - #define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ - void f_name##_LHASH_DOALL_ARG(const void *arg1, const void *arg2) { \ - o_type a = (o_type)arg1; \ - a_type b = (a_type)arg2; \ - f_name(a,b); } - #define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG - -An example of a hash table storing (pointers to) structures of type 'STUFF' -could be defined as follows; +This library implements type-checked dynamic hash tables. The hash +table entries can be arbitrary structures. Usually they consist of key +and value fields. + +lh__new() creates a new B> structure to store +arbitrary data entries, and provides the 'hash' and 'compare' +callbacks to be used in organising the table's entries. The B +callback takes a pointer to a table entry as its argument and returns +an unsigned long hash value for its key field. The hash value is +normally truncated to a power of 2, so make sure that your hash +function returns well mixed low order bits. The B callback +takes two arguments (pointers to two hash table entries), and returns +0 if their keys are equal, non-zero otherwise. If your hash table +will contain items of some particular type and the B and +B callbacks hash/compare these types, then the +B and B macros can be +used to create callback wrappers of the prototypes required by +lh__new(). These provide per-variable casts before calling the +type-specific callbacks written by the application author. These +macros, as well as those used for the "doall" callbacks, are defined +as; + + #define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); + #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } + #define LHASH_HASH_FN(name) name##_LHASH_HASH + + #define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); + #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } + #define LHASH_COMP_FN(name) name##_LHASH_COMP + + #define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); + #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } + #define LHASH_DOALL_FN(name) name##_LHASH_DOALL + + #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); + #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } + #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + + An example of a hash table storing (pointers to) structures of type 'STUFF' + could be defined as follows; /* Calculates the hash value of 'tohash' (implemented elsewhere) */ unsigned long STUFF_hash(const STUFF *tohash); /* Orders 'arg1' and 'arg2' (implemented elsewhere) */ - int STUFF_cmp(const STUFF *arg1, const STUFF *arg2); + int stuff_cmp(const STUFF *arg1, const STUFF *arg2); /* Create the type-safe wrapper functions for use in the LHASH internals */ - static IMPLEMENT_LHASH_HASH_FN(STUFF_hash, const STUFF *) - static IMPLEMENT_LHASH_COMP_FN(STUFF_cmp, const STUFF *); + static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF); + static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF); /* ... */ int main(int argc, char *argv[]) { /* Create the new hash table using the hash/compare wrappers */ - LHASH *hashtable = lh_new(LHASH_HASH_FN(STUFF_hash), + LHASH_OF(STUFF) *hashtable = lh_STUFF_new(LHASH_HASH_FN(STUFF_hash), LHASH_COMP_FN(STUFF_cmp)); /* ... */ } -lh_free() frees the B structure B. Allocated hash table -entries will not be freed; consider using lh_doall() to deallocate any -remaining entries in the hash table (see below). +lh__free() frees the B> structure +B
. Allocated hash table entries will not be freed; consider +using lh__doall() to deallocate any remaining entries in the +hash table (see below). -lh_insert() inserts the structure pointed to by B into B
. -If there already is an entry with the same key, the old value is -replaced. Note that lh_insert() stores pointers, the data are not -copied. +lh__insert() inserts the structure pointed to by B into +B
. If there already is an entry with the same key, the old +value is replaced. Note that lh__insert() stores pointers, the +data are not copied. -lh_delete() deletes an entry from B
. +lh__delete() deletes an entry from B
. -lh_retrieve() looks up an entry in B
. Normally, B is -a structure with the key field(s) set; the function will return a +lh__retrieve() looks up an entry in B
. Normally, B +is a structure with the key field(s) set; the function will return a pointer to a fully populated structure. -lh_doall() will, for every entry in the hash table, call B with -the data item as its parameter. For lh_doall() and lh_doall_arg(), -function pointer casting should be avoided in the callbacks (see -B) - instead, either declare the callbacks to match the -prototype required in lh_new() or use the declare/implement macros to -create type-safe wrappers that cast variables prior to calling your -type-specific callbacks. An example of this is illustrated here where -the callback is used to cleanup resources for items in the hash table -prior to the hashtable itself being deallocated: +lh__doall() will, for every entry in the hash table, call +B with the data item as its parameter. For lh__doall() +and lh__doall_arg(), function pointer casting should be avoided +in the callbacks (see B) - instead use the declare/implement +macros to create type-checked wrappers that cast variables prior to +calling your type-specific callbacks. An example of this is +illustrated here where the callback is used to cleanup resources for +items in the hash table prior to the hashtable itself being +deallocated: /* Cleans up resources belonging to 'a' (this is implemented elsewhere) */ - void STUFF_cleanup(STUFF *a); + void STUFF_cleanup_doall(STUFF *a); /* Implement a prototype-compatible wrapper for "STUFF_cleanup" */ - IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF *) + IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF) /* ... then later in the code ... */ /* So to run "STUFF_cleanup" against all items in a hash table ... */ - lh_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); + lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); /* Then the hash table itself can be deallocated */ - lh_free(hashtable); + lh_STUFF_free(hashtable); When doing this, be careful if you delete entries from the hash table in your callbacks: the table may decrease in size, moving the item @@ -145,51 +149,52 @@ you start (which will stop the hash table ever decreasing in size). The best solution is probably to avoid deleting items from the hash table inside a "doall" callback! -lh_doall_arg() is the same as lh_doall() except that B will be -called with B as the second argument and B should be of -type B (a callback prototype that is passed -both the table entry and an extra argument). As with lh_doall(), you -can instead choose to declare your callback with a prototype matching -the types you are dealing with and use the declare/implement macros to -create compatible wrappers that cast variables before calling your -type-specific callbacks. An example of this is demonstrated here -(printing all hash table entries to a BIO that is provided by the -caller): +lh__doall_arg() is the same as lh__doall() except that +B will be called with B as the second argument and B +should be of type B (a callback prototype +that is passed both the table entry and an extra argument). As with +lh_doall(), you can instead choose to declare your callback with a +prototype matching the types you are dealing with and use the +declare/implement macros to create compatible wrappers that cast +variables before calling your type-specific callbacks. An example of +this is demonstrated here (printing all hash table entries to a BIO +that is provided by the caller): /* Prints item 'a' to 'output_bio' (this is implemented elsewhere) */ - void STUFF_print(const STUFF *a, BIO *output_bio); + void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio); /* Implement a prototype-compatible wrapper for "STUFF_print" */ - static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF_print, const STUFF *, BIO *) + static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO) /* ... then later in the code ... */ /* Print out the entire hashtable to a particular BIO */ - lh_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), logging_bio); + lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO, + logging_bio); -lh_error() can be used to determine if an error occurred in the last -operation. lh_error() is a macro. +lh__error() can be used to determine if an error occurred in the last +operation. lh__error() is a macro. =head1 RETURN VALUES -lh_new() returns B on error, otherwise a pointer to the new +lh__new() returns B on error, otherwise a pointer to the new B structure. -When a hash table entry is replaced, lh_insert() returns the value +When a hash table entry is replaced, lh__insert() returns the value being replaced. B is returned on normal operation and on error. -lh_delete() returns the entry being deleted. B is returned if +lh__delete() returns the entry being deleted. B is returned if there is no such value in the hash table. -lh_retrieve() returns the hash table entry if it has been found, +lh__retrieve() returns the hash table entry if it has been found, B otherwise. -lh_error() returns 1 if an error occurred in the last operation, 0 +lh__error() returns 1 if an error occurred in the last operation, 0 otherwise. -lh_free(), lh_doall() and lh_doall_arg() return no values. +lh__free(), lh__doall() and lh__doall_arg() return no values. =head1 NOTE The various LHASH macros and callback types exist to make it possible -to write type-safe code without resorting to function-prototype +to write type-checked code without resorting to function-prototype casting - an evil that makes application code much harder to audit/verify and also opens the window of opportunity for stack corruption and other hard-to-find bugs. It also, apparently, violates @@ -227,7 +232,7 @@ without any "const" qualifiers. =head1 BUGS -lh_insert() returns B both for success and error. +lh__insert() returns B both for success and error. =head1 INTERNALS @@ -272,8 +277,8 @@ lh_strhash() is a demo string hashing function: unsigned long lh_strhash(const char *c); Since the B routines would normally be passed structures, this -routine would not normally be passed to lh_new(), rather it would be -used in the function passed to lh_new(). +routine would not normally be passed to lh__new(), rather it would be +used in the function passed to lh__new(). =head1 SEE ALSO @@ -291,4 +296,7 @@ were changed for better type safety, and the function types LHASH_COMP_FN_TYPE, LHASH_HASH_FN_TYPE, LHASH_DOALL_FN_TYPE and LHASH_DOALL_ARG_FN_TYPE became available. +In OpenSSL 1.0.0, the lhash interface was revamped for even better +type checking. + =cut diff --git a/crypto/openssl/doc/crypto/threads.pod b/crypto/openssl/doc/crypto/threads.pod index 3df4ecd776..dc0e9391dc 100644 --- a/crypto/openssl/doc/crypto/threads.pod +++ b/crypto/openssl/doc/crypto/threads.pod @@ -2,7 +2,9 @@ =head1 NAME -CRYPTO_set_locking_callback, CRYPTO_set_id_callback, CRYPTO_num_locks, +CRYPTO_THREADID_set_callback, CRYPTO_THREADID_get_callback, +CRYPTO_THREADID_current, CRYPTO_THREADID_cmp, CRYPTO_THREADID_cpy, +CRYPTO_THREADID_hash, CRYPTO_set_locking_callback, CRYPTO_num_locks, CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback, CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid, CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support @@ -11,14 +13,26 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support #include - void CRYPTO_set_locking_callback(void (*locking_function)(int mode, - int n, const char *file, int line)); - - void CRYPTO_set_id_callback(unsigned long (*id_function)(void)); + /* Don't use this structure directly. */ + typedef struct crypto_threadid_st + { + void *ptr; + unsigned long val; + } CRYPTO_THREADID; + /* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ + void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); + void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); + int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); + void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); + void CRYPTO_THREADID_current(CRYPTO_THREADID *id); + int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, + const CRYPTO_THREADID *b); + void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, + const CRYPTO_THREADID *src); + unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); int CRYPTO_num_locks(void); - /* struct CRYPTO_dynlock_value needs to be defined by the user */ struct CRYPTO_dynlock_value; @@ -50,7 +64,8 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support =head1 DESCRIPTION OpenSSL can safely be used in multi-threaded applications provided -that at least two callback functions are set. +that at least two callback functions are set, locking_function and +threadid_func. locking_function(int mode, int n, const char *file, int line) is needed to perform locking on shared data structures. @@ -65,10 +80,42 @@ B, and releases it otherwise. B and B are the file number of the function setting the lock. They can be useful for debugging. -id_function(void) is a function that returns a thread ID, for example -pthread_self() if it returns an integer (see NOTES below). It isn't -needed on Windows nor on platforms where getpid() returns a different -ID for each thread (see NOTES below). +threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing +thread's identifier into B. The implementation of this callback should not +fill in B directly, but should use CRYPTO_THREADID_set_numeric() if thread +IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based. +If the application does not register such a callback using +CRYPTO_THREADID_set_callback(), then a default implementation is used - on +Windows and BeOS this uses the system's default thread identifying APIs, and on +all other platforms it uses the address of B. The latter is satisfactory +for thread-safety if and only if the platform has a thread-local error number +facility. + +Once threadid_func() is registered, or if the built-in default implementation is +to be used; + +=over 4 + +=item * +CRYPTO_THREADID_current() records the currently-executing thread ID into the +given B object. + +=item * +CRYPTO_THREADID_cmp() compares two thread IDs (returning zero for equality, ie. +the same semantics as memcmp()). + +=item * +CRYPTO_THREADID_cpy() duplicates a thread ID value, + +=item * +CRYPTO_THREADID_hash() returns a numeric value usable as a hash-table key. This +is usually the exact numeric or pointer-based thread ID used internally, however +this also handles the unusual case where pointers are larger than 'long' +variables and the platform's thread IDs are pointer-based - in this case, mixing +is done to attempt to produce a unique numeric value even though it is not as +wide as the platform's true thread IDs. + +=back Additionally, OpenSSL supports dynamic locks, and sometimes, some parts of OpenSSL need it for better performance. To enable this, the following @@ -140,22 +187,6 @@ You can find out if OpenSSL was configured with thread support: Also, dynamic locks are currently not used internally by OpenSSL, but may do so in the future. -Defining id_function(void) has it's own issues. Generally speaking, -pthread_self() should be used, even on platforms where getpid() gives -different answers in each thread, since that may depend on the machine -the program is run on, not the machine where the program is being -compiled. For instance, Red Hat 8 Linux and earlier used -LinuxThreads, whose getpid() returns a different value for each -thread. Red Hat 9 Linux and later use NPTL, which is -Posix-conformant, and has a getpid() that returns the same value for -all threads in a process. A program compiled on Red Hat 8 and run on -Red Hat 9 will therefore see getpid() returning the same value for -all threads. - -There is still the issue of platforms where pthread_self() returns -something other than an integer. This is a bit unusual, and this -manual has no cookbook solution for that case. - =head1 EXAMPLES B shows examples of the callback functions on @@ -163,10 +194,14 @@ Solaris, Irix and Win32. =head1 HISTORY -CRYPTO_set_locking_callback() and CRYPTO_set_id_callback() are +CRYPTO_set_locking_callback() is available in all versions of SSLeay and OpenSSL. CRYPTO_num_locks() was added in OpenSSL 0.9.4. All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev. +B and associated functions were introduced in OpenSSL 1.0.0 +to replace (actually, deprecate) the previous CRYPTO_set_id_callback(), +CRYPTO_get_id_callback(), and CRYPTO_thread_id() functions which assumed +thread IDs to always be represented by 'unsigned long'. =head1 SEE ALSO diff --git a/crypto/openssl/doc/crypto/ui_compat.pod b/crypto/openssl/doc/crypto/ui_compat.pod index 9ab3c69bf2..adf2ae5e53 100644 --- a/crypto/openssl/doc/crypto/ui_compat.pod +++ b/crypto/openssl/doc/crypto/ui_compat.pod @@ -7,6 +7,8 @@ Compatibility user interface functions =head1 SYNOPSIS + #include + int des_read_password(DES_cblock *key,const char *prompt,int verify); int des_read_2passwords(DES_cblock *key1,DES_cblock *key2, const char *prompt,int verify); diff --git a/crypto/openssl/doc/ssl/SSL_CTX_new.pod b/crypto/openssl/doc/ssl/SSL_CTX_new.pod index 465220a75c..73e8c47f9a 100644 --- a/crypto/openssl/doc/ssl/SSL_CTX_new.pod +++ b/crypto/openssl/doc/ssl/SSL_CTX_new.pod @@ -8,7 +8,7 @@ SSL_CTX_new - create a new SSL_CTX object as framework for TLS/SSL enabled funct #include - SSL_CTX *SSL_CTX_new(SSL_METHOD *method); + SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod index 9822544e5e..8cb669daeb 100644 --- a/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod +++ b/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod @@ -61,6 +61,16 @@ deal with read/write operations returning without success report. The flag SSL_MODE_AUTO_RETRY will cause read/write operations to only return after the handshake and successful completion. +=item SSL_MODE_RELEASE_BUFFERS + +When we no longer need a read buffer or a write buffer for a given SSL, +then release the memory we were using to hold it. Released memory is +either appended to a list of unused RAM chunks on the SSL_CTX, or simply +freed if the list of unused chunks would become longer than +SSL_CTX->freelist_max_len, which defaults to 32. Using this flag can +save around 34k per idle SSL connection. +This flag has no effect on SSL v2 connections, or on DTLS connections. + =back =head1 RETURN VALUES diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod index 06025d13fa..310db84b31 100644 --- a/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod +++ b/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod @@ -219,8 +219,7 @@ handshake). This option is not needed for clients. =item SSL_OP_NO_TICKET Normally clients and servers will, where possible, transparently make use -of RFC4507bis tickets for stateless session resumption if extension support -is explicitly set when OpenSSL is compiled. +of RFC4507bis tickets for stateless session resumption. If this option is set this functionality is disabled and tickets will not be used by clients or servers. diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod new file mode 100644 index 0000000000..573f89a922 --- /dev/null +++ b/crypto/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod @@ -0,0 +1,81 @@ +=pod + +=begin comment + +Copyright 2005 Nokia. All rights reserved. + +The portions of the attached software ("Contribution") is developed by +Nokia Corporation and is licensed pursuant to the OpenSSL open source +license. + +The Contribution, originally written by Mika Kousa and Pasi Eronen of +Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites +support (see RFC 4279) to OpenSSL. + +No patent licenses or other rights except those expressly stated in +the OpenSSL open source license shall be deemed granted or received +expressly, by implication, estoppel, or otherwise. + +No assurances are provided by Nokia that the Contribution does not +infringe the patent or other intellectual property rights of any third +party or that the license provides you with all the necessary rights +to make use of the Contribution. + +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN +ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA +SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY +OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR +OTHERWISE. + +=end comment + +=head1 NAME + +SSL_CTX_set_psk_client_callback, SSL_set_psk_client_callback - set PSK client callback + +=head1 SYNOPSIS + + #include + + void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*callback)(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, + unsigned char *psk, unsigned int max_psk_len)); + void SSL_set_psk_client_callback(SSL *ssl, + unsigned int (*callback)(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, + unsigned char *psk, unsigned int max_psk_len)); + + +=head1 DESCRIPTION + +A client application must provide a callback function which is called +when the client is sending the ClientKeyExchange message to the server. + +The purpose of the callback function is to select the PSK identity and +the pre-shared key to use during the connection setup phase. + +The callback is set using functions SSL_CTX_set_psk_client_callback() +or SSL_set_psk_client_callback(). The callback function is given the +connection in parameter B, a B-terminated PSK identity hint +sent by the server in parameter B, a buffer B of +length B bytes where the the resulting +B-terminated identity is to be stored, and a buffer B of +length B bytes where the resulting pre-shared key is to +be stored. + +=head1 NOTES + +Note that parameter B given to the callback may be B. + +=head1 RETURN VALUES + +Return values from the client callback are interpreted as follows: + +On success (callback found a PSK identity and a pre-shared key to use) +the length (> 0) of B in bytes is returned. + +Otherwise or on errors callback should return 0. In this case +the connection setup fails. + +=cut diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod index 0020180965..254f2b4397 100644 --- a/crypto/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod +++ b/crypto/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod @@ -9,9 +9,9 @@ SSL_CTX_set_ssl_version, SSL_set_ssl_method, SSL_get_ssl_method #include - int SSL_CTX_set_ssl_version(SSL_CTX *ctx, SSL_METHOD *method); - int SSL_set_ssl_method(SSL *s, SSL_METHOD *method); - SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *method); + int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); + const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); =head1 DESCRIPTION diff --git a/crypto/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod b/crypto/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod new file mode 100644 index 0000000000..b80e25be7e --- /dev/null +++ b/crypto/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod @@ -0,0 +1,102 @@ +=pod + +=begin comment + +Copyright 2005 Nokia. All rights reserved. + +The portions of the attached software ("Contribution") is developed by +Nokia Corporation and is licensed pursuant to the OpenSSL open source +license. + +The Contribution, originally written by Mika Kousa and Pasi Eronen of +Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites +support (see RFC 4279) to OpenSSL. + +No patent licenses or other rights except those expressly stated in +the OpenSSL open source license shall be deemed granted or received +expressly, by implication, estoppel, or otherwise. + +No assurances are provided by Nokia that the Contribution does not +infringe the patent or other intellectual property rights of any third +party or that the license provides you with all the necessary rights +to make use of the Contribution. + +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN +ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA +SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY +OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR +OTHERWISE. + +=end comment + +=head1 NAME + +SSL_CTX_use_psk_identity_hint, SSL_use_psk_identity_hint, +SSL_CTX_set_psk_server_callback, SSL_set_psk_server_callback - set PSK +identity hint to use + + +=head1 SYNOPSIS + + #include + + int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); + int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); + + void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*callback)(SSL *ssl, const char *identity, + unsigned char *psk, int max_psk_len)); + void SSL_set_psk_server_callback(SSL *ssl, + unsigned int (*callback)(SSL *ssl, const char *identity, + unsigned char *psk, int max_psk_len)); + + +=head1 DESCRIPTION + +SSL_CTX_use_psk_identity_hint() sets the given B-terminated PSK +identity hint B to SSL context object +B. SSL_use_psk_identity_hint() sets the given B-terminated +PSK identity hint B to SSL connection object B. If B +is B the current hint from B or B is deleted. + +In the case where PSK identity hint is B, the server +does not send the ServerKeyExchange message to the client. + +A server application must provide a callback function which is called +when the server receives the ClientKeyExchange message from the +client. The purpose of the callback function is to validate the +received PSK identity and to fetch the pre-shared key used during the +connection setup phase. The callback is set using functions +SSL_CTX_set_psk_server_callback() or +SSL_set_psk_server_callback(). The callback function is given the +connection in parameter B, B-terminated PSK identity sent +by the client in parameter B, and a buffer B of length +B bytes where the pre-shared key is to be stored. + + +=head1 RETURN VALUES + +SSL_CTX_use_psk_identity_hint() and SSL_use_psk_identity_hint() return +1 on success, 0 otherwise. + +Return values from the server callback are interpreted as follows: + +=item > 0 + +PSK identity was found and the server callback has provided the PSK +successfully in parameter B. Return value is the length of +B in bytes. It is an error to return a value greater than +B. + +If the PSK identity was not found but the callback instructs the +protocol to continue anyway, the callback must provide some random +data to B and return the length of the random data, so the +connection will fail with decryption_error before it will be finished +completely. + +=item 0 + +PSK identity was not found. An "unknown_psk_identity" alert message +will be sent and the connection setup fails. + +=cut diff --git a/crypto/openssl/doc/ssl/SSL_get_psk_identity.pod b/crypto/openssl/doc/ssl/SSL_get_psk_identity.pod new file mode 100644 index 0000000000..fe6291649c --- /dev/null +++ b/crypto/openssl/doc/ssl/SSL_get_psk_identity.pod @@ -0,0 +1,63 @@ +=pod + +=begin comment + +Copyright 2005 Nokia. All rights reserved. + +The portions of the attached software ("Contribution") is developed by +Nokia Corporation and is licensed pursuant to the OpenSSL open source +license. + +The Contribution, originally written by Mika Kousa and Pasi Eronen of +Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites +support (see RFC 4279) to OpenSSL. + +No patent licenses or other rights except those expressly stated in +the OpenSSL open source license shall be deemed granted or received +expressly, by implication, estoppel, or otherwise. + +No assurances are provided by Nokia that the Contribution does not +infringe the patent or other intellectual property rights of any third +party or that the license provides you with all the necessary rights +to make use of the Contribution. + +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN +ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA +SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY +OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR +OTHERWISE. + +=end comment + +=head1 NAME + +SSL_get_psk_identity, SSL_get_psk_identity_hint - get PSK client identity and hint + + +=head1 SYNOPSIS + + #include + + const char *SSL_get_psk_identity_hint(const SSL *ssl); + const char *SSL_get_psk_identity(const SSL *ssl); + + +=head1 DESCRIPTION + +SSL_get_psk_identity_hint() is used to retrieve the PSK identity hint +used during the connection setup related to SSL object +B. Similarly, SSL_get_psk_identity() is used to retrieve the PSK +identity used during the connection setup. + + +=head1 RETURN VALUES + +If non-B, SSL_get_psk_identity_hint() returns the PSK identity +hint and SSL_get_psk_identity() returns the PSK identity. Both are +B-terminated. SSL_get_psk_identity_hint() may return B if +no PSK identity hint was used during the connection setup. + +Note that the return value is valid only during the lifetime of the +SSL object B. + +=cut diff --git a/crypto/openssl/doc/ssl/SSL_library_init.pod b/crypto/openssl/doc/ssl/SSL_library_init.pod index ecf3c4858e..8766776fea 100644 --- a/crypto/openssl/doc/ssl/SSL_library_init.pod +++ b/crypto/openssl/doc/ssl/SSL_library_init.pod @@ -15,7 +15,7 @@ SSL_library_init, OpenSSL_add_ssl_algorithms, SSLeay_add_ssl_algorithms =head1 DESCRIPTION -SSL_library_init() registers the available ciphers and digests. +SSL_library_init() registers the available SSL/TLS ciphers and digests. OpenSSL_add_ssl_algorithms() and SSLeay_add_ssl_algorithms() are synonyms for SSL_library_init(). @@ -23,27 +23,32 @@ for SSL_library_init(). =head1 NOTES SSL_library_init() must be called before any other action takes place. +SSL_library_init() is not reentrant. =head1 WARNING -SSL_library_init() only registers ciphers. Another important initialization -is the seeding of the PRNG (Pseudo Random Number Generator), which has to -be performed separately. +SSL_library_init() adds ciphers and digests used directly and indirectly by +SSL/TLS. =head1 EXAMPLES A typical TLS/SSL application will start with the library initialization, -will provide readable error messages and will seed the PRNG. +and provide readable error messages. SSL_load_error_strings(); /* readable error messages */ SSL_library_init(); /* initialize library */ - actions_to_seed_PRNG(); =head1 RETURN VALUES SSL_library_init() always returns "1", so it is safe to discard the return value. +=head1 NOTES + +OpenSSL 0.9.8o and 1.0.0a and later added SHA2 algorithms to SSL_library_init(). +Applications which need to use SHA2 in earlier versions of OpenSSL should call +OpenSSL_add_all_algorithms() as well. + =head1 SEE ALSO L, L, diff --git a/crypto/openssl/doc/ssl/ssl.pod b/crypto/openssl/doc/ssl/ssl.pod index 266697d221..2b6004ee32 100644 --- a/crypto/openssl/doc/ssl/ssl.pod +++ b/crypto/openssl/doc/ssl/ssl.pod @@ -130,39 +130,39 @@ protocol methods defined in B structures. =over 4 -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the SSLv2 SSL_METHOD structure for a dedicated client. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the SSLv2 SSL_METHOD structure for a dedicated server. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the SSLv2 SSL_METHOD structure for combined client and server. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the SSLv3 SSL_METHOD structure for a dedicated client. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the SSLv3 SSL_METHOD structure for a dedicated server. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the SSLv3 SSL_METHOD structure for combined client and server. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the TLSv1 SSL_METHOD structure for a dedicated client. -=item SSL_METHOD *B(void); +=item cosnt SSL_METHOD *B(void); Constructor for the TLSv1 SSL_METHOD structure for a dedicated server. -=item SSL_METHOD *B(void); +=item const SSL_METHOD *B(void); Constructor for the TLSv1 SSL_METHOD structure for combined client and server. @@ -249,7 +249,7 @@ protocol context defined in the B structure. =item long B(SSL_CTX *ctx); -=item SSL_CTX *B(SSL_METHOD *meth); +=item SSL_CTX *B(const SSL_METHOD *meth); =item int B(SSL_CTX *ctx, SSL_SESSION *c); @@ -327,7 +327,7 @@ protocol context defined in the B structure. =item void B(SSL_CTX *ctx, int mode); -=item int B(SSL_CTX *ctx, SSL_METHOD *meth); +=item int B(SSL_CTX *ctx, const SSL_METHOD *meth); =item void B(SSL_CTX *ctx, long t); @@ -374,6 +374,15 @@ session instead of a context. =item int B(SSL_CTX *ctx, char *file, int type); +=item void B(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)); + +=item int B(SSL_CTX *ctx, const char *hint); + +=item void B(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len)); + + + + =back =head2 DEALING WITH SESSIONS @@ -512,7 +521,7 @@ connection defined in the B structure. =item int B(const SSL *ssl); -=item SSL_METHOD *B(SSL *ssl); +=item const SSL_METHOD *B(SSL *ssl); =item int B(const SSL *ssl); @@ -596,7 +605,7 @@ connection defined in the B structure. =item void B(SSL *ssl, int mode); -=item int B(SSL *ssl, SSL_METHOD *meth); +=item int B(SSL *ssl, const SSL_METHOD *meth); =item void B(SSL *ssl, long t); @@ -650,6 +659,16 @@ connection defined in the B structure. =item int B(SSL *ssl, const void *buf, int num); +=item void B(SSL *ssl, unsigned int (*callback)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)); + +=item int B(SSL *ssl, const char *hint); + +=item void B(SSL *ssl, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len)); + +=item const char *B(SSL *ssl); + +=item const char *B(SSL *ssl); + =back =head1 SEE ALSO @@ -726,7 +745,10 @@ L, L, L, L, -L +L, +L, +L, +L =head1 HISTORY diff --git a/crypto/openssl/e_os.h b/crypto/openssl/e_os.h index 9c5c6fdb92..5ceeeeb950 100644 --- a/crypto/openssl/e_os.h +++ b/crypto/openssl/e_os.h @@ -112,7 +112,7 @@ extern "C" { /******************************************************************** The Microsoft section ********************************************************************/ -/* The following is used becaue of the small stack in some +/* The following is used because of the small stack in some * Microsoft operating systems */ #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32) # define MS_STATIC static @@ -123,9 +123,6 @@ extern "C" { #if defined(OPENSSL_SYS_WIN32) && !defined(WIN32) # define WIN32 #endif -#if defined(OPENSSL_SYS_WIN16) && !defined(WIN16) -# define WIN16 -#endif #if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif @@ -153,7 +150,6 @@ extern "C" { #define clear_socket_error() WSASetLastError(0) #define readsocket(s,b,n) recv((s),(b),(n),0) #define writesocket(s,b,n) send((s),(b),(n),0) -#define EADDRINUSE WSAEADDRINUSE #elif defined(__DJGPP__) #define WATT32 #define get_last_socket_error() errno @@ -181,6 +177,13 @@ extern "C" { #define closesocket(s) close(s) #define readsocket(s,b,n) read((s),(b),(n)) #define writesocket(s,b,n) write((s),(char *)(b),(n)) +#elif defined(OPENSSL_SYS_BEOS_R5) +#define get_last_socket_error() errno +#define clear_socket_error() errno=0 +#define FIONBIO SO_NONBLOCK +#define ioctlsocket(a,b,c) setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c))) +#define readsocket(s,b,n) recv((s),(b),(n),0) +#define writesocket(s,b,n) send((s),(b),(n),0) #elif defined(OPENSSL_SYS_NETWARE) #if defined(NETWARE_BSDSOCK) #define get_last_socket_error() errno @@ -209,7 +212,7 @@ extern "C" { #define writesocket(s,b,n) write((s),(b),(n)) #endif -#ifdef WIN16 +#ifdef WIN16 /* never the case */ # define MS_CALLBACK _far _loadds # define MS_FAR _far #else @@ -255,19 +258,31 @@ extern "C" { /* * Defining _WIN32_WINNT here in e_os.h implies certain "discipline." * Most notably we ought to check for availability of each specific - * routine with GetProcAddress() and/or quard NT-specific calls with + * routine with GetProcAddress() and/or guard NT-specific calls with * GetVersion() < 0x80000000. One can argue that in latter "or" case * we ought to /DELAYLOAD some .DLLs in order to protect ourselves * against run-time link errors. This doesn't seem to be necessary, * because it turned out that already Windows 95, first non-NT Win32 * implementation, is equipped with at least NT 3.51 stubs, dummy * routines with same name, but which do nothing. Meaning that it's - * apparently appropriate to guard generic NT calls with GetVersion - * alone, while NT 4.0 and above calls ought to be additionally - * checked upon with GetProcAddress. + * apparently sufficient to guard "vanilla" NT calls with GetVersion + * alone, while NT 4.0 and above interfaces ought to be linked with + * GetProcAddress at run-time. */ # define _WIN32_WINNT 0x0400 # endif +# if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT) + /* + * Just like defining _WIN32_WINNT including winsock2.h implies + * certain "discipline" for maintaining [broad] binary compatibility. + * As long as structures are invariant among Winsock versions, + * it's sufficient to check for specific Winsock2 API availability + * at run-time [DSO_global_lookup is recommended]... + */ +# include +# include + /* yes, they have to be #included prior to */ +# endif # include # include # include @@ -308,8 +323,8 @@ static unsigned int _strlen31(const char *str) /* pre-1300 has __p__iob(), but it's available only in msvcrt.lib, * or in other words with /MD. Declaring implicit import, i.e. * with _imp_ prefix, works correctly with all compiler options, - * but without /MD results in LINK warning LNK4049: - * 'locally defined symbol "__iob" imported'. + * but without /MD results in LINK warning LNK4049: + * 'locally defined symbol "__iob" imported'. */ extern FILE *_imp___iob; # define stdin (&_imp___iob[0]) @@ -322,7 +337,7 @@ static unsigned int _strlen31(const char *str) # include # ifdef OPENSSL_SYS_WINCE -# include +# define OPENSSL_NO_POSIX_IO # endif # define ssize_t long @@ -335,12 +350,7 @@ static unsigned int _strlen31(const char *str) # define _kbhit kbhit # endif -# if defined(WIN16) && defined(SSLEAY) && defined(_WINEXITNOPERSIST) -# define EXIT(n) _wsetexit(_WINEXITNOPERSIST) -# define OPENSSL_EXIT(n) do { if (n == 0) EXIT(n); return(n); } while(0) -# else -# define EXIT(n) exit(n) -# endif +# define EXIT(n) exit(n) # define LIST_SEPARATOR_CHAR ';' # ifndef X_OK # define X_OK 0 @@ -361,7 +371,7 @@ static unsigned int _strlen31(const char *str) # define DEFAULT_HOME "C:" # endif -#else /* The non-microsoft world world */ +#else /* The non-microsoft world */ # ifdef OPENSSL_SYS_VMS # define VMS 1 @@ -414,7 +424,6 @@ static unsigned int _strlen31(const char *str) extern int GetThreadID(void); /* # include */ extern int kbhit(void); - extern void delay(unsigned milliseconds); # else # include # endif @@ -454,6 +463,10 @@ static unsigned int _strlen31(const char *str) # define setvbuf(a, b, c, d) setbuffer((a), (b), (d)) typedef unsigned long clock_t; # endif +# ifdef OPENSSL_SYS_WIN32_CYGWIN +# include +# include +# endif # define OPENSSL_CONF "openssl.cnf" # define SSLEAY_CONF OPENSSL_CONF @@ -480,8 +493,19 @@ static unsigned int _strlen31(const char *str) # define SHUTDOWN(fd) close(fd) # define SHUTDOWN2(fd) close(fd) # elif !defined(__DJGPP__) -# include -extern HINSTANCE _hInstance; +# if defined(_WIN32_WCE) && _WIN32_WCE<410 +# define getservbyname _masked_declaration_getservbyname +# endif +# if !defined(IPPROTO_IP) + /* winsock[2].h was included already? */ +# include +# endif +# ifdef getservbyname +# undef getservbyname + /* this is used to be wcecompat/include/winsock_extras.h */ + struct servent* PASCAL getservbyname(const char*,const char*); +# endif + # ifdef _WIN64 /* * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because @@ -553,8 +577,10 @@ extern HINSTANCE _hInstance; # include /* Added for FIONBIO under unixware */ # endif # include +# if !defined(OPENSSL_SYS_BEOS_R5) # include # endif +# endif # if defined(NeXT) || defined(_NEXT_SOURCE) # include @@ -597,6 +623,18 @@ extern HINSTANCE _hInstance; # define INVALID_SOCKET (-1) # endif /* INVALID_SOCKET */ # endif + +/* Some IPv6 implementations are broken, disable them in known bad + * versions. + */ +# if !defined(OPENSSL_USE_IPV6) +# if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB) +# define OPENSSL_USE_IPV6 1 +# else +# define OPENSSL_USE_IPV6 0 +# endif +# endif + #endif #if defined(__ultrix) @@ -630,18 +668,6 @@ extern char *sys_errlist[]; extern int sys_nerr; /***********************************************/ -/* do we need to do this for getenv. - * Just define getenv for use under windows */ - -#ifdef WIN16 -/* How to do this needs to be thought out a bit more.... */ -/*char *GETENV(char *); -#define Getenv GETENV*/ -#define Getenv getenv -#else -#define Getenv getenv -#endif - #define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */ #ifdef sgi @@ -703,6 +729,15 @@ struct servent *getservbyname(const char *name, const char *proto); #endif /* end vxworks */ +/* beos */ +#if defined(OPENSSL_SYS_BEOS_R5) +#define SO_ERROR 0 +#define NO_SYS_UN +#define IPPROTO_IP 0 +#include +#endif + + #ifdef __cplusplus } #endif diff --git a/crypto/openssl/e_os2.h b/crypto/openssl/e_os2.h index 9da0b65448..4c785c62cf 100644 --- a/crypto/openssl/e_os2.h +++ b/crypto/openssl/e_os2.h @@ -202,6 +202,17 @@ extern "C" { # define OPENSSL_SYS_VXWORKS #endif +/* --------------------------------- BeOS ---------------------------------- */ +#if defined(__BEOS__) +# define OPENSSL_SYS_BEOS +# include +# if defined(BONE_VERSION) +# define OPENSSL_SYS_BEOS_BONE +# else +# define OPENSSL_SYS_BEOS_R5 +# endif +#endif + /** * That's it for OS-specific stuff *****************************************************************************/ @@ -251,24 +262,23 @@ extern "C" { #define OPENSSL_EXTERN OPENSSL_IMPORT /* Macros to allow global variables to be reached through function calls when - required (if a shared library version requvres it, for example. + required (if a shared library version requires it, for example. The way it's done allows definitions like this: // in foobar.c - OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0; + OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) // in foobar.h OPENSSL_DECLARE_GLOBAL(int,foobar); #define foobar OPENSSL_GLOBAL_REF(foobar) */ #ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION -# define OPENSSL_IMPLEMENT_GLOBAL(type,name) \ - extern type _hide_##name; \ - type *_shadow_##name(void) { return &_hide_##name; } \ - static type _hide_##name +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } # define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) # define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) #else -# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value; # define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name # define OPENSSL_GLOBAL_REF(name) _shadow_##name #endif diff --git a/crypto/openssl/engines/ccgost/README.gost b/crypto/openssl/engines/ccgost/README.gost new file mode 100644 index 0000000000..c96cccc7b4 --- /dev/null +++ b/crypto/openssl/engines/ccgost/README.gost @@ -0,0 +1,300 @@ +GOST ENGINE + +This engine provides implementation of Russian cryptography standard. +This is also an example of adding new cryptoalgorithms into OpenSSL +without changing its core. If OpenSSL is compiled with dynamic engine +support, new algorithms can be added even without recompilation of +OpenSSL and applications which use it. + +ALGORITHMS SUPPORTED + +GOST R 34.10-94 and GOST R 34.10-2001 - digital signature algorithms. + Also support key exchange based on public keys. See RFC 4357 for + details of VKO key exchange algorithm. These algorithms use + 256 bit private keys. Public keys are 1024 bit for 94 and 512 bit for + 2001 (which is elliptic-curve based). Key exchange algorithms + (VKO R 34.10) are supported on these keys too. + +GOST R 34.11-94 Message digest algorithm. 256-bit hash value + +GOST 28147-89 - Symmetric cipher with 256-bit key. Various modes are + defined in the standard, but only CFB and CNT modes are implemented + in the engine. To make statistical analysis more difficult, key + meshing is supported (see RFC 4357). + +GOST 28147-89 MAC mode. Message authentication code. While most MAC + algorithms out there are based on hash functions using HMAC + algorithm, this algoritm is based on symmetric cipher. + It has 256-bit symmetric key and only 32 bits of MAC value + (while HMAC has same key size and value size). + + It is implemented as combination of EVP_PKEY type and EVP_MD type. + +USAGE OF THESE ALGORITHMS + +This engine is designed to allow usage of this algorithms in the +high-level openssl functions, such as PKI, S/MIME and TLS. + +See RFC 4490 for S/MIME with GOST algorithms and RFC 4491 for PKI. +TLS support is implemented according IETF +draft-chudov-cryptopro-cptls-03.txt and is compatible with +CryptoPro CSP 3.0 and 3.6 as well as with MagPro CSP. +GOST ciphersuites implemented in CryptoPro CSP 2.0 are not supported +because they use ciphersuite numbers used now by AES ciphersuites. + +To use the engine you have to load it via openssl configuration +file. Applications should read openssl configuration file or provide +their own means to load engines. Also, applications which operate with +private keys, should use generic EVP_PKEY API instead of using RSA or +other algorithm-specific API. + +CONFIGURATION FILE + +Configuration file should include following statement in the global +section, i.e. before first bracketed section header (see config(5) for details) + + openssl_conf = openssl_def + +where openssl_def is name of the section in configuration file which +describes global defaults. + +This section should contain following statement: + + [openssl_def] + engines = engine_section + +which points to the section which describes list of the engines to be +loaded. This section should contain: + + [engine_section] + gost = gost_section + +And section which describes configuration of the engine should contain + + [gost_section] + engine_id = gost + dynamic_path = /usr/lib/ssl/engines/libgost.so + default_algorithms = ALL + CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet + +Where engine_id parameter specifies name of engine (should be "gost"). +dynamic_path is a location of the loadable shared library implementing the +engine. If the engine is compiled statically or is located in the OpenSSL +engines directory, this line can be omitted. +default_algorithms parameter specifies that all algorithms, provided by +engine, should be used. + +The CRYPT_PARAMS parameter is engine-specific. It allows the user to choose +between different parameter sets of symmetric cipher algorithm. RFC 4357 +specifies several parameters for the GOST 28147-89 algorithm, but OpenSSL +doesn't provide user interface to choose one when encrypting. So use engine +configuration parameter instead. + +Value of this parameter can be either short name, defined in OpenSSL +obj_dat.h header file or numeric representation of OID, defined in RFC +4357. + +USAGE WITH COMMAND LINE openssl UTILITY + +1. Generation of private key + + openssl genpkey -algorithm gost2001 -pkeyopt paramset:A -out seckey.pem + + Use -algorithm option to specify algorithm. + Use -pkeyopt option to pass paramset to algorithm. The following paramsets + are supported by + gost94: 0,A,B,C,D,XA,XB,XC + gost2001: 0,A,B,C,XA,XB + You can also use numeric representation of OID as to destinate + paramset. + + Paramsets starting with X are intended to use for key exchange keys. + Paramsets without X are for digital signature keys. + + Paramset for both algorithms 0 is the test paramset which should be used + only for test purposes. + +There are no algorithm-specific things with generation of certificate +request once you have a private key. + +2. Generation of certificate request along with private/public keypar + + openssl req -newkey gost2001 -pkeyopt paramset:A + + Syntax of -pkeyopt parameter is identical with genpkey command. + + You can also use oldstyle syntax -newkey gost2001:paramfile, but in + this case you should create parameter file first. + + It can be created with + + openssl genpkey -genparam -algorithm gost2001 -pkeyopt paramset:A\ + -out paramfile. + +3. S/MIME operations + +If you want to send encrypted mail using GOST algorithms, don't forget +to specify -gost89 as encryption algorithm for OpenSSL smime command. +While OpenSSL is clever enough to find out that GOST R 34.11-94 digest +must be used for digital signing with GOST private key, it have no way +to derive symmetric encryption algorithm from key exchange keys. + +4. TLS operations + +OpenSSL supports all four ciphersuites defined in the IETF draft. +Once you've loaded GOST key and certificate into your TLS server, +ciphersuites which use GOST 28147-89 encryption are enabled. + +Ciphersuites with NULL encryption should be enabled explicitely if +needed. + +GOST2001-GOST89-GOST89 Uses GOST R 34.10-2001 for auth and key exchange + GOST 28147-89 for encryption and GOST 28147-89 MAC +GOST94-GOST89-GOST89 Uses GOST R 34.10-94 for auth and key exchange + GOST 28147-89 for encryption and GOST 28147-89 MAC +GOST2001-NULL-GOST94 Uses GOST R 34.10-2001 for auth and key exchange, + no encryption and HMAC, based on GOST R 34.11-94 +GOST94-NULL-GOST94 Uses GOST R 34.10-94 for auth and key exchange, + no encryption and HMAC, based on GOST R 34.11-94 + +Gost 94 and gost 2001 keys can be used simultaneously in the TLS server. +RSA, DSA and EC keys can be used simultaneously with GOST keys, if +server implementation supports loading more than two private +key/certificate pairs. In this case ciphersuites which use any of loaded +keys would be supported and clients can negotiate ones they wish. + +This allows creation of TLS servers which use GOST ciphersuites for +Russian clients and RSA/DSA ciphersuites for foreign clients. + +5. Calculation of digests and symmetric encryption + OpenSSL provides specific commands (like sha1, aes etc) for calculation + of digests and symmetric encryption. Since such commands cannot be + added dynamically, no such commands are provided for GOST algorithms. + Use generic commands 'dgst' and 'enc'. + + Calculation of GOST R 34.11-94 message digest + + openssl dgst -md_gost94 datafile + + Note that GOST R 34.11-94 specifies that digest value should be + interpreted as little-endian number, but OpenSSL outputs just hex dump + of digest value. + + So, to obtain correct digest value, such as produced by gostsum utility + included in the engine distribution, bytes of output should be + reversed. + + Calculation of HMAC based on GOST R 34.11-94 + + openssl dgst -md_gost94 -mac hmac -macopt key:<32 bytes of key> datafile + + (or use hexkey if key contain NUL bytes) + Calculation of GOST 28147 MAC + + openssl dgst -mac gost-mac -macopt key:<32 bytes of key> datafile + + Note absense of an option that specifies digest algorithm. gost-mac + algorithm supports only one digest (which is actually part of + implementation of this mac) and OpenSSL is clever enough to find out + this. + + Encryption with GOST 28147 CFB mode + openssl enc -gost89 -out encrypted-file -in plain-text-file -k + Encryption with GOST 28147 CNT mode + openssl enc -gost89-cnt -out encrypted-file -in plain-text-file -k + + +6. Encrypting private keys and PKCS12 + +To produce PKCS12 files compatible with MagPro CSP, you need to use +GOST algorithm for encryption of PKCS12 file and also GOST R 34.11-94 +hash to derive key from password. + +openssl pksc12 -export -inkey gost.pem -in gost_cert.pem -keypbe gost89\ + -certpbe gost89 -macalg md_gost94 + +7. Testing speed of symmetric ciphers. + +To test performance of GOST symmetric ciphers you should use -evp switch +of the openssl speed command. Engine-provided ciphers couldn't be +accessed by cipher-specific functions, only via generic evp interface + + openssl speed -evp gost89 + openssl speed -evp gost89-cnt + + +PROGRAMMING INTERFACES DETAILS + +Applications never should access engine directly. They only use provided +EVP_PKEY API. But there are some details, which should be taken into +account. + +EVP provides two kinds of API for key exchange: + +1. EVP_PKEY_encrypt/EVP_PKEY_decrypt functions, intended to use with + RSA-like public key encryption algorithms + +2. EVP_PKEY_derive, intended to use with Diffie-Hellman-like shared key +computing algorithms. + +Although VKO R 34.10 algorithms, described in the RFC 4357 are +definitely second case, engine provides BOTH API for GOST R 34.10 keys. + +EVP_PKEY_derive just invokes appropriate VKO algorithm and computes +256 bit shared key. VKO R 34.10-2001 requires 64 bits of random user key +material (UKM). This UKM should be transmitted to other party, so it is +not generated inside derive function. + +It should be set by EVP_PKEY_CTX_ctrl function using +EVP_PKEY_CTRL_SET_IV command after call of EVP_PKEY_derive_init, but +before EVP_PKEY_derive. + unsigned char ukm[8]; + RAND_bytes(ukm,8); + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, 8, ukm) + +EVP_PKEY_encrypt encrypts provided session key with VKO shared key and +packs it into GOST key transport structure, described in the RFC 4490. + +It typically uses ephemeral key pair to compute shared key and packs its +public part along with encrypted key. So, for most cases use of +EVP_PKEY_encrypt/EVP_PKEY_decrypt with GOST keys is almost same as with +RSA. + +However, if peerkey field in the EVP_PKEY_CTX structure is set (using +EVP_PKEY_derive_set_peerkey function) to EVP_PKEY structure which has private +key and uses same parameters as the public key from which this EVP_PKEY_CTX is +created, EVP_PKEY_encrypt will use this private key to compute shared key and +set ephemeral key in the GOST_key_transport structure to NULL. In this case +pkey and peerkey fields in the EVP_PKEY_CTX are used upside-down. + +If EVP_PKEY_decrypt encounters GOST_key_transport structure with NULL +public key field, it tries to use peerkey field from the context to +compute shared key. In this case peerkey field should really contain +peer public key. + +Encrypt operation supports EVP_PKEY_CTRL_SET_IV operation as well. +It can be used when some specific restriction on UKM are imposed by +higher level protocol. For instance, description of GOST ciphersuites +requires UKM to be derived from shared secret. + +If UKM is not set by this control command, encrypt operation would +generate random UKM. + + +This sources include implementation of GOST 28147-89 and GOST R 34.11-94 +which are completely indepentent from OpenSSL and can be used separately +(files gost89.c, gost89.h, gosthash.c, gosthash.h) Utility gostsum (file +gostsum.c) is provided as example of such separate usage. This is +program, simular to md5sum and sha1sum utilities, but calculates GOST R +34.11-94 hash. + +Makefile doesn't include rule for compiling gostsum. +Use command + +$(CC) -o gostsum gostsum.c gost89.c gosthash.c +where $(CC) is name of your C compiler. + +Implementations of GOST R 34.10-xx, including VKO algorithms heavily +depends on OpenSSL BIGNUM and Elliptic Curve libraries. + + diff --git a/crypto/openssl/engines/ccgost/e_gost_err.c b/crypto/openssl/engines/ccgost/e_gost_err.c new file mode 100644 index 0000000000..9a79a374e2 --- /dev/null +++ b/crypto/openssl/engines/ccgost/e_gost_err.c @@ -0,0 +1,212 @@ +/* e_gost_err.c */ +/* ==================================================================== + * Copyright (c) 1999-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). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include "e_gost_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(0,func,0) +#define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA GOST_str_functs[]= + { +{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, +{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"}, +{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"}, +{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"}, +{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"}, +{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"}, +{ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"}, +{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"}, +{ERR_FUNC(GOST_F_GOST2001_KEYGEN), "GOST2001_KEYGEN"}, +{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), "GOST89_GET_ASN1_PARAMETERS"}, +{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), "GOST89_SET_ASN1_PARAMETERS"}, +{ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC), "GOST94_COMPUTE_PUBLIC"}, +{ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"}, +{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, +{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, +{ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"}, +{ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"}, +{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"}, +{ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, +{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, +{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"}, +{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "PKEY_GOST01CP_ENCRYPT"}, +{ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN), "PKEY_GOST01CP_KEYGEN"}, +{ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"}, +{ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE), "PKEY_GOST2001_DERIVE"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT), "PKEY_GOST94CP_DECRYPT"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "PKEY_GOST94CP_ENCRYPT"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CP_KEYGEN), "PKEY_GOST94CP_KEYGEN"}, +{ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN), "PKEY_GOST94_PARAMGEN"}, +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, +{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL), "PKEY_GOST_MAC_CTRL"}, +{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR), "PKEY_GOST_MAC_CTRL_STR"}, +{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN), "PKEY_GOST_MAC_KEYGEN"}, +{ERR_FUNC(GOST_F_PRINT_GOST_01), "PRINT_GOST_01"}, +{ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"}, +{ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"}, +{ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"}, +{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"}, +{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, +{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, +{0,NULL} + }; + +static ERR_STRING_DATA GOST_str_reasons[]= + { +{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"}, +{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"}, +{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"}, +{ERR_REASON(GOST_R_CTRL_CALL_FAILED) ,"ctrl call failed"}, +{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"}, +{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"}, +{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"}, +{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"}, +{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"}, +{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"}, +{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"}, +{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, +{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"}, +{ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"}, +{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"}, +{ERR_REASON(GOST_R_INVALID_PARAMSET) ,"invalid paramset"}, +{ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED),"key is not initalized"}, +{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"}, +{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"}, +{ERR_REASON(GOST_R_MAC_KEY_NOT_SET) ,"mac key not set"}, +{ERR_REASON(GOST_R_MALLOC_FAILURE) ,"malloc failure"}, +{ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"}, +{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"}, +{ERR_REASON(GOST_R_NO_PEER_KEY) ,"no peer key"}, +{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"}, +{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"}, +{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"}, +{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"}, +{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"}, +{ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"}, +{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"}, +{ERR_REASON(GOST_R_UKM_NOT_SET) ,"ukm not set"}, +{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"}, +{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"}, +{0,NULL} + }; + +#endif + +#ifdef GOST_LIB_NAME +static ERR_STRING_DATA GOST_lib_name[]= + { +{0 ,GOST_LIB_NAME}, +{0,NULL} + }; +#endif + + +static int GOST_lib_error_code=0; +static int GOST_error_init=1; + +void ERR_load_GOST_strings(void) + { + if (GOST_lib_error_code == 0) + GOST_lib_error_code=ERR_get_next_error_library(); + + if (GOST_error_init) + { + GOST_error_init=0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(GOST_lib_error_code,GOST_str_functs); + ERR_load_strings(GOST_lib_error_code,GOST_str_reasons); +#endif + +#ifdef GOST_LIB_NAME + GOST_lib_name->error = ERR_PACK(GOST_lib_error_code,0,0); + ERR_load_strings(0,GOST_lib_name); +#endif + } + } + +void ERR_unload_GOST_strings(void) + { + if (GOST_error_init == 0) + { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(GOST_lib_error_code,GOST_str_functs); + ERR_unload_strings(GOST_lib_error_code,GOST_str_reasons); +#endif + +#ifdef GOST_LIB_NAME + ERR_unload_strings(0,GOST_lib_name); +#endif + GOST_error_init=1; + } + } + +void ERR_GOST_error(int function, int reason, char *file, int line) + { + if (GOST_lib_error_code == 0) + GOST_lib_error_code=ERR_get_next_error_library(); + ERR_PUT_error(GOST_lib_error_code,function,reason,file,line); + } diff --git a/crypto/openssl/engines/ccgost/e_gost_err.h b/crypto/openssl/engines/ccgost/e_gost_err.h new file mode 100644 index 0000000000..6dc500079d --- /dev/null +++ b/crypto/openssl/engines/ccgost/e_gost_err.h @@ -0,0 +1,156 @@ +/* ==================================================================== + * Copyright (c) 2001-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). + * + */ + +#ifndef HEADER_GOST_ERR_H +#define HEADER_GOST_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_GOST_strings(void); +void ERR_unload_GOST_strings(void); +void ERR_GOST_error(int function, int reason, char *file, int line); +#define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the GOST functions. */ + +/* Function codes. */ +#define GOST_F_DECODE_GOST_ALGOR_PARAMS 99 +#define GOST_F_ENCODE_GOST_ALGOR_PARAMS 100 +#define GOST_F_FILL_GOST2001_PARAMS 101 +#define GOST_F_FILL_GOST94_PARAMS 102 +#define GOST_F_GET_ENCRYPTION_PARAMS 103 +#define GOST_F_GOST2001_COMPUTE_PUBLIC 104 +#define GOST_F_GOST2001_DO_SIGN 105 +#define GOST_F_GOST2001_DO_VERIFY 106 +#define GOST_F_GOST2001_KEYGEN 107 +#define GOST_F_GOST89_GET_ASN1_PARAMETERS 108 +#define GOST_F_GOST89_SET_ASN1_PARAMETERS 109 +#define GOST_F_GOST94_COMPUTE_PUBLIC 110 +#define GOST_F_GOST_CIPHER_CTL 111 +#define GOST_F_GOST_DO_SIGN 112 +#define GOST_F_GOST_DO_VERIFY 113 +#define GOST_F_GOST_IMIT_CTRL 114 +#define GOST_F_GOST_IMIT_FINAL 140 +#define GOST_F_GOST_IMIT_UPDATE 115 +#define GOST_F_PARAM_COPY_GOST01 116 +#define GOST_F_PARAM_COPY_GOST94 117 +#define GOST_F_PKEY_GOST01CP_DECRYPT 118 +#define GOST_F_PKEY_GOST01CP_ENCRYPT 119 +#define GOST_F_PKEY_GOST01CP_KEYGEN 120 +#define GOST_F_PKEY_GOST01_PARAMGEN 138 +#define GOST_F_PKEY_GOST2001_DERIVE 121 +#define GOST_F_PKEY_GOST94CP_DECRYPT 122 +#define GOST_F_PKEY_GOST94CP_ENCRYPT 123 +#define GOST_F_PKEY_GOST94CP_KEYGEN 124 +#define GOST_F_PKEY_GOST94_PARAMGEN 139 +#define GOST_F_PKEY_GOST_CTRL 125 +#define GOST_F_PKEY_GOST_CTRL01_STR 126 +#define GOST_F_PKEY_GOST_CTRL94_STR 127 +#define GOST_F_PKEY_GOST_MAC_CTRL 128 +#define GOST_F_PKEY_GOST_MAC_CTRL_STR 129 +#define GOST_F_PKEY_GOST_MAC_KEYGEN 130 +#define GOST_F_PRINT_GOST_01 131 +#define GOST_F_PRIV_DECODE_GOST 132 +#define GOST_F_PUB_DECODE_GOST01 133 +#define GOST_F_PUB_DECODE_GOST94 134 +#define GOST_F_PUB_ENCODE_GOST01 135 +#define GOST_F_UNPACK_CC_SIGNATURE 136 +#define GOST_F_UNPACK_CP_SIGNATURE 137 + +/* Reason codes. */ +#define GOST_R_BAD_KEY_PARAMETERS_FORMAT 99 +#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 100 +#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 101 +#define GOST_R_CTRL_CALL_FAILED 132 +#define GOST_R_ERROR_COMPUTING_SHARED_KEY 102 +#define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 103 +#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 104 +#define GOST_R_INCOMPATIBLE_ALGORITHMS 105 +#define GOST_R_INCOMPATIBLE_PEER_KEY 131 +#define GOST_R_INVALID_CIPHER_PARAMS 106 +#define GOST_R_INVALID_CIPHER_PARAM_OID 107 +#define GOST_R_INVALID_DIGEST_TYPE 108 +#define GOST_R_INVALID_GOST94_PARMSET 109 +#define GOST_R_INVALID_IV_LENGTH 110 +#define GOST_R_INVALID_MAC_KEY_LENGTH 111 +#define GOST_R_INVALID_PARAMSET 112 +#define GOST_R_KEY_IS_NOT_INITALIZED 113 +#define GOST_R_KEY_IS_NOT_INITIALIZED 114 +#define GOST_R_KEY_PARAMETERS_MISSING 115 +#define GOST_R_MAC_KEY_NOT_SET 116 +#define GOST_R_MALLOC_FAILURE 117 +#define GOST_R_NO_MEMORY 118 +#define GOST_R_NO_PARAMETERS_SET 119 +#define GOST_R_NO_PEER_KEY 120 +#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 121 +#define GOST_R_PUBLIC_KEY_UNDEFINED 122 +#define GOST_R_RANDOM_GENERATOR_ERROR 123 +#define GOST_R_RANDOM_GENERATOR_FAILURE 124 +#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 125 +#define GOST_R_SIGNATURE_MISMATCH 126 +#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127 +#define GOST_R_UKM_NOT_SET 128 +#define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129 +#define GOST_R_UNSUPPORTED_PARAMETER_SET 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/openssl/engines/ccgost/gost2001.c b/crypto/openssl/engines/ccgost/gost2001.c new file mode 100644 index 0000000000..dacd82d2b9 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost2001.c @@ -0,0 +1,343 @@ +/********************************************************************** + * gost2001.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.10-2001 * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include "gost_lcl.h" +#include "gost_params.h" +#include +#include +#include +#include +#include "e_gost_err.h" +#ifdef DEBUG_SIGN +extern +void dump_signature(const char *message,const unsigned char *buffer,size_t len); +void dump_dsa_sig(const char *message, DSA_SIG *sig); +#else + +#define dump_signature(a,b,c) +#define dump_dsa_sig(a,b) +#endif + +/* + * Fills EC_KEY structure hidden in the app_data field of DSA structure + * with parameter information, extracted from parameter array in + * params.c file. + * + * Also fils DSA->q field with copy of EC_GROUP order field to make + * DSA_size function work + */ +int fill_GOST2001_params(EC_KEY *eckey, int nid) + { + R3410_2001_params *params = R3410_2001_paramset; + EC_GROUP *grp=NULL; + BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL; + EC_POINT *P=NULL; + BN_CTX *ctx=BN_CTX_new(); + int ok=0; + + BN_CTX_start(ctx); + p=BN_CTX_get(ctx); + a=BN_CTX_get(ctx); + b=BN_CTX_get(ctx); + x=BN_CTX_get(ctx); + y=BN_CTX_get(ctx); + q=BN_CTX_get(ctx); + while (params->nid!=NID_undef && params->nid != nid) params++; + if (params->nid == NID_undef) + { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET); + goto err; + } + BN_hex2bn(&p,params->p); + BN_hex2bn(&a,params->a); + BN_hex2bn(&b,params->b); + + grp = EC_GROUP_new_curve_GFp(p,a,b,ctx); + + P = EC_POINT_new(grp); + + BN_hex2bn(&x,params->x); + BN_hex2bn(&y,params->y); + EC_POINT_set_affine_coordinates_GFp(grp,P,x,y,ctx); + BN_hex2bn(&q,params->q); +#ifdef DEBUG_KEYS + fprintf(stderr,"Set params index %d oid %s\nq=", + (params-R3410_2001_paramset),OBJ_nid2sn(params->nid)); + BN_print_fp(stderr,q); + fprintf(stderr,"\n"); +#endif + + EC_GROUP_set_generator(grp,P,q,NULL); + EC_GROUP_set_curve_name(grp,params->nid); + + EC_KEY_set_group(eckey,grp); + ok=1; + err: + EC_POINT_free(P); + EC_GROUP_free(grp); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; + } + + +/* + * Computes gost2001 signature as DSA_SIG structure + * + * + */ +DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) + { + DSA_SIG *newsig = NULL; + BIGNUM *md = hashsum2bn(dgst); + BIGNUM *order = NULL; + const EC_GROUP *group; + const BIGNUM *priv_key; + BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL; + EC_POINT *C=NULL; + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_start(ctx); + OPENSSL_assert(dlen==32); + newsig=DSA_SIG_new(); + if (!newsig) + { + GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY); + goto err; + } + group = EC_KEY_get0_group(eckey); + order=BN_CTX_get(ctx); + EC_GROUP_get_order(group,order,ctx); + priv_key = EC_KEY_get0_private_key(eckey); + e = BN_CTX_get(ctx); + BN_mod(e,md,order,ctx); +#ifdef DEBUG_SIGN + fprintf(stderr,"digest as bignum="); + BN_print_fp(stderr,md); + fprintf(stderr,"\ndigest mod q="); + BN_print_fp(stderr,e); + fprintf(stderr,"\n"); +#endif + if (BN_is_zero(e)) + { + BN_one(e); + } + k =BN_CTX_get(ctx); + C=EC_POINT_new(group); + do + { + do + { + if (!BN_rand_range(k,order)) + { + GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + DSA_SIG_free(newsig); + newsig = NULL; + goto err; + } + if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx)) + { + GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); + DSA_SIG_free(newsig); + newsig = NULL; + goto err; + } + if (!X) X=BN_CTX_get(ctx); + if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) + { + GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); + DSA_SIG_free(newsig); + newsig = NULL; + goto err; + } + if (!r) r=BN_CTX_get(ctx); + BN_nnmod(r,X,order,ctx); + } + while (BN_is_zero(r)); + /* s = (r*priv_key+k*e) mod order */ + if (!tmp) tmp = BN_CTX_get(ctx); + BN_mod_mul(tmp,priv_key,r,order,ctx); + if (!tmp2) tmp2 = BN_CTX_get(ctx); + BN_mod_mul(tmp2,k,e,order,ctx); + if (!s) s=BN_CTX_get(ctx); + BN_mod_add(s,tmp,tmp2,order,ctx); + } + while (BN_is_zero(s)); + + newsig->s=BN_dup(s); + newsig->r=BN_dup(r); + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(C); + BN_free(md); + return newsig; + } +/* + * Verifies gost 2001 signature + * + */ +int gost2001_do_verify(const unsigned char *dgst,int dgst_len, + DSA_SIG *sig, EC_KEY *ec) + { + BN_CTX *ctx=BN_CTX_new(); + const EC_GROUP *group = EC_KEY_get0_group(ec); + BIGNUM *order; + BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL; + BIGNUM *X=NULL,*tmp=NULL; + EC_POINT *C = NULL; + const EC_POINT *pub_key=NULL; + int ok=0; + + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + e = BN_CTX_get(ctx); + z1 = BN_CTX_get(ctx); + z2 = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + X= BN_CTX_get(ctx); + R=BN_CTX_get(ctx); + v=BN_CTX_get(ctx); + + EC_GROUP_get_order(group,order,ctx); + pub_key = EC_KEY_get0_public_key(ec); + if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || + (BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) + { + GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + goto err; + + } + md = hashsum2bn(dgst); + + BN_mod(e,md,order,ctx); +#ifdef DEBUG_SIGN + fprintf(stderr,"digest as bignum: "); + BN_print_fp(stderr,md); + fprintf(stderr,"\ndigest mod q: "); + BN_print_fp(stderr,e); +#endif + if (BN_is_zero(e)) BN_one(e); + v=BN_mod_inverse(v,e,order,ctx); + BN_mod_mul(z1,sig->s,v,order,ctx); + BN_sub(tmp,order,sig->r); + BN_mod_mul(z2,tmp,v,order,ctx); +#ifdef DEBUG_SIGN + fprintf(stderr,"\nInverted digest value: "); + BN_print_fp(stderr,v); + fprintf(stderr,"\nz1: "); + BN_print_fp(stderr,z1); + fprintf(stderr,"\nz2: "); + BN_print_fp(stderr,z2); +#endif + C = EC_POINT_new(group); + if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) + { + GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) + { + GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); + goto err; + } + BN_mod(R,X,order,ctx); +#ifdef DEBUG_SIGN + fprintf(stderr,"\nX="); + BN_print_fp(stderr,X); + fprintf(stderr,"\nX mod q="); + BN_print_fp(stderr,R); + fprintf(stderr,"\n"); +#endif + if (BN_cmp(R,sig->r)!=0) + { + GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH); + } + else + { + ok = 1; + } + err: + EC_POINT_free(C); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_free(md); + return ok; + } +/* + * Computes GOST R 34.10-2001 public key + * + * + */ +int gost2001_compute_public(EC_KEY *ec) + { + const EC_GROUP *group = EC_KEY_get0_group(ec); + EC_POINT *pub_key=NULL; + const BIGNUM *priv_key=NULL; + BN_CTX *ctx=NULL; + int ok=0; + + if (!group) + { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED); + return 0; + } + ctx=BN_CTX_new(); + BN_CTX_start(ctx); + if (!(priv_key=EC_KEY_get0_private_key(ec))) + { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB); + goto err; + } + + pub_key = EC_POINT_new(group); + if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx)) + { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB); + goto err; + } + if (!EC_KEY_set_public_key(ec,pub_key)) + { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB); + goto err; + } + ok = 256; + err: + BN_CTX_end(ctx); + EC_POINT_free(pub_key); + BN_CTX_free(ctx); + return ok; + } +/* + * + * Generates GOST R 34.10-2001 keypair + * + * + */ +int gost2001_keygen(EC_KEY *ec) + { + BIGNUM *order = BN_new(),*d=BN_new(); + const EC_GROUP *group = EC_KEY_get0_group(ec); + EC_GROUP_get_order(group,order,NULL); + + do + { + if (!BN_rand_range(d,order)) + { + GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + BN_free(d); + BN_free(order); + return 0; + } + } + while (BN_is_zero(d)); + EC_KEY_set_private_key(ec,d); + BN_free(d); + BN_free(order); + return gost2001_compute_public(ec); + } + diff --git a/crypto/openssl/engines/ccgost/gost2001_keyx.c b/crypto/openssl/engines/ccgost/gost2001_keyx.c new file mode 100644 index 0000000000..00759bcab0 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost2001_keyx.c @@ -0,0 +1,304 @@ +/********************************************************************** + * gost_keyx.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * VK0 34.10-2001 key exchange and GOST R 34.10-2001 * + * based PKCS7/SMIME support * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include +#include "gost89.h" +#include "gosthash.h" +#include "e_gost_err.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" +#include "gost2001_keyx.h" + + + +/* Implementation of CryptoPro VKO 34.10-2001 algorithm */ +static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,const EC_POINT *pub_key,EC_KEY *priv_key,const unsigned char *ukm) + { + unsigned char ukm_be[8],databuf[64],hashbuf[64]; + BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL; + const BIGNUM* key=EC_KEY_get0_private_key(priv_key); + EC_POINT *pnt=EC_POINT_new(EC_KEY_get0_group(priv_key)); + int i; + gost_hash_ctx hash_ctx; + BN_CTX *ctx = BN_CTX_new(); + + for (i=0;i<8;i++) + { + ukm_be[7-i]=ukm[i]; + } + BN_CTX_start(ctx); + UKM=getbnfrombuf(ukm_be,8); + p=BN_CTX_get(ctx); + order = BN_CTX_get(ctx); + X=BN_CTX_get(ctx); + Y=BN_CTX_get(ctx); + EC_GROUP_get_order(EC_KEY_get0_group(priv_key),order,ctx); + BN_mod_mul(p,key,UKM,order,ctx); + EC_POINT_mul(EC_KEY_get0_group(priv_key),pnt,NULL,pub_key,p,ctx); + EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key), + pnt,X,Y,ctx); + /*Serialize elliptic curve point same way as we do it when saving + * key */ + store_bignum(Y,databuf,32); + store_bignum(X,databuf+32,32); + /* And reverse byte order of whole buffer */ + for (i=0;i<64;i++) + { + hashbuf[63-i]=databuf[i]; + } + init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet); + start_hash(&hash_ctx); + hash_block(&hash_ctx,hashbuf,64); + finish_hash(&hash_ctx,shared_key); + done_gost_hash_ctx(&hash_ctx); + BN_free(UKM); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(pnt); + return 32; + } + + +/* + * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001 + * algorithm + */ +int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + /* Public key of peer in the ctx field peerkey + * Our private key in the ctx pkey + * ukm is in the algorithm specific context data + */ + EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); + EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + + if (!data->shared_ukm) { + GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET); + return 0; + } + + if (key == NULL) { + *keylen = 32; + return 32; + } + + *keylen=VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)), + (EC_KEY *)EVP_PKEY_get0(my_key),data->shared_ukm); + return 1; +} + + + + +/* + * EVP_PKEY_METHOD callback encrypt + * Implementation of GOST2001 key transport, cryptocom variation + */ +/* Generates ephemeral key based on pubk algorithm + * computes shared key using VKO and returns filled up + * GOST_KEY_TRANSPORT structure + */ + +/* + * EVP_PKEY_METHOD callback encrypt + * Implementation of GOST2001 key transport, cryptopo variation + */ + +int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) + { + GOST_KEY_TRANSPORT *gkt=NULL; + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); + const struct gost_cipher_info *param=get_encryption_params(NULL); + unsigned char ukm[8], shared_key[32], crypted_key[44]; + int ret=0; + int key_is_ephemeral=1; + gost_ctx cctx; + EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx); + if (data->shared_ukm) + { + memcpy(ukm, data->shared_ukm,8); + } + else if (out) + { + + if (RAND_bytes(ukm,8)<=0) + { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_RANDOM_GENERATOR_FAILURE); + return 0; + } + } + /* Check for private key in the peer_key of context */ + if (sec_key) + { + key_is_ephemeral=0; + if (!gost_get0_priv_key(sec_key)) + { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + goto err; + } + } + else + { + key_is_ephemeral=1; + if (out) + { + sec_key = EVP_PKEY_new(); + EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new()); + EVP_PKEY_copy_parameters(sec_key,pubk); + if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) + { + goto err; + } + } + } + if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) + { + param= gost_cipher_list+1; + } + if (out) + { + VKO_compute_key(shared_key,32,EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),EVP_PKEY_get0(sec_key),ukm); + gost_init(&cctx,param->sblock); + keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key); + } + gkt = GOST_KEY_TRANSPORT_new(); + if (!gkt) + { + goto err; + } + if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, + ukm,8)) + { + goto err; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) + { + goto err; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) + { + goto err; + } + if (key_is_ephemeral) { + if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk)) + { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + goto err; + } + } + ASN1_OBJECT_free(gkt->key_agreement_info->cipher); + gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); + if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key); + if (!key_is_ephemeral) + { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) + { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1; + GOST_KEY_TRANSPORT_free(gkt); + return ret; + err: + if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key); + GOST_KEY_TRANSPORT_free(gkt); + return -1; + } +/* + * EVP_PKEY_METHOD callback decrypt + * Implementation of GOST2001 key transport, cryptopo variation + */ +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_len, const unsigned char *in, size_t in_len) + { + const unsigned char *p = in; + EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); + GOST_KEY_TRANSPORT *gkt = NULL; + int ret=0; + unsigned char wrappedKey[44]; + unsigned char sharedKey[32]; + gost_ctx ctx; + const struct gost_cipher_info *param=NULL; + EVP_PKEY *eph_key=NULL, *peerkey=NULL; + + if (!key) + { + *key_len = 32; + return 1; + } + gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p, + in_len); + if (!gkt) + { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); + return -1; + } + + /* If key transport structure contains public key, use it */ + eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); + if (eph_key) + { + if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) + { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_INCOMPATIBLE_PEER_KEY); + goto err; + } + } + else + { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) + { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + peerkey = EVP_PKEY_CTX_get0_peerkey(pctx); + if (!peerkey) + { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_NO_PEER_KEY); + goto err; + } + + param = get_encryption_params(gkt->key_agreement_info->cipher); + gost_init(&ctx,param->sblock); + OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8); + memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8); + OPENSSL_assert(gkt->key_info->encrypted_key->length==32); + memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32); + OPENSSL_assert(gkt->key_info->imit->length==4); + memcpy(wrappedKey+40,gkt->key_info->imit->data,4); + VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)), + EVP_PKEY_get0(priv),wrappedKey); + if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key)) + { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + + ret=1; +err: + if (eph_key) EVP_PKEY_free(eph_key); + if (gkt) GOST_KEY_TRANSPORT_free(gkt); + return ret; + } diff --git a/crypto/openssl/engines/ccgost/gost2001_keyx.h b/crypto/openssl/engines/ccgost/gost2001_keyx.h new file mode 100644 index 0000000000..a014d9c1e2 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost2001_keyx.h @@ -0,0 +1,10 @@ +GOST_KEY_TRANSPORT * +make_rfc4490_keytransport_2001(EVP_PKEY *pubk, BIGNUM *eph_key, + const unsigned char *key, size_t keylen, + unsigned char *ukm, size_t ukm_len); + +int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv, + GOST_KEY_TRANSPORT *gkt, + unsigned char *key_buf, + int key_buf_len) ; + diff --git a/crypto/openssl/engines/ccgost/gost89.c b/crypto/openssl/engines/ccgost/gost89.c new file mode 100644 index 0000000000..7ebae0f71f --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost89.c @@ -0,0 +1,409 @@ +/********************************************************************** + * gost89.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST 28147-89 encryption algorithm * + * No OpenSSL libraries required to compile and use * + * this code * + **********************************************************************/ +#include +#include "gost89.h" +/* Substitution blocks from RFC 4357 + + Note: our implementation of gost 28147-89 algorithm + uses S-box matrix rotated 90 degrees counterclockwise, relative to + examples given in RFC. + + +*/ + +/* Substitution blocks from test examples for GOST R 34.11-94*/ +gost_subst_block GostR3411_94_TestParamSet = { + {0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC}, + {0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC}, + {0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE}, + {0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2}, + {0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3}, + {0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB}, + {0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9}, + {0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3} + }; +/* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */ +gost_subst_block GostR3411_94_CryptoProParamSet= { + {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC}, + {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB}, + {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3}, + {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5}, + {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3}, + {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD}, + {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8}, + {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF} + } ; + +/* Test paramset from GOST 28147 */ +gost_subst_block Gost28147_TestParamSet = + { + {0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8}, + {0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD}, + {0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4}, + {0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4}, + {0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8}, + {0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB}, + {0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5}, + {0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6} + }; + + + + +/* 1.2.643.2.2.31.1 */ +gost_subst_block Gost28147_CryptoProParamSetA= { + {0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4}, + {0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE}, + {0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6}, + {0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6}, + {0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6}, + {0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9}, + {0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1}, + {0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5} + }; +/* 1.2.643.2.2.31.2 */ +gost_subst_block Gost28147_CryptoProParamSetB= + { + {0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC}, + {0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE}, + {0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5}, + {0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3}, + {0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8}, + {0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4}, + {0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE}, + {0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF} + }; +/* 1.2.643.2.2.31.3 */ +gost_subst_block Gost28147_CryptoProParamSetC= + { + {0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8}, + {0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7}, + {0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD}, + {0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7}, + {0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4}, + {0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB}, + {0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3}, + {0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3} + }; + +/* 1.2.643.2.2.31.4 */ +gost_subst_block Gost28147_CryptoProParamSetD= + { + {0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE}, + {0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7}, + {0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6}, + {0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1}, + {0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8}, + {0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2}, + {0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1}, + {0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3} + }; + + +const byte CryptoProKeyMeshingKey[]={ + 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23, + 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4, + 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12, + 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B + }; +/* Initialization of gost_ctx subst blocks*/ +static void kboxinit(gost_ctx *c, const gost_subst_block *b) + { + int i; + + for (i = 0; i < 256; i++) + { + c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24; + c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16; + c->k43[i] = (b->k4[i>>4] <<4 | b->k3 [i &15])<<8; + c->k21[i] = b->k2[i>>4] <<4 | b->k1 [i &15]; + + } + } + +/* Part of GOST 28147 algorithm moved into separate function */ +static word32 f(gost_ctx *c,word32 x) + { + x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]| + c->k43[x>> 8 & 255] | c->k21[x & 255]; + /* Rotate left 11 bits */ + return x<<11 | x>>(32-11); + } +/* Low-level encryption routine - encrypts one 64 bit block*/ +void gostcrypt(gost_ctx *c, const byte *in, byte *out) + { + register word32 n1, n2; /* As named in the GOST */ + n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); + n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); + /* Instead of swapping halves, swap names each round */ + + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + + n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]); + n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]); + n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]); + n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); + + out[0] = (byte)(n2&0xff); out[1] = (byte)((n2>>8)&0xff); + out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24); + out[4] = (byte)(n1&0xff); out[5] = (byte)((n1>>8)&0xff); + out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24); + } +/* Low-level decryption routine. Decrypts one 64-bit block */ +void gostdecrypt(gost_ctx *c, const byte *in,byte *out) + { + register word32 n1, n2; /* As named in the GOST */ + n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); + n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); + + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + + n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]); + n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]); + n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]); + n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); + + n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]); + n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]); + n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]); + n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); + + n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]); + n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]); + n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]); + n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); + + out[0] = (byte)(n2&0xff); out[1] = (byte)((n2>>8)&0xff); + out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24); + out[4] = (byte)(n1&0xff); out[5] = (byte)((n1>>8)&0xff); + out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24); + } + +/* Encrypts several blocks in ECB mode */ +void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks) + { + int i; + for(i=0;ik[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24); + } + } + +/* Retrieve 256-bit key from context */ +void gost_get_key(gost_ctx *c, byte *k) + { + int i,j; + for(i=0,j=0;i<8;i++,j+=4) + { + k[j]=(byte)(c->k[i]& 0xFF); + k[j+1]=(byte)((c->k[i]>>8 )&0xFF); + k[j+2]=(byte)((c->k[i]>>16) &0xFF); + k[j+3]=(byte)((c->k[i]>>24) &0xFF); + } + } + +/* Initalize context. Provides default value for subst_block */ +void gost_init(gost_ctx *c, const gost_subst_block *b) + { + if(!b) + { + b=&GostR3411_94_TestParamSet; + } + kboxinit(c,b); + } + +/* Cleans up key from context */ +void gost_destroy(gost_ctx *c) + { + int i; for(i=0;i<8;i++) c->k[i]=0; + } + +/* Compute GOST 28147 mac block + * + * Parameters + * gost_ctx *c - context initalized with substitution blocks and key + * buffer - 8-byte mac state buffer + * block 8-byte block to process. + * */ +void mac_block(gost_ctx *c,byte *buffer,const byte *block) + { + register word32 n1, n2; /* As named in the GOST */ + int i; + for (i=0; i<8; i++) + { + buffer[i]^=block[i]; + } + n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24); + n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24); + /* Instead of swapping halves, swap names each round */ + + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + + buffer[0] = (byte)(n1&0xff); buffer[1] = (byte)((n1>>8)&0xff); + buffer[2] = (byte)((n1>>16)&0xff); buffer[3] = (byte)(n1>>24); + buffer[4] = (byte)(n2&0xff); buffer[5] = (byte)((n2>>8)&0xff); + buffer[6] = (byte)((n2>>16)&0xff); buffer[7] = (byte)(n2>>24); + } + +/* Get mac with specified number of bits from MAC state buffer */ +void get_mac(byte *buffer,int nbits,byte *out) + { + int nbytes= nbits >> 3; + int rembits = nbits & 7; + int mask =rembits?((1 2147483647L +typedef unsigned int u4; +#else +typedef unsigned long u4; +#endif +/* Typedef for unsigned 8-bit integer */ +typedef unsigned char byte; + +/* Internal representation of GOST substitution blocks */ +typedef struct { + byte k8[16]; + byte k7[16]; + byte k6[16]; + byte k5[16]; + byte k4[16]; + byte k3[16]; + byte k2[16]; + byte k1[16]; +} gost_subst_block; + + +/* Cipher context includes key and preprocessed substitution block */ +typedef struct { + u4 k[8]; + /* Constant s-boxes -- set up in gost_init(). */ + u4 k87[256],k65[256],k43[256],k21[256]; +} gost_ctx; +/* Note: encrypt and decrypt expect full blocks--padding blocks is + caller's responsibility. All bulk encryption is done in + ECB mode by these calls. Other modes may be added easily + enough. */ +/* Encrypt several full blocks in ECB mode */ +void gost_enc(gost_ctx *ctx, const byte *clear,byte *cipher, int blocks); +/* Decrypt several full blocks in ECB mode */ +void gost_dec(gost_ctx *ctx, const byte *cipher,byte *clear, int blocks); +/* Encrypts several full blocks in CFB mode using 8byte IV */ +void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher,int blocks); +/* Decrypts several full blocks in CFB mode using 8byte IV */ +void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,int blocks); + +/* Encrypt one block */ +void gostcrypt(gost_ctx *c, const byte *in, byte *out); +/* Decrypt one block */ +void gostdecrypt(gost_ctx *c, const byte *in,byte *out); +/* Set key into context */ +void gost_key(gost_ctx *ctx, const byte *key); +/* Get key from context */ +void gost_get_key(gost_ctx *ctx, byte *key); +/* Set S-blocks into context */ +void gost_init(gost_ctx *ctx, const gost_subst_block *subst_block); +/* Clean up context */ +void gost_destroy(gost_ctx *ctx); +/* Intermediate function used for calculate hash */ +void gost_enc_with_key(gost_ctx *,byte *key,byte *inblock,byte *outblock); +/* Compute MAC of given length in bits from data */ +int gost_mac(gost_ctx *ctx,int hmac_len,const unsigned char *data, + unsigned int data_len,unsigned char *hmac) ; +/* Compute MAC of given length in bits from data, using non-zero 8-byte + * IV (non-standard, for use in CryptoPro key transport only */ +int gost_mac_iv(gost_ctx *ctx,int hmac_len,const unsigned char *iv,const unsigned char *data, + unsigned int data_len,unsigned char *hmac) ; +/* Perform one step of MAC calculation like gostcrypt */ +void mac_block(gost_ctx *c,byte *buffer,const byte *block); +/* Extracts MAC value from mac state buffer */ +void get_mac(byte *buffer,int nbits,byte *out); +/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/ +void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv); +/* Parameter sets specified in RFC 4357 */ +extern gost_subst_block GostR3411_94_TestParamSet; +extern gost_subst_block GostR3411_94_CryptoProParamSet; +extern gost_subst_block Gost28147_TestParamSet; +extern gost_subst_block Gost28147_CryptoProParamSetA; +extern gost_subst_block Gost28147_CryptoProParamSetB; +extern gost_subst_block Gost28147_CryptoProParamSetC; +extern gost_subst_block Gost28147_CryptoProParamSetD; +extern const byte CryptoProKeyMeshingKey[]; +#if __LONG_MAX__ > 2147483647L +typedef unsigned int word32; +#else +typedef unsigned long word32; +#endif + +#endif diff --git a/crypto/openssl/engines/ccgost/gost94_keyx.c b/crypto/openssl/engines/ccgost/gost94_keyx.c new file mode 100644 index 0000000000..624be586a5 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost94_keyx.c @@ -0,0 +1,287 @@ +/********************************************************************** + * gost94_keyx.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implements generation and parsing of GOST_KEY_TRANSPORT for * + * GOST R 34.10-94 algorithms * + * * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include +#include + +#include "gost89.h" +#include "gosthash.h" +#include "e_gost_err.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" +/* Common functions for both 94 and 2001 key exchange schemes */ +/* Implementation of the Diffi-Hellman key agreement scheme based on + * GOST-94 keys */ + +/* Computes Diffie-Hellman key and stores it into buffer in + * little-endian byte order as expected by both versions of GOST 94 + * algorithm + */ +static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) + { + unsigned char be_key[128]; + int i,key_size; + key_size=DH_compute_key(be_key,pub_key,dh); + if (!key_size) return 0; + memset(pair_key,0,128); + for (i=0;ig = BN_dup(pubk->pkey.dsa->g); + dh->p = BN_dup(pubk->pkey.dsa->p); + dh->priv_key = BN_dup(priv_key); + ret=compute_pair_key_le(dh_key,((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,dh) ; + DH_free(dh); + if (!ret) return 0; + init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet); + start_hash(&hash_ctx); + hash_block(&hash_ctx,dh_key,128); + finish_hash(&hash_ctx,shared_key); + done_gost_hash_ctx(&hash_ctx); + return 1; + } + +/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */ + +int pkey_gost94_derive(EVP_PKEY_CTX *ctx,unsigned char *key,size_t *keylen) + { + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx); + EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx); + *keylen = 32; + if (key == NULL) return 1; + + return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key); + } + +/* EVP_PKEY_METHOD callback encrypt for + * GOST R 34.10-94 cryptopro modification + */ + + +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) + { + GOST_KEY_TRANSPORT *gkt=NULL; + unsigned char shared_key[32], ukm[8],crypted_key[44]; + const struct gost_cipher_info *param=get_encryption_params(NULL); + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + gost_ctx cctx; + int key_is_ephemeral=1; + EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx); + + /* Do not use vizir cipher parameters with cryptopro */ + if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) + { + param= gost_cipher_list+1; + } + + if (mykey) + { + /* If key already set, it is not ephemeral */ + key_is_ephemeral=0; + if (!gost_get0_priv_key(mykey)) + { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + goto err; + } + } + else + { + /* Otherwise generate ephemeral key */ + key_is_ephemeral = 1; + if (out) + { + mykey = EVP_PKEY_new(); + EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new()); + EVP_PKEY_copy_parameters(mykey,pubk); + if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) + { + goto err; + } + } + } + if (out) + make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key); + if (data->shared_ukm) + { + memcpy(ukm,data->shared_ukm,8); + } + else if (out) + { + if (RAND_bytes(ukm,8)<=0) + { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_RANDOM_GENERATOR_FAILURE); + goto err; + } + } + + if (out) { + gost_init(&cctx,param->sblock); + keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key); + } + gkt = GOST_KEY_TRANSPORT_new(); + if (!gkt) + { + goto memerr; + } + if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, + ukm,8)) + { + goto memerr; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) + { + goto memerr; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) + { + goto memerr; + } + if (key_is_ephemeral) { + if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk)) + { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + goto err; + } + if (out) EVP_PKEY_free(mykey); + } + ASN1_OBJECT_free(gkt->key_agreement_info->cipher); + gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); + *outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL); + if (*outlen <= 0) + { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO); + goto err; + } + if (!key_is_ephemeral) + { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) + { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + GOST_KEY_TRANSPORT_free(gkt); + return 1; + memerr: + if (key_is_ephemeral) { + EVP_PKEY_free(mykey); + } + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_MALLOC_FAILURE); + err: + GOST_KEY_TRANSPORT_free(gkt); + return -1; + } + + +/* EVP_PLEY_METHOD callback decrypt for + * GOST R 34.10-94 cryptopro modification + */ +int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) { + const unsigned char *p = in; + GOST_KEY_TRANSPORT *gkt = NULL; + unsigned char wrappedKey[44]; + unsigned char sharedKey[32]; + gost_ctx cctx; + const struct gost_cipher_info *param=NULL; + EVP_PKEY *eph_key=NULL, *peerkey=NULL; + EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); + + if (!key) + { + *key_len = 32; + return 1; + } + + gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p, + in_len); + if (!gkt) + { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); + return 0; + } + eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); + if (eph_key) + { + if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0) + { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_INCOMPATIBLE_PEER_KEY); + goto err; + } + } + else + { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) + { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + peerkey = EVP_PKEY_CTX_get0_peerkey(ctx); + if (!peerkey) + { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_NO_PEER_KEY); + goto err; + } + + param = get_encryption_params(gkt->key_agreement_info->cipher); + gost_init(&cctx,param->sblock); + OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8); + memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8); + OPENSSL_assert(gkt->key_info->encrypted_key->length==32); + memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32); + OPENSSL_assert(gkt->key_info->imit->length==4); + memcpy(wrappedKey+40,gkt->key_info->imit->data,4); + make_cp_exchange_key(gost_get0_priv_key(priv),peerkey,sharedKey); + if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key)) + { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + + EVP_PKEY_free(eph_key); + GOST_KEY_TRANSPORT_free(gkt); + return 1; +err: + EVP_PKEY_free(eph_key); + GOST_KEY_TRANSPORT_free(gkt); + return -1; + } + diff --git a/crypto/openssl/engines/ccgost/gost_ameth.c b/crypto/openssl/engines/ccgost/gost_ameth.c new file mode 100644 index 0000000000..f620a216c8 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_ameth.c @@ -0,0 +1,910 @@ +/********************************************************************** + * gost_ameth.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of RFC 4490/4491 ASN1 method * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "gost_params.h" +#include "gost_lcl.h" +#include "e_gost_err.h" + +int gost94_nid_by_params(DSA *p) + { + R3410_params *gost_params; + BIGNUM *q=BN_new(); + for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) + { + BN_dec2bn(&q,gost_params->q); + if (!BN_cmp(q,p->q)) + { + BN_free(q); + return gost_params->nid; + } + } + BN_free(q); + return NID_undef; + } + +static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) + { + ASN1_STRING *params = ASN1_STRING_new(); + GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); + int pkey_param_nid = NID_undef; + int cipher_param_nid = NID_undef; + if (!params || !gkp) + { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, + ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + switch (EVP_PKEY_base_id(key)) + { + case NID_id_GostR3410_2001: + pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key))); + cipher_param_nid = get_encryption_params(NULL)->nid; + break; + case NID_id_GostR3410_94: + pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); + if (pkey_param_nid == NID_undef) + { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, + GOST_R_INVALID_GOST94_PARMSET); + ASN1_STRING_free(params); + params=NULL; + goto err; + } + cipher_param_nid = get_encryption_params(NULL)->nid; + break; + } + gkp->key_params = OBJ_nid2obj(pkey_param_nid); + gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); + /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);*/ + params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); + if (params->length <=0 ) + { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, + ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + params ->type = V_ASN1_SEQUENCE; + err: + GOST_KEY_PARAMS_free(gkp); + return params; + } + +/* Parses GOST algorithm parameters from X509_ALGOR and + * modifies pkey setting NID and parameters + */ +static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) + { + ASN1_OBJECT *palg_obj =NULL; + int ptype = V_ASN1_UNDEF; + int pkey_nid = NID_undef,param_nid = NID_undef; + void *_pval; + ASN1_STRING *pval = NULL; + const unsigned char *p; + GOST_KEY_PARAMS *gkp = NULL; + + X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); + pval = _pval; + if (ptype != V_ASN1_SEQUENCE) + { + GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, + GOST_R_BAD_KEY_PARAMETERS_FORMAT); + return 0; + } + p=pval->data; + pkey_nid = OBJ_obj2nid(palg_obj); + + gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length); + if (!gkp) + { + GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, + GOST_R_BAD_PKEY_PARAMETERS_FORMAT); + return 0; + } + param_nid = OBJ_obj2nid(gkp->key_params); + GOST_KEY_PARAMS_free(gkp); + EVP_PKEY_set_type(pkey,pkey_nid); + switch (pkey_nid) + { + case NID_id_GostR3410_94: + { + DSA *dsa= EVP_PKEY_get0(pkey); + if (!dsa) + { + dsa = DSA_new(); + if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0; + } + if (!fill_GOST94_params(dsa,param_nid)) return 0; + break; + } + case NID_id_GostR3410_2001: + { + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (!ec) + { + ec = EC_KEY_new(); + if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0; + } + if (!fill_GOST2001_params(ec,param_nid)) return 0; + } + } + + return 1; + } + +static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) + { + switch (EVP_PKEY_base_id(pkey)) + { + case NID_id_GostR3410_94: + { + DSA *dsa = EVP_PKEY_get0(pkey); + if (!dsa) + { + dsa = DSA_new(); + EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa); + } + dsa->priv_key = BN_dup(priv); + if (!EVP_PKEY_missing_parameters(pkey)) + gost94_compute_public(dsa); + break; + } + case NID_id_GostR3410_2001: + { + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (!ec) + { + ec = EC_KEY_new(); + EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec); + } + if (!EC_KEY_set_private_key(ec,priv)) return 0; + if (!EVP_PKEY_missing_parameters(pkey)) + gost2001_compute_public(ec); + break; + } + } + return 1; + } +BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) + { + switch (EVP_PKEY_base_id(pkey)) + { + case NID_id_GostR3410_94: + { + DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); + if (!dsa) + { + return NULL; + } + if (!dsa->priv_key) return NULL; + return dsa->priv_key; + break; + } + case NID_id_GostR3410_2001: + { + EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); + const BIGNUM* priv; + if (!ec) + { + return NULL; + } + if (!(priv=EC_KEY_get0_private_key(ec))) return NULL; + return (BIGNUM *)priv; + break; + } + } + return NULL; + } + +static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, + long arg1, void *arg2) + { + switch (op) + { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + { + X509_ALGOR *alg1 = NULL, *alg2 = NULL; + int nid = EVP_PKEY_base_id(pkey); + PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2, + NULL, &alg1, &alg2); + X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), + V_ASN1_NULL, 0); + if (nid == NID_undef) + { + return (-1); + } + X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); + } + return 1; + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) + { + X509_ALGOR *alg; + ASN1_STRING * params = encode_gost_algor_params(pkey); + if (!params) + { + return -1; + } + PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg); + X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), + V_ASN1_SEQUENCE, params); + } + return 1; + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_id_GostR3411_94; + return 2; + } + + return -2; + } +/*----------------------- free functions * ------------------------------*/ +static void pkey_free_gost94(EVP_PKEY *key) + { + if (key->pkey.dsa) + { + DSA_free(key->pkey.dsa); + } + } + +static void pkey_free_gost01(EVP_PKEY *key) + { + if (key->pkey.ec) + { + EC_KEY_free(key->pkey.ec); + } + } + +/* ------------------ private key functions -----------------------------*/ +static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) + { + const unsigned char *pkey_buf = NULL,*p=NULL; + int priv_len = 0; + BIGNUM *pk_num=NULL; + int ret =0; + X509_ALGOR *palg =NULL; + ASN1_OBJECT *palg_obj = NULL; + ASN1_INTEGER *priv_key=NULL; + + if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) + return 0; + p = pkey_buf; + if (!decode_gost_algor_params(pk,palg)) + { + return 0; + } + if (V_ASN1_OCTET_STRING == *p) + { + /* New format - Little endian octet string */ + unsigned char rev_buf[32]; + int i; + ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len); + if (!s||s->length !=32) + { + GOSTerr(GOST_F_PRIV_DECODE_GOST, + EVP_R_DECODE_ERROR); + return 0; + } + for (i=0;i<32;i++) + { + rev_buf[31-i]=s->data[i]; + } + ASN1_STRING_free(s); + pk_num = getbnfrombuf(rev_buf,32); + } + else + { + priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len); + if (!priv_key) return 0; + ret= ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ; + ASN1_INTEGER_free(priv_key); + if (!ret) + { + GOSTerr(GOST_F_PRIV_DECODE_GOST, + EVP_R_DECODE_ERROR); + return 0; + } + } + + ret= gost_set_priv_key(pk,pk_num); + BN_free(pk_num); + return ret; + } + +/* ----------------------------------------------------------------------*/ +static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) + { + ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + ASN1_STRING *params = encode_gost_algor_params(pk); + unsigned char *priv_buf = NULL; + int priv_len; + + ASN1_INTEGER *asn1key=NULL; + if (!params) + { + return 0; + } + asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL); + priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf); + ASN1_INTEGER_free(asn1key); + return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params, + priv_buf,priv_len); + } +/* --------- printing keys --------------------------------*/ +static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) + { + int param_nid = NID_undef; + + if (type == 2) + { + BIGNUM *key; + + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Private key: "); + key = gost_get0_priv_key(pkey); + if (!key) + BIO_printf(out,""); + else + BN_print(out,key); + BIO_printf(out,"\n"); + } + if (type >= 1) + { + BIGNUM *pubkey; + + pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; + BIO_indent(out,indent,128); + BIO_printf(out,"Public key: "); + BN_print(out,pubkey); + BIO_printf(out,"\n"); + } + + param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); + BIO_indent(out,indent,128); + BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid)); + return 1; +} + +static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_94(out, pkey, indent, pctx,0); + } + +static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_94(out,pkey, indent, pctx,1); + } +static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_94(out,pkey,indent,pctx,2); + } + +static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) + { + int param_nid = NID_undef; + if (type == 2) + { + BIGNUM *key; + + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Private key: "); + key = gost_get0_priv_key(pkey); + if (!key) + BIO_printf(out,"= 1) + { + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *X,*Y; + const EC_POINT *pubkey; + const EC_GROUP *group; + + if (!ctx) + { + GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); + group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); + if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) + { + GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB); + BN_CTX_free(ctx); + return 0; + } + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Public key:\n"); + if (!BIO_indent(out,indent+3,128)) return 0; + BIO_printf(out,"X:"); + BN_print(out,X); + BIO_printf(out,"\n"); + BIO_indent(out,indent+3,128); + BIO_printf(out,"Y:"); + BN_print(out,Y); + BIO_printf(out,"\n"); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid)); + return 1; +} +static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_01(out,pkey,indent,pctx,0); + } +static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_01(out,pkey, indent, pctx,1); + } +static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_01(out,pkey,indent,pctx,2); + } +/* ---------------------------------------------------------------------*/ +static int param_missing_gost94(const EVP_PKEY *pk) + { + const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); + if (!dsa) return 1; + if (!dsa->q) return 1; + return 0; + } + +static int param_missing_gost01(const EVP_PKEY *pk) + { + const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); + if (!ec) return 1; + if (!EC_KEY_get0_group(ec)) return 1; + return 0; + } + +static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) + { + const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); + DSA *dto = EVP_PKEY_get0(to); + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) + { + GOSTerr(GOST_F_PARAM_COPY_GOST94, + GOST_R_INCOMPATIBLE_ALGORITHMS); + return 0; + } + if (!dfrom) + { + GOSTerr(GOST_F_PARAM_COPY_GOST94, + GOST_R_KEY_PARAMETERS_MISSING); + return 0; + } + if (!dto) + { + dto = DSA_new(); + EVP_PKEY_assign(to,EVP_PKEY_base_id(from),dto); + } +#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); + COPYBIGNUM(dto,dfrom,p) + COPYBIGNUM(dto,dfrom,q) + COPYBIGNUM(dto,dfrom,g) + + if (dto->priv_key) + gost94_compute_public(dto); + return 1; + } +static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) + { + EC_KEY *eto = EVP_PKEY_get0(to); + const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) + { + GOSTerr(GOST_F_PARAM_COPY_GOST01, + GOST_R_INCOMPATIBLE_ALGORITHMS); + return 0; + } + if (!efrom) + { + GOSTerr(GOST_F_PARAM_COPY_GOST01, + GOST_R_KEY_PARAMETERS_MISSING); + return 0; + } + if (!eto) + { + eto = EC_KEY_new(); + EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto); + } + EC_KEY_set_group(eto,EC_KEY_get0_group(efrom)); + if (EC_KEY_get0_private_key(eto)) + { + gost2001_compute_public(eto); + } + return 1; + } + +static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) + { + const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); + const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); + if (!BN_cmp(da->q,db->q)) return 1; + return 0; + } + +static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a)))== + EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b)))) + { + return 1; + } + return 0; + + } + +/* ---------- Public key functions * --------------------------------------*/ +static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) + { + X509_ALGOR *palg = NULL; + const unsigned char *pubkey_buf = NULL; + unsigned char *databuf; + ASN1_OBJECT *palgobj = NULL; + int pub_len,i,j; + DSA *dsa; + ASN1_OCTET_STRING *octet= NULL; + + if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, + &palg, pub)) return 0; + EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL); + if (!decode_gost_algor_params(pk,palg)) return 0; + octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len); + if (!octet) + { + GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE); + return 0; + } + databuf = OPENSSL_malloc(octet->length); + for (i=0,j=octet->length-1;ilength;i++,j--) + { + databuf[j]=octet->data[i]; + } + dsa = EVP_PKEY_get0(pk); + dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL); + ASN1_OCTET_STRING_free(octet); + OPENSSL_free(databuf); + return 1; + + } + +static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk) + { + ASN1_OBJECT *algobj = NULL; + ASN1_OCTET_STRING *octet = NULL; + void *pval = NULL; + unsigned char *buf=NULL,*databuf,*sptr; + int i,j,data_len,ret=0; + + int ptype = V_ASN1_UNDEF; + DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); + algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + if (pk->save_parameters) + { + ASN1_STRING *params = encode_gost_algor_params(pk); + pval = params; + ptype = V_ASN1_SEQUENCE; + } + data_len = BN_num_bytes(dsa->pub_key); + databuf = OPENSSL_malloc(data_len); + BN_bn2bin(dsa->pub_key,databuf); + octet = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(octet,NULL,data_len); + sptr = ASN1_STRING_data(octet); + for (i=0,j=data_len-1; i< data_len;i++,j--) + { + sptr[i]=databuf[j]; + } + OPENSSL_free(databuf); + ret = i2d_ASN1_OCTET_STRING(octet,&buf); + ASN1_BIT_STRING_free(octet); + if (ret <0) return 0; + return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); + } + +static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) + { + X509_ALGOR *palg = NULL; + const unsigned char *pubkey_buf = NULL; + unsigned char *databuf; + ASN1_OBJECT *palgobj = NULL; + int pub_len,i,j; + EC_POINT *pub_key; + BIGNUM *X,*Y; + ASN1_OCTET_STRING *octet= NULL; + int len; + const EC_GROUP *group; + + if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, + &palg, pub)) return 0; + EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL); + if (!decode_gost_algor_params(pk,palg)) return 0; + group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); + octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len); + if (!octet) + { + GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE); + return 0; + } + databuf = OPENSSL_malloc(octet->length); + for (i=0,j=octet->length-1;ilength;i++,j--) + { + databuf[j]=octet->data[i]; + } + len=octet->length/2; + ASN1_OCTET_STRING_free(octet); + + Y= getbnfrombuf(databuf,len); + X= getbnfrombuf(databuf+len,len); + OPENSSL_free(databuf); + pub_key = EC_POINT_new(group); + if (!EC_POINT_set_affine_coordinates_GFp(group + ,pub_key,X,Y,NULL)) + { + GOSTerr(GOST_F_PUB_DECODE_GOST01, + ERR_R_EC_LIB); + EC_POINT_free(pub_key); + BN_free(X); + BN_free(Y); + return 0; + } + BN_free(X); + BN_free(Y); + if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key)) + { + GOSTerr(GOST_F_PUB_DECODE_GOST01, + ERR_R_EC_LIB); + EC_POINT_free(pub_key); + return 0; + } + EC_POINT_free(pub_key); + return 1; + + } + +static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) + { + ASN1_OBJECT *algobj = NULL; + ASN1_OCTET_STRING *octet = NULL; + void *pval = NULL; + unsigned char *buf=NULL,*databuf,*sptr; + int i,j,data_len,ret=0; + const EC_POINT *pub_key; + BIGNUM *X,*Y,*order; + const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); + int ptype = V_ASN1_UNDEF; + + algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + if (pk->save_parameters) + { + ASN1_STRING *params = encode_gost_algor_params(pk); + pval = params; + ptype = V_ASN1_SEQUENCE; + } + order = BN_new(); + EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL); + pub_key=EC_KEY_get0_public_key(ec); + if (!pub_key) + { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, + GOST_R_PUBLIC_KEY_UNDEFINED); + return 0; + } + X=BN_new(); + Y=BN_new(); + EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), + pub_key,X,Y,NULL); + data_len = 2*BN_num_bytes(order); + BN_free(order); + databuf = OPENSSL_malloc(data_len); + memset(databuf,0,data_len); + + store_bignum(X,databuf+data_len/2,data_len/2); + store_bignum(Y,databuf,data_len/2); + + BN_free(X); + BN_free(Y); + octet = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(octet,NULL,data_len); + sptr=ASN1_STRING_data(octet); + for (i=0,j=data_len-1;ipub_key && db->pub_key + && !BN_cmp(da->pub_key,db->pub_key)) + { + return 1; + } + return 0; + } + +static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b) + { + const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); + const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); + const EC_POINT *ka,*kb; + int ret=0; + if (!ea || !eb) return 0; + ka = EC_KEY_get0_public_key(ea); + kb = EC_KEY_get0_public_key(eb); + if (!ka || !kb) return 0; + ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ; + return ret; + } + + + + +static int pkey_size_gost(const EVP_PKEY *pk) + { + return 64; + } + +static int pkey_bits_gost(const EVP_PKEY *pk) + { + return 256; + } +/*------------------------ ASN1 METHOD for GOST MAC -------------------*/ +static void mackey_free_gost(EVP_PKEY *pk) + { + if (pk->pkey.ptr) { + OPENSSL_free(pk->pkey.ptr); + } + } +static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) + { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_id_Gost28147_89_MAC; + return 2; + } + return -2; +} + +static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); + return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder); +} +static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); + return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder); +} + +static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) +{ + ASN1_OBJECT *obj=NULL; + DSA *dsa = EVP_PKEY_get0(pkey); + int nid; + if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) { + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + if (!dsa) + { + dsa=DSA_new(); + if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0; + } + if (!fill_GOST94_params(dsa,nid)) return 0; + return 1; +} + +static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { + ASN1_OBJECT *obj=NULL; + int nid; + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) { + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + if (!ec) + { + ec = EC_KEY_new(); + if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0; + } + if (!fill_GOST2001_params(ec, nid)) return 0; + return 1; +} + + + + + +/* ----------------------------------------------------------------------*/ +int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) + { + *ameth = EVP_PKEY_asn1_new(nid, + ASN1_PKEY_SIGPARAM_NULL, pemstr, info); + if (!*ameth) return 0; + switch (nid) + { + case NID_id_GostR3410_94: + EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94); + EVP_PKEY_asn1_set_private (*ameth, + priv_decode_gost, priv_encode_gost, + priv_print_gost94); + + EVP_PKEY_asn1_set_param (*ameth, + gost94_param_decode, gost94_param_encode, + param_missing_gost94, param_copy_gost94, + param_cmp_gost94,param_print_gost94 ); + EVP_PKEY_asn1_set_public (*ameth, + pub_decode_gost94, pub_encode_gost94, + pub_cmp_gost94, pub_print_gost94, + pkey_size_gost, pkey_bits_gost); + + EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); + break; + case NID_id_GostR3410_2001: + EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01); + EVP_PKEY_asn1_set_private (*ameth, + priv_decode_gost, priv_encode_gost, + priv_print_gost01); + + EVP_PKEY_asn1_set_param (*ameth, + gost2001_param_decode, gost2001_param_encode, + param_missing_gost01, param_copy_gost01, + param_cmp_gost01, param_print_gost01); + EVP_PKEY_asn1_set_public (*ameth, + pub_decode_gost01, pub_encode_gost01, + pub_cmp_gost01, pub_print_gost01, + pkey_size_gost, pkey_bits_gost); + + EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); + break; + case NID_id_Gost28147_89_MAC: + EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); + EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost); + break; + } + return 1; + } diff --git a/crypto/openssl/engines/ccgost/gost_asn1.c b/crypto/openssl/engines/ccgost/gost_asn1.c new file mode 100644 index 0000000000..318ecfce57 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_asn1.c @@ -0,0 +1,55 @@ +/********************************************************************** + * gost_keytrans.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * ASN1 structure definition for GOST key transport * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include "gost_lcl.h" + +ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = { + ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO), + ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0) +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) + +ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = { + ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING), + ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO) + +ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = { + ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT), + ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0), + ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) + +ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = { + ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT), + ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT), + ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT), +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS) + +ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = { + ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING), + ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT), +} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) + +ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /*FIXME incomplete*/ + ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT) +} ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) diff --git a/crypto/openssl/engines/ccgost/gost_crypt.c b/crypto/openssl/engines/ccgost/gost_crypt.c new file mode 100644 index 0000000000..4977d1dcf5 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_crypt.c @@ -0,0 +1,616 @@ +/********************************************************************** + * gost_crypt.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * OpenSSL interface to GOST 28147-89 cipher functions * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include "gost89.h" +#include +#include "e_gost_err.h" +#include "gost_lcl.h" +static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +/* Handles block of data in CFB mode */ +static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +/* Handles block of data in CNT mode */ +static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +/* Cleanup function */ +static int gost_cipher_cleanup(EVP_CIPHER_CTX *); +/* set/get cipher parameters */ +static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params); +static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params); +/* Control function */ +static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr); + +EVP_CIPHER cipher_gost = + { + NID_id_Gost28147_89, + 1,/*block_size*/ + 32,/*key_size*/ + 8,/*iv_len */ + EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init, + gost_cipher_do_cfb, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, + }; + +EVP_CIPHER cipher_gost_cpacnt = + { + NID_gost89_cnt, + 1,/*block_size*/ + 32,/*key_size*/ + 8,/*iv_len */ + EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init_cpa, + gost_cipher_do_cnt, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, + }; + +/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */ +/* Init functions which set specific parameters */ +static int gost_imit_init_cpa(EVP_MD_CTX *ctx); +/* process block of data */ +static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count); +/* Return computed value */ +static int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md); +/* Copies context */ +static int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from); +static int gost_imit_cleanup(EVP_MD_CTX *ctx); +/* Control function, knows how to set MAC key.*/ +static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr); + +EVP_MD imit_gost_cpa = + { + NID_id_Gost28147_89_MAC, + NID_undef, + 4, + 0, + gost_imit_init_cpa, + gost_imit_update, + gost_imit_final, + gost_imit_copy, + gost_imit_cleanup, + NULL, + NULL, + {0,0,0,0,0}, + 8, + sizeof(struct ossl_gost_imit_ctx), + gost_imit_ctrl + }; + +/* + * Correspondence between gost parameter OIDs and substitution blocks + * NID field is filed by register_gost_NID function in engine.c + * upon engine initialization + */ + +struct gost_cipher_info gost_cipher_list[]= + { +/* NID */ /* Subst block */ /* Key meshing*/ +/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/ + {NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0}, + {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1}, + {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1}, + {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1}, + {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1}, + {NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,1}, + {NID_undef,NULL,0} + }; + +/* get encryption parameters from crypto network settings + FIXME For now we use environment var CRYPT_PARAMS as place to + store these settings. Actually, it is better to use engine control command, read from configuration file to set them */ +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj) + { + int nid; + struct gost_cipher_info *param; + if (!obj) + { + const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS); + if (!params || !strlen(params)) + return &gost_cipher_list[1]; + + nid = OBJ_txt2nid(params); + if (nid == NID_undef) + { + GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, + GOST_R_INVALID_CIPHER_PARAM_OID); + return NULL; + } + } + else + { + nid= OBJ_obj2nid(obj); + } + for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; + param++); + if (!param->sblock) + { + GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS); + return NULL; + } + return param; + } + +/* Sets cipher param from paramset NID. */ +static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid) + { + const struct gost_cipher_info *param; + param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid))); + if (!param) return 0; + + c->paramNID = param->nid; + c->key_meshing=param->key_meshing; + c->count=0; + gost_init(&(c->cctx), param->sblock); + return 1; + } + +/* Initializes EVP_CIPHER_CTX by paramset NID */ +static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc, int paramNID,int mode) + { + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + if (ctx->app_data == NULL) + { + if (!gost_cipher_set_param(c,paramNID)) return 0; + ctx->app_data = ctx->cipher_data; + } + if (key) gost_key(&(c->cctx),key); + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; + } + +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); + c->key_meshing=1; + c->count=0; + if(key) gost_key(&(c->cctx),key); + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; + } + +/* Initializes EVP_CIPHER_CTX with default values */ +int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE); + } +/* Wrapper around gostcrypt function from gost89.c which perform + * key meshing when nesseccary + */ +static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) + { + struct ossl_gost_cipher_ctx *c = ctx; + if (c->count&&c->key_meshing && c->count%1024==0) + { + cryptopro_key_meshing(&(c->cctx),iv); + } + gostcrypt(&(c->cctx),iv,buf); + c->count+=8; + } + +static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) + { + struct ossl_gost_cipher_ctx *c = ctx; + word32 g,go; + unsigned char buf1[8]; + if (c->count && c->key_meshing && c->count %1024 ==0) + { + cryptopro_key_meshing(&(c->cctx),iv); + } + if (c->count==0) + { + gostcrypt(&(c->cctx),iv,buf1); + } + else + { + memcpy(buf1,iv,8); + } + g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24); + g += 0x01010101; + buf1[0]=(unsigned char)(g&0xff); + buf1[1]=(unsigned char)((g>>8)&0xff); + buf1[2]=(unsigned char)((g>>16)&0xff); + buf1[3]=(unsigned char)((g>>24)&0xff); + g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|(buf1[7]<<24); + go = g; + g += 0x01010104; + if (go > g) /* overflow*/ + g++; + buf1[4]=(unsigned char)(g&0xff); + buf1[5]=(unsigned char)((g>>8)&0xff); + buf1[6]=(unsigned char)((g>>16)&0xff); + buf1[7]=(unsigned char)((g>>24)&0xff); + memcpy(iv,buf1,8); + gostcrypt(&(c->cctx),buf1,buf); + c->count +=8; + } + +/* GOST encryption in CFB mode */ +int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) + { + const unsigned char *in_ptr=in; + unsigned char *out_ptr=out; + size_t i=0; + size_t j=0; +/* process partial block if any */ + if (ctx->num) + { + for (j=ctx->num,i=0;j<8 && iencrypt) ctx->buf[j+8]=*in_ptr; + *out_ptr=ctx->buf[j]^(*in_ptr); + if (ctx->encrypt) ctx->buf[j+8]=*out_ptr; + } + if (j==8) + { + memcpy(ctx->iv,ctx->buf+8,8); + ctx->num=0; + } + else + { + ctx->num=j; + return 1; + } + } + + for (;i+8cipher_data,ctx->iv,ctx->buf); + /*xor next block of input text with it and output it*/ + /*output this block */ + if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8); + for (j=0;j<8;j++) + { + out_ptr[j]=ctx->buf[j]^in_ptr[j]; + } + /* Encrypt */ + /* Next iv is next block of cipher text*/ + if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8); + } +/* Process rest of buffer */ + if (icipher_data,ctx->iv,ctx->buf); + if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,inl-i); + for (j=0;ibuf[j]^in_ptr[j]; + } + ctx->num = j; + if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j); + } + else + { + ctx->num = 0; + } + return 1; + } + +static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) + { + const unsigned char *in_ptr=in; + unsigned char *out_ptr=out; + size_t i=0; + size_t j; +/* process partial block if any */ + if (ctx->num) + { + for (j=ctx->num,i=0;j<8 && ibuf[j]^(*in_ptr); + } + if (j==8) + { + ctx->num=0; + } + else + { + ctx->num=j; + return 1; + } + } + + for (;i+8cipher_data,ctx->iv,ctx->buf); + /*xor next block of input text with it and output it*/ + /*output this block */ + for (j=0;j<8;j++) + { + out_ptr[j]=ctx->buf[j]^in_ptr[j]; + } + } +/* Process rest of buffer */ + if (icipher_data,ctx->iv,ctx->buf); + for (j=0;ibuf[j]^in_ptr[j]; + } + ctx->num = j; + } + else + { + ctx->num = 0; + } + return 1; + } + +/* Cleaning up of EVP_CIPHER_CTX */ +int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) + { + gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx); + ctx->app_data = NULL; + return 1; + } + +/* Control function for gost cipher */ +int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr) + { + switch (type) + { + case EVP_CTRL_RAND_KEY: + { + if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0) + { + GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR); + return -1; + } + break; + } + case EVP_CTRL_PBE_PRF_NID: + if (ptr) { + *((int *)ptr)= NID_id_HMACGostR3411_94; + return 1; + } else { + return 0; + } + + default: + GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND); + return -1; + } + return 1; + } + +/* Set cipher parameters from ASN1 structure */ +int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params) + { + int len=0; + unsigned char *buf=NULL; + unsigned char *p=NULL; + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); + ASN1_OCTET_STRING *os = NULL; + if (!gcp) + { + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) + { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + ASN1_OBJECT_free(gcp->enc_param_set); + gcp->enc_param_set = OBJ_nid2obj(c->paramNID); + + len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); + p = buf = (unsigned char*)OPENSSL_malloc(len); + if (!buf) + { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + i2d_GOST_CIPHER_PARAMS(gcp, &p); + GOST_CIPHER_PARAMS_free(gcp); + + os = ASN1_OCTET_STRING_new(); + + if(!os || !ASN1_OCTET_STRING_set(os, buf, len)) + { + OPENSSL_free(buf); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + OPENSSL_free(buf); + + ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); + return 1; + } + +/* Store parameters into ASN1 structure */ +int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params) + { + int ret = -1; + int len; + GOST_CIPHER_PARAMS *gcp = NULL; + unsigned char *p; + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) + { + return ret; + } + + p = params->value.sequence->data; + + gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p, + params->value.sequence->length); + + len = gcp->iv->length; + if (len != ctx->cipher->iv_len) + { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, + GOST_R_INVALID_IV_LENGTH); + return -1; + } + if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set))) + { + GOST_CIPHER_PARAMS_free(gcp); + return -1; + } + memcpy(ctx->oiv, gcp->iv->data, len); + + GOST_CIPHER_PARAMS_free(gcp); + + return 1; + } + + +int gost_imit_init_cpa(EVP_MD_CTX *ctx) + { + struct ossl_gost_imit_ctx *c = ctx->md_data; + memset(c->buffer,0,16); + c->count = 0; + c->bytes_left=0; + c->key_meshing=1; + gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); + return 1; + } + +static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data) + { + unsigned char buffer[8]; + /* We are using local buffer for iv because CryptoPro doesn't + * interpret internal state of MAC algorithm as iv during keymeshing + * (but does initialize internal state from iv in key transport + */ + if (c->key_meshing&& c->count && c->count %1024 ==0) + { + cryptopro_key_meshing(&(c->cctx),buffer); + } + mac_block(&(c->cctx),c->buffer,data); + c->count +=8; + } + +int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) + { + struct ossl_gost_imit_ctx *c = ctx->md_data; + const unsigned char *p = data; + size_t bytes = count,i; + if (!(c->key_set)) { + GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + if (c->bytes_left) + { + for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++) + { + c->partial_block[i]=*p; + } + if (i==8) + { + mac_block_mesh(c,c->partial_block); + } + else + { + c->bytes_left = i; + return 1; + } + } + while (bytes>8) + { + mac_block_mesh(c,p); + p+=8; + bytes-=8; + } + if (bytes>0) + { + memcpy(c->partial_block,p,bytes); + } + c->bytes_left=bytes; + return 1; + } + +int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md) + { + struct ossl_gost_imit_ctx *c = ctx->md_data; + if (!c->key_set) { + GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + if (c->bytes_left) + { + int i; + for (i=c->bytes_left;i<8;i++) + { + c->partial_block[i]=0; + } + mac_block_mesh(c,c->partial_block); + } + get_mac(c->buffer,32,md); + return 1; + } + +int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr) + { + switch (type) + { + case EVP_MD_CTRL_KEY_LEN: + *((unsigned int*)(ptr)) = 32; + return 1; + case EVP_MD_CTRL_SET_KEY: + { + if (arg!=32) { + GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ; + ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1; + return 1; + + } + default: + return 0; + } + } + +int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) + { + memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx)); + return 1; + } + +/* Clean up imit ctx */ +int gost_imit_cleanup(EVP_MD_CTX *ctx) + { + memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx)); + return 1; + } + diff --git a/crypto/openssl/engines/ccgost/gost_ctl.c b/crypto/openssl/engines/ccgost/gost_ctl.c new file mode 100644 index 0000000000..d3cd171818 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_ctl.c @@ -0,0 +1,89 @@ +/********************************************************************** + * gost_ctl.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of control commands for GOST engine * + * OpenSSL 0.9.9 libraries required * + **********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "gost_lcl.h" + +static char *gost_params[GOST_PARAM_MAX+1]={NULL}; +static const char *gost_envnames[]={"CRYPT_PARAMS"}; +const ENGINE_CMD_DEFN gost_cmds[]= + { +/* { GOST_CTRL_RNG, + "RNG", + "Type of random number generator to use", + ENGINE_CMD_FLAG_STRING + }, + { GOST_CTRL_RNG_PARAMS, + "RNG_PARAMS", + "Parameter for random number generator", + ENGINE_CMD_FLAG_STRING + }, +*/ { GOST_CTRL_CRYPT_PARAMS, + "CRYPT_PARAMS", + "OID of default GOST 28147-89 parameters", + ENGINE_CMD_FLAG_STRING + }, +{0,NULL,NULL,0} + }; + +void gost_param_free() +{ + int i; + for (i=0;i<=GOST_PARAM_MAX;i++) + if (gost_params[i]!=NULL) + { + OPENSSL_free(gost_params[i]); + gost_params[i]=NULL; + } + +} + +int gost_control_func(ENGINE *e,int cmd,long i, void *p, void (*f)(void)) + { + int param = cmd-ENGINE_CMD_BASE; + int ret=0; + if (param <0 || param >GOST_PARAM_MAX) return -1; + ret=gost_set_default_param(param,p); + return ret; + } + +const char *get_gost_engine_param(int param) + { + char *tmp; + if (param <0 || param >GOST_PARAM_MAX) return NULL; + if (gost_params[param]!=NULL) + { + return gost_params[param]; + } + tmp = getenv(gost_envnames[param]); + if (tmp) + { + if (gost_params[param]) OPENSSL_free(gost_params[param]); + gost_params[param] = BUF_strdup(tmp); + return gost_params[param]; + } + return NULL; + } + +int gost_set_default_param(int param, const char *value) + { + const char *tmp; + if (param <0 || param >GOST_PARAM_MAX) return 0; + tmp = getenv(gost_envnames[param]); + /* if there is value in the environment, use it, else -passed string * */ + if (!tmp) tmp=value; + if (gost_params[param]) OPENSSL_free(gost_params[param]); + gost_params[param] = BUF_strdup(tmp); + + return 1; + } diff --git a/crypto/openssl/engines/ccgost/gost_eng.c b/crypto/openssl/engines/ccgost/gost_eng.c new file mode 100644 index 0000000000..d2cbe3b831 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_eng.c @@ -0,0 +1,273 @@ +/********************************************************************** + * gost_eng.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Main file of GOST engine * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "e_gost_err.h" +#include "gost_lcl.h" +static const char *engine_gost_id = "gost"; +static const char *engine_gost_name = "Reference implementation of GOST engine"; + +/* Symmetric cipher and digest function registrar */ + +static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); + +static int gost_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int ind); + +static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, + const int **nids, int nid); + +static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, + const int **nids, int nid); + +static int gost_cipher_nids[] = + {NID_id_Gost28147_89, NID_gost89_cnt,0}; + +static int gost_digest_nids[] = + {NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0}; + +static int gost_pkey_meth_nids[] = + {NID_id_GostR3410_94, + NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0}; + +static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, + *pmeth_GostR3410_2001 = NULL, + *pmeth_Gost28147_MAC = NULL; + +static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, + *ameth_GostR3410_2001 = NULL, + *ameth_Gost28147_MAC = NULL; + + +static int gost_engine_init(ENGINE *e) + { + return 1; + } + +static int gost_engine_finish(ENGINE *e) + { + return 1; + } + +static int gost_engine_destroy(ENGINE *e) + { + gost_param_free(); + return 1; + } + +static int bind_gost (ENGINE *e,const char *id) + { + int ret = 0; + if (id && strcmp(id, engine_gost_id)) return 0; + + if (!ENGINE_set_id(e, engine_gost_id)) + { + printf("ENGINE_set_id failed\n"); + goto end; + } + if (!ENGINE_set_name(e, engine_gost_name)) + { + printf("ENGINE_set_name failed\n"); + goto end; + } + if (!ENGINE_set_digests(e, gost_digests)) + { + printf("ENGINE_set_digests failed\n"); + goto end; + } + if (! ENGINE_set_ciphers(e, gost_ciphers)) + { + printf("ENGINE_set_ciphers failed\n"); + goto end; + } + if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) + { + printf("ENGINE_set_pkey_meths failed\n"); + goto end; + } + if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) + { + printf("ENGINE_set_pkey_asn1_meths failed\n"); + goto end; + } + /* Control function and commands */ + if (!ENGINE_set_cmd_defns(e,gost_cmds)) + { + fprintf(stderr,"ENGINE_set_cmd_defns failed\n"); + goto end; + } + if (!ENGINE_set_ctrl_function(e,gost_control_func)) + { + fprintf(stderr,"ENGINE_set_ctrl_func failed\n"); + goto end; + } + if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy) + || ! ENGINE_set_init_function(e,gost_engine_init) + || ! ENGINE_set_finish_function(e,gost_engine_finish)) + { + goto end; + } + + if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end; + if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end; + if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC, + "GOST-MAC", "GOST 28147-89 MAC")) goto end; + + if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end; + if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end; + if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) + goto end; + if ( ! ENGINE_register_ciphers(e) + || ! ENGINE_register_digests(e) + || ! ENGINE_register_pkey_meths(e) + /* These two actually should go in LIST_ADD command */ + || ! EVP_add_cipher(&cipher_gost) + || ! EVP_add_cipher(&cipher_gost_cpacnt) + || ! EVP_add_digest(&digest_gost) + || ! EVP_add_digest(&imit_gost_cpa) + ) + { + goto end; + } + + ERR_load_GOST_strings(); + ret = 1; + end: + return ret; + } + +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +IMPLEMENT_DYNAMIC_BIND_FN(bind_gost) +IMPLEMENT_DYNAMIC_CHECK_FN() +#endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */ + +static int gost_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) + { + int ok =1 ; + if (!digest) + { + *nids = gost_digest_nids; + return 2; + } + /*printf("Digest no %d requested\n",nid);*/ + if(nid == NID_id_GostR3411_94) + { + *digest = &digest_gost; + } + else if (nid == NID_id_Gost28147_89_MAC) + { + *digest = &imit_gost_cpa; + } + else + { + ok =0; + *digest = NULL; + } + return ok; + } + +static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher, + const int **nids, int nid) + { + int ok = 1; + if (!cipher) + { + *nids = gost_cipher_nids; + return 2; /* two ciphers are supported */ + } + + if(nid == NID_id_Gost28147_89) + { + *cipher = &cipher_gost; + } + else if (nid == NID_gost89_cnt) + { + *cipher = &cipher_gost_cpacnt; + } + else + { + ok = 0; + *cipher = NULL; + } + return ok; + } + +static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, + const int **nids, int nid) + { + if (!pmeth) + { + *nids = gost_pkey_meth_nids; + return 3; + } + + switch (nid) + { + case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; + case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; + case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1; + default:; + } + + *pmeth = NULL; + return 0; + } + +static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, + const int **nids, int nid) + { + if (!ameth) + { + *nids = gost_pkey_meth_nids; + return 3; + } + switch (nid) + { + case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; + case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; + case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1; + + default:; + } + + *ameth = NULL; + return 0; + } + +#ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_gost(void) + { + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_gost(ret,engine_gost_id)) + { + ENGINE_free(ret); + return NULL; + } + return ret; + } + +void ENGINE_load_gost(void) + { + ENGINE *toadd =engine_gost(); + if (!toadd) return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); + } +#endif + diff --git a/crypto/openssl/engines/ccgost/gost_keywrap.c b/crypto/openssl/engines/ccgost/gost_keywrap.c new file mode 100644 index 0000000000..c618f6da28 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_keywrap.c @@ -0,0 +1,109 @@ +/********************************************************************** + * keywrap.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of CryptoPro key wrap algorithm, as defined in * + * RFC 4357 p 6.3 and 6.4 * + * Doesn't need OpenSSL * + **********************************************************************/ +#include +#include "gost89.h" +#include "gost_keywrap.h" + +/* Diversifies key using random UserKey Material + * Implements RFC 4357 p 6.5 key diversification algorithm + * + * inputKey - 32byte key to be diversified + * ukm - 8byte user key material + * outputKey - 32byte buffer to store diversified key + * + */ +void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey) + { + + u4 k,s1,s2; + int i,j,mask; + unsigned char S[8]; + memcpy(outputKey,inputKey,32); + for (i=0;i<8;i++) + { + /* Make array of integers from key */ + /* Compute IV S*/ + s1=0,s2=0; + for (j=0,mask=1;j<8;j++,mask<<=1) + { + k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)| + (outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24); + if (mask & ukm[i]) + { + s1+=k; + } + else + { + s2+=k; + } + } + S[0]=(unsigned char)(s1&0xff); + S[1]=(unsigned char)((s1>>8)&0xff); + S[2]=(unsigned char)((s1>>16)&0xff); + S[3]=(unsigned char)((s1>>24)&0xff); + S[4]=(unsigned char)(s2&0xff); + S[5]=(unsigned char)((s2>>8)&0xff); + S[6]=(unsigned char)((s2>>16)&0xff); + S[7]=(unsigned char)((s2>>24)&0xff); + gost_key(ctx,outputKey); + gost_enc_cfb(ctx,S,outputKey,outputKey,4); + } + } + + +/* + * Wraps key using RFC 4357 6.3 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey (KEK) 32-byte (256-bit) shared key + * ukm - 8 byte (64 bit) user key material, + * sessionKey - 32-byte (256-bit) key to be wrapped + * wrappedKey - 44-byte buffer to store wrapped key + */ + +int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm, + const unsigned char *sessionKey, unsigned char *wrappedKey) + { + unsigned char kek_ukm[32]; + keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm); + gost_key(ctx,kek_ukm); + memcpy(wrappedKey,ukm,8); + gost_enc(ctx,sessionKey,wrappedKey+8,4); + gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40); + return 1; + } +/* + * Unwraps key using RFC 4357 6.4 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey 32-byte shared key + * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM, + * 32 byte encrypted key and 4 byte MAC + * + * sessionKEy - 32byte buffer to store sessionKey in + * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match + */ + +int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, + const unsigned char *wrappedKey, unsigned char *sessionKey) + { + unsigned char kek_ukm[32],cek_mac[4]; + keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey + /* First 8 bytes of wrapped Key is ukm */ + ,kek_ukm); + gost_key(ctx,kek_ukm); + gost_dec(ctx,wrappedKey+8,sessionKey,4); + gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac); + if (memcmp(cek_mac,wrappedKey+40,4)) + { + return 0; + } + return 1; + } + + diff --git a/crypto/openssl/engines/ccgost/gost_keywrap.h b/crypto/openssl/engines/ccgost/gost_keywrap.h new file mode 100644 index 0000000000..37c2a0f73d --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_keywrap.h @@ -0,0 +1,56 @@ +/********************************************************************** + * gost_keywrap.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of CryptoPro key wrap algorithm, as defined in * + * RFC 4357 p 6.3 and 6.4 * + * Doesn't need OpenSSL * + **********************************************************************/ +#ifndef GOST_KEYWRAP_H +#define GOST_KEYWRAP_H +#include +#include "gost89.h" +/* Diversifies key using random UserKey Material + * Implements RFC 4357 p 6.5 key diversification algorithm + * + * inputKey - 32byte key to be diversified + * ukm - 8byte user key material + * outputKey - 32byte buffer to store diversified key + * + */ +void keyDiversifyCryptoPro(gost_ctx *ctx, + const unsigned char *inputKey, + const unsigned char *ukm, + unsigned char *outputKey); +/* + * Wraps key using RFC 4357 6.3 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey (KEK) 32-byte (256-bit) shared key + * ukm - 8 byte (64 bit) user key material, + * sessionKey - 32-byte (256-bit) key to be wrapped + * wrappedKey - 44-byte buffer to store wrapped key + */ + +int keyWrapCryptoPro(gost_ctx *ctx, + const unsigned char *keyExchangeKey, + const unsigned char *ukm, + const unsigned char *sessionKey, + unsigned char *wrappedKey) ; +/* + * Unwraps key using RFC 4357 6.4 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey 32-byte shared key + * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM, + * 32 byte encrypted key and 4 byte MAC + * + * sessionKEy - 32byte buffer to store sessionKey in + * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match + */ + + +int keyUnwrapCryptoPro(gost_ctx *ctx, + const unsigned char *keyExchangeKey, + const unsigned char *wrappedKey, + unsigned char *sessionKey) ; +#endif diff --git a/crypto/openssl/engines/ccgost/gost_lcl.h b/crypto/openssl/engines/ccgost/gost_lcl.h new file mode 100644 index 0000000000..437a48cc86 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_lcl.h @@ -0,0 +1,218 @@ +#ifndef GOST_TOOLS_H +#define GOST_TOOLS_H +/********************************************************************** + * gost_lcl.h * + * Copyright (c) 2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Internal declarations used in GOST engine * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include "gost89.h" +#include "gosthash.h" +/* Control commands */ +#define GOST_PARAM_CRYPT_PARAMS 0 +#define GOST_PARAM_MAX 0 +#define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) + + extern const ENGINE_CMD_DEFN gost_cmds[]; + int gost_control_func(ENGINE *e,int cmd, long i, void *p, void (*f)(void)); + const char *get_gost_engine_param(int param); + int gost_set_default_param(int param, const char *value); + void gost_param_free(void); + +/* method registration */ + + int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info); + int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags); + +/* Gost-specific pmeth control-function parameters */ +/* For GOST R34.10 parameters */ +#define param_ctrl_string "paramset" +#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) +/* For GOST 28147 MAC */ +#define key_ctrl_string "key" +#define hexkey_ctrl_string "hexkey" +#define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3) +/* Pmeth internal representation */ + struct gost_pmeth_data { + int sign_param_nid; /* Should be set whenever parameters are filled */ + EVP_MD *md; + unsigned char *shared_ukm; + int peer_key_used; + }; + + struct gost_mac_pmeth_data { + int key_set; + EVP_MD *md; + unsigned char key[32]; + } ; +/* GOST-specific ASN1 structures */ + + +typedef struct { + ASN1_OCTET_STRING *encrypted_key; + ASN1_OCTET_STRING *imit; +} GOST_KEY_INFO; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO) + +typedef struct { + ASN1_OBJECT *cipher; + X509_PUBKEY *ephem_key; + ASN1_OCTET_STRING *eph_iv; +} GOST_KEY_AGREEMENT_INFO; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) + +typedef struct { + GOST_KEY_INFO *key_info; + GOST_KEY_AGREEMENT_INFO *key_agreement_info; +} GOST_KEY_TRANSPORT; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) + +typedef struct { /* FIXME incomplete */ + GOST_KEY_TRANSPORT *gkt; +} GOST_CLIENT_KEY_EXCHANGE_PARAMS; + +/* Hacks to shorten symbols to 31 characters or less, or OpenVMS. + This mimics what's done in symhacks.h, but since this is a very + local header file, I prefered to put this hack directly here. + -- Richard Levitte */ +#ifdef OPENSSL_SYS_VMS +#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it +#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it GOST_CLIENT_KEY_EXC_PARAMS_it +#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new +#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new GOST_CLIENT_KEY_EXC_PARAMS_new +#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free +#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free GOST_CLIENT_KEY_EXC_PARAMS_free +#undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS +#define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS d2i_GOST_CLIENT_KEY_EXC_PARAMS +#undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS +#define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS i2d_GOST_CLIENT_KEY_EXC_PARAMS +#endif /* End of hack */ +DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) +typedef struct { + ASN1_OBJECT *key_params; + ASN1_OBJECT *hash_params; + ASN1_OBJECT *cipher_params; +} GOST_KEY_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS) + +typedef struct { + ASN1_OCTET_STRING *iv; + ASN1_OBJECT *enc_param_set; +} GOST_CIPHER_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) +/*============== Message digest and cipher related structures ==========*/ + /* Structure used as EVP_MD_CTX-md_data. + * It allows to avoid storing in the md-data pointers to + * dynamically allocated memory. + * + * I cannot invent better way to avoid memory leaks, because + * openssl insist on invoking Init on Final-ed digests, and there + * is no reliable way to find out whether pointer in the passed + * md_data is valid or not. + * */ +struct ossl_gost_digest_ctx { + gost_hash_ctx dctx; + gost_ctx cctx; +}; +/* EVP_MD structure for GOST R 34.11 */ +extern EVP_MD digest_gost; +/* EVP_MD structure for GOST 28147 in MAC mode */ +extern EVP_MD imit_gost_cpa; +/* Cipher context used for EVP_CIPHER operation */ +struct ossl_gost_cipher_ctx { + int paramNID; + off_t count; + int key_meshing; + gost_ctx cctx; +}; +/* Structure to map parameter NID to S-block */ +struct gost_cipher_info { + int nid; + gost_subst_block *sblock; + int key_meshing; +}; +/* Context for MAC */ +struct ossl_gost_imit_ctx { + gost_ctx cctx; + unsigned char buffer[8]; + unsigned char partial_block[8]; + off_t count; + int key_meshing; + int bytes_left; + int key_set; +}; +/* Table which maps parameter NID to S-blocks */ +extern struct gost_cipher_info gost_cipher_list[]; +/* Find encryption params from ASN1_OBJECT */ +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); +/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ +extern EVP_CIPHER cipher_gost; +extern EVP_CIPHER cipher_gost_cpacnt; +#define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3) +#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4) +/* EVP_PKEY_METHOD key encryption callbacks */ +/* From gost94_keyx.c */ +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ); + +int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len ); +/* From gost2001_keyx.c */ +int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ); + +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len ); +/* derive functions */ +/* From gost2001_keyx.c */ +int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +/* From gost94_keyx.c */ +int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +/* Internal functions for signature algorithms */ +int fill_GOST94_params(DSA *dsa,int nid); +int fill_GOST2001_params(EC_KEY *eckey, int nid); +int gost_sign_keygen(DSA *dsa) ; +int gost2001_keygen(EC_KEY *ec) ; + +DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa) ; +DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey); + +int gost_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) ; +int gost2001_do_verify(const unsigned char *dgst,int dgst_len, + DSA_SIG *sig, EC_KEY *ec); +int gost2001_compute_public(EC_KEY *ec) ; +int gost94_compute_public(DSA *dsa) ; +/*============== miscellaneous functions============================= */ +/* from gost_sign.c */ +/* Convert GOST R 34.11 hash sum to bignum according to standard */ +BIGNUM *hashsum2bn(const unsigned char *dgst) ; +/* Store bignum in byte array of given length, prepending by zeros + * if nesseccary */ +int store_bignum(BIGNUM *bn, unsigned char *buf,int len); +/* Read bignum, which can have few MSB all-zeros from buffer*/ +BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len); +/* Pack GOST R 34.10 signature according to CryptoPro rules */ +int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen); +/* Unpack GOST R 34.10 signature according to CryptoPro rules */ +DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) ; +/* from ameth.c */ +/* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001 keys*/ +/* Returns pointer into EVP_PKEY structure */ +BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) ; +/* Find NID by GOST 94 parameters */ +int gost94_nid_by_params(DSA *p) ; + + +#endif diff --git a/crypto/openssl/engines/ccgost/gost_md.c b/crypto/openssl/engines/ccgost/gost_md.c new file mode 100644 index 0000000000..417e10887b --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_md.c @@ -0,0 +1,75 @@ +/********************************************************************** + * md_gost.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * OpenSSL interface to GOST R 34.11-94 hash functions * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include "gost_lcl.h" +#include "gosthash.h" +#include "e_gost_err.h" + +/* implementation of GOST 34.11 hash function See gost_md.c*/ +static int gost_digest_init(EVP_MD_CTX *ctx); +static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count); +static int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md); +static int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from); +static int gost_digest_cleanup(EVP_MD_CTX *ctx); + +EVP_MD digest_gost= + { + NID_id_GostR3411_94, + NID_undef, + 32, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, + gost_digest_init, + gost_digest_update, + gost_digest_final, + gost_digest_copy, + gost_digest_cleanup, + NULL, + NULL, + {NID_undef,NID_undef,0,0,0}, + 32, + sizeof(struct ossl_gost_digest_ctx ), + NULL + }; + +int gost_digest_init(EVP_MD_CTX *ctx) + { + struct ossl_gost_digest_ctx *c = ctx->md_data; + memset(&(c->dctx),0,sizeof(gost_hash_ctx)); + gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet); + c->dctx.cipher_ctx= &(c->cctx); + return 1; + } + +int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) + { + return hash_block((gost_hash_ctx *)ctx->md_data,data,count); + } + +int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md) + { + return finish_hash((gost_hash_ctx *)ctx->md_data,md); + + } + +int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) + { + struct ossl_gost_digest_ctx *md_ctx=to->md_data; + if (to->md_data && from->md_data) { + memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx)); + md_ctx->dctx.cipher_ctx=&(md_ctx->cctx); + } + return 1; + } + +int gost_digest_cleanup(EVP_MD_CTX *ctx) + { + if (ctx->md_data) + memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx)); + return 1; + } diff --git a/crypto/openssl/engines/ccgost/gost_params.c b/crypto/openssl/engines/ccgost/gost_params.c new file mode 100644 index 0000000000..40fc343af1 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_params.c @@ -0,0 +1,198 @@ +/********************************************************************** + * params.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357 * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +#include "gost_params.h" +#include +/* Parameters of GOST 34.10 */ + +R3410_params R3410_paramset[]={ +/* Paramset A */ +{NID_id_GostR3410_94_CryptoPro_A_ParamSet, +"100997906755055304772081815535925224869" +"8410825720534578748235158755771479905292727772441528526992987964833" +"5669968284202797289605274717317548059048560713474685214192868091256" +"1502802222185647539190902656116367847270145019066794290930185446216" +"3997308722217328898303231940973554032134009725883228768509467406639" +"62", +"127021248288932417465907042777176443525" +"7876535089165358128175072657050312609850984974231883334834011809259" +"9999512098893413065920561499672425412104927434935707492031276956145" +"1689224110579311248812610229678534638401693520013288995000362260684" +"2227508135323070045173416336850045410625869714168836867788425378203" +"83", +"683631961449557007844441656118272528951" +"02170888761442055095051287550314083023"}, +{NID_id_GostR3410_94_CryptoPro_B_ParamSet, +"429418261486158041438734477379555023926" +"7234596860714306679811299408947123142002706038521669956384871995765" +"7284814898909770759462613437669456364882730370838934791080835932647" +"9767786019153434744009610342313166725786869204821949328786333602033" +"8479709268434224762105576023501613261478065276102850944540333865234" +"1", +"139454871199115825601409655107690713107" +"0417070599280317977580014543757653577229840941243685222882398330391" +"1468164807668823692122073732267216074074777170091113455043205380464" +"7694904686120113087816240740184800477047157336662926249423571248823" +"9685422217536601433914856808405203368594584948031873412885804895251" +"63", +"79885141663410976897627118935756323747307951916507639758300472692338873533959" +}, +{NID_id_GostR3410_94_CryptoPro_C_ParamSet, +"816552717970881016017893191415300348226" +"2544051353358162468249467681876621283478212884286545844013955142622" +"2087723485023722868022275009502224827866201744494021697716482008353" +"6398202298024892620480898699335508064332313529725332208819456895108" +"5155178100221003459370588291073071186553005962149936840737128710832" +"3", +"110624679233511963040518952417017040248" +"5862954819831383774196396298584395948970608956170224210628525560327" +"8638246716655439297654402921844747893079518669992827880792192992701" +"1428546551433875806377110443534293554066712653034996277099320715774" +"3542287621283671843703709141350171945045805050291770503634517804938" +"01", +"113468861199819350564868233378875198043" +"267947776488510997961231672532899549103" +}, +{NID_id_GostR3410_94_CryptoPro_D_ParamSet, +"756976611021707301782128757801610628085" +"5283803109571158829574281419208532589041660017017859858216341400371" +"4687551412794400562878935266630754392677014598582103365983119173924" +"4732511225464712252386803315902707727668715343476086350472025298282" +"7271461690125050616858238384366331089777463541013033926723743254833" +"7", +"905457649621929965904290958774625315611" +"3056083907389766971404812524422262512556054474620855996091570786713" +"5849550236741915584185990627801066465809510095784713989819413820871" +"5964648914493053407920737078890520482730623038837767710173664838239" +"8574828787891286471201460474326612697849693665518073864436497893214" +"9", +"108988435796353506912374591498972192620" +"190487557619582334771735390599299211593" +}, + +{NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, +"1335318132727206734338595199483190012179423759678474868994823595993" +"6964252873471246159040332773182141032801252925387191478859899310331" +"0567744136196364803064721377826656898686468463277710150809401182608" +"7702016153249904683329312949209127762411378780302243557466062839716" +"59376426832674269780880061631528163475887", +"14201174159756348119636828602231808974327613839524373876287257344192" +"74593935127189736311660784676003608489466235676257952827747192122419" +"29071046134208380636394084512691828894000571524625445295769349356752" +"72895683154177544176313938445719175509684710784659566254794231229333" +"8483924514339614727760681880609734239", +"91771529896554605945588149018382750217296858393520724172743325725474" +"374979801" +}, +{NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, +"8890864727828423151699995801875757891031463338652579140051973659" +"3048131440685857067369829407947744496306656291505503608252399443" +"7900272386749145996230867832228661977543992816745254823298629859" +"8753575466286051738837854736167685769017780335804511440773337196" +"2538423532919394477873664752824509986617878992443177", +"1028946126624994859676552074360530315217970499989304888248413244" +"8474923022758470167998871003604670704877377286176171227694098633" +"1539089568784129110109512690503345393869871295783467257264868341" +"7200196629860561193666752429682367397084815179752036423595736533" +"68957392061769855284593965042530895046088067160269433", +"9109671391802626916582318050603555673628769498182593088388796888" +"5281641595199" +}, +{NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, +"4430618464297584182473135030809859326863990650118941756995270074" +"8609973181426950235239623239110557450826919295792878938752101867" +"7047181623251027516953100431855964837602657827828194249605561893" +"6965865325513137194483136247773653468410118796740709840825496997" +"9375560722345106704721086025979309968763193072908334", +"1246996366993477513607147265794064436203408861395055989217248455" +"7299870737698999651480662364723992859320868822848751165438350943" +"3276647222625940615560580450040947211826027729977563540237169063" +"0448079715771649447778447000597419032457722226253269698374446528" +"35352729304393746106576383349151001715930924115499549", +"6787876137336591234380295020065682527118129468050147943114675429" +"4748422492761" +}, + + +{NID_undef,NULL, NULL, NULL} +}; + +R3410_2001_params R3410_2001_paramset[]={ + /* default_cc_sign01_param 1.2.643.2.9.1.8.1 */ + {NID_id_GostR3410_2001_ParamSet_cc, + /* A */ + "C0000000000000000000000000000000000000000000000000000000000003c4", + /* B */ + "2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c", + /* P */ + "C0000000000000000000000000000000000000000000000000000000000003C7", + /* Q */ + "5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85", + /* X */ + "2", + /* Y */ + "a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c" + }, + /* 1.2.643.2.2.35.0 */ + {NID_id_GostR3410_2001_TestParamSet, + "7", + "5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E", + "8000000000000000000000000000000000000000000000000000000000000431", + "8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3", + "2", + "08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8" + }, + /*1.2.643.2.2.35.1*/ + {NID_id_GostR3410_2001_CryptoPro_A_ParamSet, + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", + "a6", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", + "1", + "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14" + }, + /*1.2.643.2.2.35.2*/ + {NID_id_GostR3410_2001_CryptoPro_B_ParamSet, + "8000000000000000000000000000000000000000000000000000000000000C96", + "3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B", + "8000000000000000000000000000000000000000000000000000000000000C99", + "800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F", + "1", + "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC" + }, + /*1.2.643.2.2.35.3*/ + {NID_id_GostR3410_2001_CryptoPro_C_ParamSet, + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", + "805a", + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", + "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", + "0", + "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67" + }, + /*1.2.643.2.2.36.0*/ + {NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", + "a6", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", + "1", + "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14" + }, + /*1.2.643.2.2.36.1*/ + {NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", + "805a", + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", + "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", + "0", + "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67" + }, + { 0,NULL,NULL,NULL,NULL,NULL,NULL + } +}; diff --git a/crypto/openssl/engines/ccgost/gost_params.h b/crypto/openssl/engines/ccgost/gost_params.h new file mode 100644 index 0000000000..4c3f5567d7 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_params.h @@ -0,0 +1,34 @@ +/********************************************************************** + * gost_params.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Declaration of structures used to represent GOST R 34.10 * + * parameter sets, defined in RFC 4357 * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +#ifndef GOST_PARAMSET_H +#define GOST_PARAMSET_H +typedef struct R3410 { + int nid; + char *a; + char *p; + char *q; +} R3410_params; + +extern R3410_params R3410_paramset[]; + +typedef struct R3410_2001 { + int nid; + char *a; + char *b; + char *p; + char *q; + char *x; + char *y; +} R3410_2001_params; + +extern R3410_2001_params R3410_2001_paramset[]; + +#endif diff --git a/crypto/openssl/engines/ccgost/gost_pmeth.c b/crypto/openssl/engines/ccgost/gost_pmeth.c new file mode 100644 index 0000000000..caaea99d36 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_pmeth.c @@ -0,0 +1,621 @@ +/********************************************************************** + * gost_pmeth.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of RFC 4357 (GOST R 34.10) Publick key method * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include /*For string_to_hex */ +#include +#include +#include +#include "gost_params.h" +#include "gost_lcl.h" +#include "e_gost_err.h" +/*-------init, cleanup, copy - uniform for all algs ---------------*/ +/* Allocates new gost_pmeth_data structure and assigns it as data */ +static int pkey_gost_init(EVP_PKEY_CTX *ctx) + { + struct gost_pmeth_data *data; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); + if (!data) return 0; + memset(data,0,sizeof(struct gost_pmeth_data)); + if (pkey && EVP_PKEY_get0(pkey)) + { + switch (EVP_PKEY_base_id(pkey)) { + case NID_id_GostR3410_94: + data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey)); + break; + case NID_id_GostR3410_2001: + data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); + break; + default: + return 0; + } + } + EVP_PKEY_CTX_set_data(ctx,data); + return 1; + } + +/* Copies contents of gost_pmeth_data structure */ +static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + struct gost_pmeth_data *dst_data,*src_data; + if (!pkey_gost_init(dst)) + { + return 0; + } + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + *dst_data = *src_data; + if (src_data -> shared_ukm) { + dst_data->shared_ukm=NULL; + } + return 1; + } + +/* Frees up gost_pmeth_data structure */ +static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx) + { + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + if (data->shared_ukm) OPENSSL_free(data->shared_ukm); + OPENSSL_free(data); + } + +/* --------------------- control functions ------------------------------*/ +static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); + switch (type) + { + case EVP_PKEY_CTRL_MD: + { + if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) + { + GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + pctx->md = (EVP_MD *)p2; + return 1; + } + break; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; + + case EVP_PKEY_CTRL_GOST_PARAMSET: + pctx->sign_param_nid = (int)p1; + return 1; + case EVP_PKEY_CTRL_SET_IV: + pctx->shared_ukm=OPENSSL_malloc((int)p1); + memcpy(pctx->shared_ukm,p2,(int) p1); + return 1; + case EVP_PKEY_CTRL_PEER_KEY: + if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ + return 1; + if (p1 == 2) /* TLS: peer key used? */ + return pctx->peer_key_used; + if (p1 == 3) /* TLS: peer key used! */ + return (pctx->peer_key_used = 1); + return -2; + } + return -2; + } + + +static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + int param_nid=0; + if(!strcmp(type, param_ctrl_string)) + { + if (!value) + { + return 0; + } + if (strlen(value) == 1) + { + switch(toupper(value[0])) + { + case 'A': + param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet; + break; + case 'C': + param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet; + break; + case 'D': + param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet; + break; + default: + return 0; + break; + } + } + else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) + { + switch (toupper(value[1])) + { + case 'A': + param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet; + break; + case 'C': + param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet; + break; + default: + return 0; + break; + } + } + else + { + R3410_params *p = R3410_paramset; + param_nid = OBJ_txt2nid(value); + if (param_nid == NID_undef) + { + return 0; + } + for (;p->nid != NID_undef;p++) + { + if (p->nid == param_nid) break; + } + if (p->nid == NID_undef) + { + GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, + GOST_R_INVALID_PARAMSET); + return 0; + } + } + + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } + return -2; + } + +static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + int param_nid=0; + if(!strcmp(type, param_ctrl_string)) + { + if (!value) + { + return 0; + } + if (strlen(value) == 1) + { + switch(toupper(value[0])) + { + case 'A': + param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet; + break; + case 'C': + param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet; + break; + case '0': + param_nid = NID_id_GostR3410_2001_TestParamSet; + break; + default: + return 0; + break; + } + } + else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) + { + switch (toupper(value[1])) + { + case 'A': + param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet; + break; + default: + return 0; + break; + } + } + else + { + R3410_2001_params *p = R3410_2001_paramset; + param_nid = OBJ_txt2nid(value); + if (param_nid == NID_undef) + { + return 0; + } + for (;p->nid != NID_undef;p++) + { + if (p->nid == param_nid) break; + } + if (p->nid == NID_undef) + { + GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, + GOST_R_INVALID_PARAMSET); + return 0; + } + } + + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } + return -2; + } + +/* --------------------- key generation --------------------------------*/ + +static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) { + return 1; +} +static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + DSA *dsa=NULL; + if (data->sign_param_nid == NID_undef) + { + GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, + GOST_R_NO_PARAMETERS_SET); + return 0; + } + dsa = DSA_new(); + if (!fill_GOST94_params(dsa,data->sign_param_nid)) + { + DSA_free(dsa); + return 0; + } + EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa); + return 1; + } +static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + EC_KEY *ec=NULL; + + if (data->sign_param_nid == NID_undef) + { + GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, + GOST_R_NO_PARAMETERS_SET); + return 0; + } + if (!ec) + ec = EC_KEY_new(); + if (!fill_GOST2001_params(ec,data->sign_param_nid)) + { + EC_KEY_free(ec); + return 0; + } + EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec); + return 1; + } + +/* Generates Gost_R3410_94_cp key */ +static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + DSA *dsa; + if (!pkey_gost94_paramgen(ctx,pkey)) return 0; + dsa = EVP_PKEY_get0(pkey); + gost_sign_keygen(dsa); + return 1; + } + +/* Generates GOST_R3410 2001 key and assigns it using specified type */ +static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + EC_KEY *ec; + if (!pkey_gost01_paramgen(ctx,pkey)) return 0; + ec = EVP_PKEY_get0(pkey); + gost2001_keygen(ec); + return 1; + } + + + +/* ----------- sign callbacks --------------------------------------*/ + +static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbs_len) + { + DSA_SIG *unpacked_sig=NULL; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!siglen) return 0; + if (!sig) + { + *siglen= 64; /* better to check size of pkey->pkey.dsa-q */ + return 1; + } + unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); + if (!unpacked_sig) + { + return 0; + } + return pack_sign_cp(unpacked_sig,32,sig,siglen); + } + +static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbs_len) + { + DSA_SIG *unpacked_sig=NULL; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!siglen) return 0; + if (!sig) + { + *siglen= 64; /* better to check size of curve order*/ + return 1; + } + unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); + if (!unpacked_sig) + { + return 0; + } + return pack_sign_cp(unpacked_sig,32,sig,siglen); + } + +/* ------------------- verify callbacks ---------------------------*/ + +static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, size_t tbs_len) + { + int ok = 0; + EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); + DSA_SIG *s=unpack_cp_signature(sig,siglen); + if (!s) return 0; + if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); + DSA_SIG_free(s); + return ok; + } + + +static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, size_t tbs_len) + { + int ok = 0; + EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); + DSA_SIG *s=unpack_cp_signature(sig,siglen); + if (!s) return 0; +#ifdef DEBUG_SIGN + fprintf(stderr,"R="); + BN_print_fp(stderr,s->r); + fprintf(stderr,"\nS="); + BN_print_fp(stderr,s->s); + fprintf(stderr,"\n"); +#endif + if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); + DSA_SIG_free(s); + return ok; + } + +/* ------------- encrypt init -------------------------------------*/ +/* Generates ephermeral key */ +static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) + { + return 1; + } +/* --------------- Derive init ------------------------------------*/ +static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx) +{ + return 1; +} +/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ +static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) + { + struct gost_mac_pmeth_data *data; + data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); + if (!data) return 0; + memset(data,0,sizeof(struct gost_mac_pmeth_data)); + EVP_PKEY_CTX_set_data(ctx,data); + return 1; + } +static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx) + { + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + OPENSSL_free(data); + } +static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + struct gost_mac_pmeth_data *dst_data,*src_data; + if (!pkey_gost_mac_init(dst)) + { + return 0; + } + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + *dst_data = *src_data; + return 1; + } + +static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + struct gost_mac_pmeth_data *data = +(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); + + switch (type) + { + case EVP_PKEY_CTRL_MD: + { + if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + data->md = (EVP_MD *)p2; + return 1; + } + break; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (p1 != 32) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + memcpy(data->key,p2,32); + data->key_set = 1; + return 1; + case EVP_PKEY_CTRL_DIGESTINIT: + { + EVP_MD_CTX *mctx = p2; + void *key; + if (!data->key_set) + { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!pkey) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + key = EVP_PKEY_get0(pkey); + if (!key) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + } else { + key = &(data->key); + } + return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key); + } + } + return -2; + } +static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!strcmp(type, key_ctrl_string)) + { + if (strlen(value)!=32) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + 32,(char *)value); + } + if (!strcmp(type, hexkey_ctrl_string)) + { + long keylen; int ret; + unsigned char *keybuf=string_to_hex(value,&keylen); + if (keylen != 32) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + 32,keybuf); + OPENSSL_free(keybuf); + return ret; + + } + return -2; + } + +static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + unsigned char *keydata; + if (!data->key_set) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + keydata = OPENSSL_malloc(32); + memcpy(keydata,data->key,32); + EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); + return 1; + } + +static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) + { + return 1; +} + +static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx) + { + unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/ + int ret; + if (!sig) + { + *siglen = 4; + return 1; + } + ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen); + *siglen = tmpsiglen; + return ret; + } +/* ----------------------------------------------------------------*/ +int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) + { + *pmeth = EVP_PKEY_meth_new(id, flags); + if (!*pmeth) return 0; + + switch (id) + { + case NID_id_GostR3410_94: + EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str); + EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify); + EVP_PKEY_meth_set_encrypt(*pmeth, + pkey_gost_encrypt_init, pkey_GOST94cp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost94_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen); + break; + case NID_id_GostR3410_2001: + EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify); + + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen); + + EVP_PKEY_meth_set_encrypt(*pmeth, + pkey_gost_encrypt_init, pkey_GOST01cp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost2001_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen); + break; + case NID_id_Gost28147_89_MAC: + EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str); + EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx); + EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen); + EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init); + EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup); + EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy); + return 1; + default: /*Unsupported method*/ + return 0; + } + EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init); + EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup); + + EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy); + /*FIXME derive etc...*/ + + return 1; + } + diff --git a/crypto/openssl/engines/ccgost/gost_sign.c b/crypto/openssl/engines/ccgost/gost_sign.c new file mode 100644 index 0000000000..4095654358 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gost_sign.c @@ -0,0 +1,321 @@ +/********************************************************************** + * gost_sign.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.10-94 signature algorithm * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include +#include + +#include "gost_params.h" +#include "gost_lcl.h" +#include "e_gost_err.h" + +#ifdef DEBUG_SIGN +void dump_signature(const char *message,const unsigned char *buffer,size_t len) + { + size_t i; + fprintf(stderr,"signature %s Length=%d",message,len); + for (i=0; iq,ctx); + if (BN_is_zero(tmp)) + { + BN_one(md); + } + do + { + do + { + /*Generate random number k less than q*/ + BN_rand_range(k,dsa->q); + /* generate r = (a^x mod p) mod q */ + BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx); + if (!(newsig->r)) newsig->r=BN_new(); + BN_mod(newsig->r,tmp,dsa->q,ctx); + } + while (BN_is_zero(newsig->r)); + /* generate s = (xr + k(Hm)) mod q */ + BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx); + BN_mod_mul(tmp2,k,md,dsa->q,ctx); + if (!newsig->s) newsig->s=BN_new(); + BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx); + } + while (BN_is_zero(newsig->s)); + err: + BN_free(md); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return newsig; + } + + +/* + * Packs signature according to Cryptocom rules + * and frees up DSA_SIG structure + */ +/* +int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) + { + *siglen = 2*order; + memset(sig,0,*siglen); + store_bignum(s->r, sig,order); + store_bignum(s->s, sig + order,order); + dump_signature("serialized",sig,*siglen); + DSA_SIG_free(s); + return 1; + } +*/ +/* + * Packs signature according to Cryptopro rules + * and frees up DSA_SIG structure + */ +int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) + { + *siglen = 2*order; + memset(sig,0,*siglen); + store_bignum(s->s, sig, order); + store_bignum(s->r, sig+order,order); + dump_signature("serialized",sig,*siglen); + DSA_SIG_free(s); + return 1; + } + +/* + * Verifies signature passed as DSA_SIG structure + * + */ + +int gost_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) + { + BIGNUM *md, *tmp=NULL; + BIGNUM *q2=NULL; + BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL; + BIGNUM *tmp2=NULL,*tmp3=NULL; + int ok; + BN_CTX *ctx = BN_CTX_new(); + + BN_CTX_start(ctx); + if (BN_cmp(sig->s,dsa->q)>=1|| + BN_cmp(sig->r,dsa->q)>=1) + { + GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + return 0; + } + md=hashsum2bn(dgst); + + tmp=BN_CTX_get(ctx); + v=BN_CTX_get(ctx); + q2=BN_CTX_get(ctx); + z1=BN_CTX_get(ctx); + z2=BN_CTX_get(ctx); + tmp2=BN_CTX_get(ctx); + tmp3=BN_CTX_get(ctx); + u = BN_CTX_get(ctx); + + BN_mod(tmp,md,dsa->q,ctx); + if (BN_is_zero(tmp)) + { + BN_one(md); + } + BN_copy(q2,dsa->q); + BN_sub_word(q2,2); + BN_mod_exp(v,md,q2,dsa->q,ctx); + BN_mod_mul(z1,sig->s,v,dsa->q,ctx); + BN_sub(tmp,dsa->q,sig->r); + BN_mod_mul(z2,tmp,v,dsa->p,ctx); + BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx); + BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx); + BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx); + BN_mod(u,tmp3,dsa->q,ctx); + ok= BN_cmp(u,sig->r); + + BN_free(md); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (ok!=0) + { + GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH); + } + return (ok==0); + } + +/* + * Computes public keys for GOST R 34.10-94 algorithm + * + */ +int gost94_compute_public(DSA *dsa) + { + /* Now fill algorithm parameters with correct values */ + BN_CTX *ctx = BN_CTX_new(); + if (!dsa->g) + { + GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED); + return 0; + } + /* Compute public key y = a^x mod p */ + dsa->pub_key=BN_new(); + BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx); + BN_CTX_free(ctx); + return 1; + } + +/* + * Fill GOST 94 params, searching them in R3410_paramset array + * by nid of paramset + * + */ +int fill_GOST94_params(DSA *dsa,int nid) + { + R3410_params *params=R3410_paramset; + while (params->nid!=NID_undef && params->nid !=nid) params++; + if (params->nid == NID_undef) + { + GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET); + return 0; + } +#define dump_signature(a,b,c) + if (dsa->p) { BN_free(dsa->p); } + dsa->p=NULL; + BN_dec2bn(&(dsa->p),params->p); + if (dsa->q) { BN_free(dsa->q); } + dsa->q=NULL; + BN_dec2bn(&(dsa->q),params->q); + if (dsa->g) { BN_free(dsa->g); } + dsa->g=NULL; + BN_dec2bn(&(dsa->g),params->a); + return 1; + } + +/* + * Generate GOST R 34.10-94 keypair + * + * + */ +int gost_sign_keygen(DSA *dsa) + { + dsa->priv_key = BN_new(); + BN_rand_range(dsa->priv_key,dsa->q); + return gost94_compute_public( dsa); + } + +/* Unpack signature according to cryptocom rules */ +/* +DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen) + { + DSA_SIG *s; + s = DSA_SIG_new(); + if (s == NULL) + { + GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY); + return(NULL); + } + s->r = getbnfrombuf(sig, siglen/2); + s->s = getbnfrombuf(sig + siglen/2, siglen/2); + return s; + } +*/ +/* Unpack signature according to cryptopro rules */ +DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) + { + DSA_SIG *s; + + s = DSA_SIG_new(); + if (s == NULL) + { + GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY); + return NULL; + } + s->s = getbnfrombuf(sig , siglen/2); + s->r = getbnfrombuf(sig + siglen/2, siglen/2); + return s; + } + +/* Convert little-endian byte array into bignum */ +BIGNUM *hashsum2bn(const unsigned char *dgst) + { + unsigned char buf[32]; + int i; + for (i=0;i<32;i++) + { + buf[31-i]=dgst[i]; + } + return getbnfrombuf(buf,32); + } + +/* Convert byte buffer to bignum, skipping leading zeros*/ +BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len) + { + while (*buf==0&&len>0) + { + buf++; len--; + } + if (len) + { + return BN_bin2bn(buf,len,NULL); + } + else + { + BIGNUM *b=BN_new(); + BN_zero(b); + return b; + } + } + +/* Pack bignum into byte buffer of given size, filling all leading bytes + * by zeros */ +int store_bignum(BIGNUM *bn, unsigned char *buf,int len) + { + int bytes = BN_num_bytes(bn); + if (bytes>len) return 0; + memset(buf,0,len); + BN_bn2bin(bn,buf+len-bytes); + return 1; + } diff --git a/crypto/openssl/engines/ccgost/gosthash.c b/crypto/openssl/engines/ccgost/gosthash.c new file mode 100644 index 0000000000..a5c0662ffc --- /dev/null +++ b/crypto/openssl/engines/ccgost/gosthash.c @@ -0,0 +1,255 @@ +/********************************************************************** + * gosthash.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.11-94 hash function * + * uses on gost89.c and gost89.h Doesn't need OpenSSL * + **********************************************************************/ +#include + +#include "gost89.h" +#include "gosthash.h" + + +/* Use OPENSSL_malloc for memory allocation if compiled with + * -DOPENSSL_BUILD, and libc malloc otherwise + */ +#ifndef MYALLOC +# ifdef OPENSSL_BUILD +# include +# define MYALLOC(size) OPENSSL_malloc(size) +# define MYFREE(ptr) OPENSSL_free(ptr) +# else +# define MYALLOC(size) malloc(size) +# define MYFREE(ptr) free(ptr) +# endif +#endif +/* Following functions are various bit meshing routines used in + * GOST R 34.11-94 algorithms */ +static void swap_bytes (byte *w, byte *k) + { + int i,j; + for (i=0;i<4;i++) + for (j=0;j<8;j++) + k[i+4*j]=w[8*i+j]; + + } + +/* was A_A */ +static void circle_xor8 (const byte *w, byte *k) + { + byte buf[8]; + int i; + memcpy(buf,w,8); + memcpy(k,w+8,24); + for(i=0;i<8;i++) + k[i+24]=buf[i]^k[i]; + } + +/* was R_R */ +static void transform_3 (byte *data) + { + unsigned short int acc; + acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])| + ((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8); + memmove(data,data+2,30); + data[30]=acc&0xff; + data[31]=acc>>8; + } + +/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/ +static int add_blocks(int n,byte *left, const byte *right) + { + int i; + int carry=0; + int sum; + for (i=0;i>8; + } + return carry; + } + +/* Xor two sequences of bytes */ +static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len) + { + size_t i; + for (i=0;icipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx)); + if (!ctx->cipher_ctx) + { + return 0; + } + gost_init(ctx->cipher_ctx,subst_block); + return 1; + } + +/* + * Free cipher CTX if it is dynamically allocated. Do not use + * if cipher ctx is statically allocated as in OpenSSL implementation of + * GOST hash algroritm + * + */ +void done_gost_hash_ctx(gost_hash_ctx *ctx) + { + /* No need to use gost_destroy, because cipher keys are not really + * secret when hashing */ + MYFREE(ctx->cipher_ctx); + } + +/* + * reset state of hash context to begin hashing new message + */ +int start_hash(gost_hash_ctx *ctx) + { + if (!ctx->cipher_ctx) return 0; + memset(&(ctx->H),0,32); + memset(&(ctx->S),0,32); + ctx->len = 0L; + ctx->left=0; + return 1; + } + +/* + * Hash block of arbitrary length + * + * + */ +int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length) + { + const byte *curptr=block; + const byte *barrier=block+(length-32);/* Last byte we can safely hash*/ + if (ctx->left) + { + /*There are some bytes from previous step*/ + unsigned int add_bytes = 32-ctx->left; + if (add_bytes>length) + { + add_bytes = length; + } + memcpy(&(ctx->remainder[ctx->left]),block,add_bytes); + ctx->left+=add_bytes; + if (ctx->left<32) + { + return 1; + } + curptr=block+add_bytes; + hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder); + add_blocks(32,ctx->S,ctx->remainder); + ctx->len+=32; + ctx->left=0; + } + while (curptr<=barrier) + { + hash_step(ctx->cipher_ctx,ctx->H,curptr); + + add_blocks(32,ctx->S,curptr); + ctx->len+=32; + curptr+=32; + } + if (curptr!=block+length) + { + ctx->left=block+length-curptr; + memcpy(ctx->remainder,curptr,ctx->left); + } + return 1; + } + +/* + * Compute hash value from current state of ctx + * state of hash ctx becomes invalid and cannot be used for further + * hashing. + */ +int finish_hash(gost_hash_ctx *ctx,byte *hashval) + { + byte buf[32]; + byte H[32]; + byte S[32]; + ghosthash_len fin_len=ctx->len; + byte *bptr; + memcpy(H,ctx->H,32); + memcpy(S,ctx->S,32); + if (ctx->left) + { + memset(buf,0,32); + memcpy(buf,ctx->remainder,ctx->left); + hash_step(ctx->cipher_ctx,H,buf); + add_blocks(32,S,buf); + fin_len+=ctx->left; + } + memset(buf,0,32); + bptr=buf; + fin_len<<=3; /* Hash length in BITS!!*/ + while(fin_len>0) + { + *(bptr++)=(byte)(fin_len&0xFF); + fin_len>>=8; + }; + hash_step(ctx->cipher_ctx,H,buf); + hash_step(ctx->cipher_ctx,H,S); + memcpy(hashval,H,32); + return 1; + } diff --git a/crypto/openssl/engines/ccgost/gosthash.h b/crypto/openssl/engines/ccgost/gosthash.h new file mode 100644 index 0000000000..4a2e441ece --- /dev/null +++ b/crypto/openssl/engines/ccgost/gosthash.h @@ -0,0 +1,48 @@ +/********************************************************************** + * gosthash.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Declaration of GOST R 34.11-94 hash functions * + * uses and gost89.h Doesn't need OpenSSL * + **********************************************************************/ +#ifndef GOSTHASH_H +#define GOSTHASH_H +#include "gost89.h" +#include + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +typedef __int64 ghosthash_len; +#elif defined(__arch64__) +typedef long ghosthash_len; +#else +typedef long long ghosthash_len; +#endif + +typedef struct gost_hash_ctx { + ghosthash_len len; + gost_ctx *cipher_ctx; + int left; + byte H[32]; + byte S[32]; + byte remainder[32]; +} gost_hash_ctx; + + +/* Initalizes gost hash ctx, including creation of gost cipher ctx */ + +int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block); +void done_gost_hash_ctx(gost_hash_ctx *ctx); + +/* Cleans up all fields, except cipher ctx preparing ctx for computing + * of new hash value */ +int start_hash(gost_hash_ctx *ctx); + +/* Hashes block of data */ +int hash_block(gost_hash_ctx *ctx, const byte *block, size_t length); + +/* Finalizes computation of hash and fills buffer (which should be at + * least 32 bytes long) with value of computed hash. */ +int finish_hash(gost_hash_ctx *ctx, byte *hashval); + +#endif diff --git a/crypto/openssl/engines/ccgost/gostsum.c b/crypto/openssl/engines/ccgost/gostsum.c new file mode 100644 index 0000000000..d57112eb54 --- /dev/null +++ b/crypto/openssl/engines/ccgost/gostsum.c @@ -0,0 +1,210 @@ +/********************************************************************** + * gostsum.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Almost drop-in replacement for md5sum and sha1sum * + * which computes GOST R 34.11-94 hashsum instead * + * * + **********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "gosthash.h" +#define BUF_SIZE 262144 +int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode); +int hash_stream(gost_hash_ctx *ctx,int fd, char *sum); +int get_line(FILE *f,char *hash,char *filename); +void help() + { + fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n" + "\t-c check message digests (default is generate)\n" + "\t-v verbose, print file names when checking\n" + "\t-b read files in binary mode\n" + "\t-t use test GOST paramset (default is CryptoPro paramset)\n" + "The input for -c should be the list of message digests and file names\n" + "that is printed on stdout by this program when it generates digests.\n"); + exit(3); + } + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +int main(int argc,char **argv) + { + int c,i; + int verbose=0; + int errors=0; + int open_mode = O_RDONLY; + gost_subst_block *b= &GostR3411_94_CryptoProParamSet; + FILE *check_file = NULL; + gost_hash_ctx ctx; + + while( (c=getopt(argc,argv,"bc::tv"))!=-1) + { + switch (c) + { + case 'v': verbose=1; break; + case 't': b= &GostR3411_94_TestParamSet; break; + case 'b': open_mode |= O_BINARY; break; + case 'c': + if (optarg) + { + check_file = fopen(optarg,"r"); + if (!check_file) + { + perror(optarg); + exit(2); + } + } + else + { + check_file= stdin; + } + break; + default: + fprintf(stderr,"invalid option %c",optopt); + help(); + } + } + init_gost_hash_ctx(&ctx,b); + if (check_file) + { + char inhash[65],calcsum[65],filename[PATH_MAX]; + int failcount=0,count=0;; + if (check_file==stdin && optind0) + { + hash_block(ctx,buffer,bytes); + } + if (bytes<0) + { + return 0; + } + finish_hash(ctx,buffer); + for (i=0;i<32;i++) + { + sprintf(sum+2*i,"%02x",buffer[31-i]); + } + return 1; + } + +int get_line(FILE *f,char *hash,char *filename) + { + int i; + if (fread(hash,1,64,f)<64) return 0; + hash[64]=0; + for (i=0;i<64;i++) + { + if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F' + && hash[i]<'a')||hash[i]>'f') + { + fprintf(stderr,"Not a hash value '%s'\n",hash); + return 0; + } + } + if (fgetc(f)!=' ') + { + fprintf(stderr,"Malformed input line\n"); + return 0; + } + i=strlen(fgets(filename,PATH_MAX,f)); + while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0; + return 1; + } diff --git a/crypto/openssl/engines/e_4758cca.c b/crypto/openssl/engines/e_4758cca.c index 0f1dae7567..443182bd31 100644 --- a/crypto/openssl/engines/e_4758cca.c +++ b/crypto/openssl/engines/e_4758cca.c @@ -92,7 +92,7 @@ static int cca_rsa_priv_dec(int flen, const unsigned char *from, static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, const RSA *rsa); static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, - unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); + const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); /* utility functions */ /*-----------------------*/ @@ -108,7 +108,7 @@ static int getModulusAndExponent(const unsigned char *token, long *exponentLengt /* RAND number functions */ /*-----------------------*/ -static int cca_get_random_bytes(unsigned char*, int ); +static int cca_get_random_bytes(unsigned char*, int); static int cca_random_status(void); #ifndef OPENSSL_NO_RSA @@ -482,10 +482,6 @@ static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id, err: if (keyToken) OPENSSL_free(keyToken); - if (res) - EVP_PKEY_free(res); - if (rtmp) - RSA_free(rtmp); return NULL; } @@ -560,10 +556,6 @@ static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id, err: if (keyToken) OPENSSL_free(keyToken); - if (res) - EVP_PKEY_free(res); - if (rtmp) - RSA_free(rtmp); return NULL; } @@ -626,7 +618,7 @@ static int cca_rsa_priv_dec(int flen, const unsigned char *from, #define SSL_SIG_LEN 36 static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigbuf, unsigned int siglen, const RSA *rsa) + const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa) { long returnCode; long reasonCode; @@ -735,7 +727,8 @@ static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len, digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, exitData, &ruleArrayLength, ruleArray, &keyTokenLength, - keyToken, &length, hashBuffer, &lsiglen, sigbuf); + keyToken, &length, hashBuffer, &lsiglen, + (unsigned char *)sigbuf); if (type == NID_sha1 || type == NID_md5) { diff --git a/crypto/openssl/engines/e_aep.c b/crypto/openssl/engines/e_aep.c index e24e4b424e..742b4f9b18 100644 --- a/crypto/openssl/engines/e_aep.c +++ b/crypto/openssl/engines/e_aep.c @@ -57,7 +57,7 @@ #include #include -#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) +#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__) #include #include #else diff --git a/crypto/openssl/engines/e_capi.c b/crypto/openssl/engines/e_capi.c new file mode 100644 index 0000000000..e2a7cb58b0 --- /dev/null +++ b/crypto/openssl/engines/e_capi.c @@ -0,0 +1,1816 @@ +/* engines/e_capi.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 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. + * ==================================================================== + */ + + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_SYS_WIN32 +#ifndef OPENSSL_NO_CAPIENG + +#include + +#include + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif + +#include + +/* + * This module uses several "new" interfaces, among which is + * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is + * one of possible values you can pass to function in question. By + * checking if it's defined we can see if wincrypt.h and accompanying + * crypt32.lib are in shape. Yes, it's rather "weak" test and if + * compilation fails, then re-configure with -DOPENSSL_NO_CAPIENG. + */ +#ifdef CERT_KEY_PROV_INFO_PROP_ID +# define __COMPILE_CAPIENG +#endif /* CERT_KEY_PROV_INFO_PROP_ID */ +#endif /* OPENSSL_NO_CAPIENG */ +#endif /* OPENSSL_SYS_WIN32 */ + +#ifdef __COMPILE_CAPIENG + +#undef X509_EXTENSIONS +#undef X509_CERT_PAIR + +/* Definitions which may be missing from earlier version of headers */ +#ifndef CERT_STORE_OPEN_EXISTING_FLAG +#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 +#endif + +#ifndef CERT_STORE_CREATE_NEW_FLAG +#define CERT_STORE_CREATE_NEW_FLAG 0x00002000 +#endif + +#ifndef CERT_SYSTEM_STORE_CURRENT_USER +#define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000 +#endif + +#include +#include +#include + +#include "e_capi_err.h" +#include "e_capi_err.c" + + +static const char *engine_capi_id = "capi"; +static const char *engine_capi_name = "CryptoAPI ENGINE"; + +typedef struct CAPI_CTX_st CAPI_CTX; +typedef struct CAPI_KEY_st CAPI_KEY; + +static void capi_addlasterror(void); +static void capi_adderror(DWORD err); + +static void CAPI_trace(CAPI_CTX *ctx, char *format, ...); + +static int capi_list_providers(CAPI_CTX *ctx, BIO *out); +static int capi_list_containers(CAPI_CTX *ctx, BIO *out); +int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename); +void capi_free_key(CAPI_KEY *key); + +static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore); + +CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id); + +static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa); +static int capi_rsa_priv_enc(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int capi_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int capi_rsa_free(RSA *rsa); + +static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, + DSA *dsa); +static int capi_dsa_free(DSA *dsa); + +static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); + +static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); +#ifdef OPENSSL_CAPIENG_DIALOG +static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); +#endif + +typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR, + LPCWSTR, DWORD, DWORD, + void *); +typedef HWND (WINAPI *GETCONSWIN)(void); + +/* This structure contains CAPI ENGINE specific data: + * it contains various global options and affects how + * other functions behave. + */ + +#define CAPI_DBG_TRACE 2 +#define CAPI_DBG_ERROR 1 + +struct CAPI_CTX_st { + int debug_level; + char *debug_file; + /* Parameters to use for container lookup */ + DWORD keytype; + LPSTR cspname; + DWORD csptype; + /* Certificate store name to use */ + LPSTR storename; + LPSTR ssl_client_store; + /* System store flags */ + DWORD store_flags; + +/* Lookup string meanings in load_private_key */ +/* Substring of subject: uses "storename" */ +#define CAPI_LU_SUBSTR 1 +/* Friendly name: uses storename */ +#define CAPI_LU_FNAME 2 +/* Container name: uses cspname, keytype */ +#define CAPI_LU_CONTNAME 3 + int lookup_method; +/* Info to dump with dumpcerts option */ +/* Issuer and serial name strings */ +#define CAPI_DMP_SUMMARY 0x1 +/* Friendly name */ +#define CAPI_DMP_FNAME 0x2 +/* Full X509_print dump */ +#define CAPI_DMP_FULL 0x4 +/* Dump PEM format certificate */ +#define CAPI_DMP_PEM 0x8 +/* Dump pseudo key (if possible) */ +#define CAPI_DMP_PSKEY 0x10 +/* Dump key info (if possible) */ +#define CAPI_DMP_PKEYINFO 0x20 + + DWORD dump_flags; + int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); + + CERTDLG certselectdlg; + GETCONSWIN getconswindow; +}; + + +static CAPI_CTX *capi_ctx_new(); +static void capi_ctx_free(CAPI_CTX *ctx); +static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check); +static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx); + +#define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE +#define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1) +#define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2) +#define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3) +#define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4) +#define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5) +#define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6) +#define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7) +#define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8) +#define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9) +#define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10) +#define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11) +#define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12) +#define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13) + +static const ENGINE_CMD_DEFN capi_cmd_defns[] = { + {CAPI_CMD_LIST_CERTS, + "list_certs", + "List all certificates in store", + ENGINE_CMD_FLAG_NO_INPUT}, + {CAPI_CMD_LOOKUP_CERT, + "lookup_cert", + "Lookup and output certificates", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_DEBUG_LEVEL, + "debug_level", + "debug level (1=errors, 2=trace)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_DEBUG_FILE, + "debug_file", + "debugging filename)", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_KEYTYPE, + "key_type", + "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_LIST_CSPS, + "list_csps", + "List all CSPs", + ENGINE_CMD_FLAG_NO_INPUT}, + {CAPI_CMD_SET_CSP_IDX, + "csp_idx", + "Set CSP by index", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_SET_CSP_NAME, + "csp_name", + "Set CSP name, (default CSP used if not specified)", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_SET_CSP_TYPE, + "csp_type", + "Set CSP type, (default RSA_PROV_FULL)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_LIST_CONTAINERS, + "list_containers", + "list container names", + ENGINE_CMD_FLAG_NO_INPUT}, + {CAPI_CMD_LIST_OPTIONS, + "list_options", + "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, " + "32=private key info)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_LOOKUP_METHOD, + "lookup_method", + "Set key lookup method (1=substring, 2=friendlyname, 3=container name)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_STORE_NAME, + "store_name", + "certificate store name, default \"MY\"", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_STORE_FLAGS, + "store_flags", + "Certificate store flags: 1 = system store", + ENGINE_CMD_FLAG_NUMERIC}, + + {0, NULL, NULL, 0} + }; + +static int capi_idx = -1; +static int rsa_capi_idx = -1; +static int dsa_capi_idx = -1; +static int cert_capi_idx = -1; + +static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) + { + int ret = 1; + CAPI_CTX *ctx; + BIO *out; + if (capi_idx == -1) + { + CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED); + return 0; + } + ctx = ENGINE_get_ex_data(e, capi_idx); + out = BIO_new_fp(stdout, BIO_NOCLOSE); + switch (cmd) + { + case CAPI_CMD_LIST_CSPS: + ret = capi_list_providers(ctx, out); + break; + + case CAPI_CMD_LIST_CERTS: + ret = capi_list_certs(ctx, out, NULL); + break; + + case CAPI_CMD_LOOKUP_CERT: + ret = capi_list_certs(ctx, out, p); + break; + + case CAPI_CMD_LIST_CONTAINERS: + ret = capi_list_containers(ctx, out); + break; + + case CAPI_CMD_STORE_NAME: + if (ctx->storename) + OPENSSL_free(ctx->storename); + ctx->storename = BUF_strdup(p); + CAPI_trace(ctx, "Setting store name to %s\n", p); + break; + + case CAPI_CMD_STORE_FLAGS: + if (i & 1) + { + ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; + ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER; + } + else + { + ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER; + ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE; + } + CAPI_trace(ctx, "Setting flags to %d\n", i); + break; + + case CAPI_CMD_DEBUG_LEVEL: + ctx->debug_level = (int)i; + CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level); + break; + + case CAPI_CMD_DEBUG_FILE: + ctx->debug_file = BUF_strdup(p); + CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file); + break; + + case CAPI_CMD_KEYTYPE: + ctx->keytype = i; + CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype); + break; + + case CAPI_CMD_SET_CSP_IDX: + ret = capi_ctx_set_provname_idx(ctx, i); + break; + + case CAPI_CMD_LIST_OPTIONS: + ctx->dump_flags = i; + break; + + case CAPI_CMD_LOOKUP_METHOD: + if (i < 1 || i > 3) + { + CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD); + return 0; + } + ctx->lookup_method = i; + break; + + case CAPI_CMD_SET_CSP_NAME: + ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1); + break; + + case CAPI_CMD_SET_CSP_TYPE: + ctx->csptype = i; + break; + + default: + CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND); + ret = 0; + } + + BIO_free(out); + return ret; + + } + +static RSA_METHOD capi_rsa_method = + { + "CryptoAPI RSA method", + 0, /* pub_enc */ + 0, /* pub_dec */ + capi_rsa_priv_enc, /* priv_enc */ + capi_rsa_priv_dec, /* priv_dec */ + 0, /* rsa_mod_exp */ + 0, /* bn_mod_exp */ + 0, /* init */ + capi_rsa_free, /* finish */ + RSA_FLAG_SIGN_VER, /* flags */ + NULL, /* app_data */ + capi_rsa_sign, /* rsa_sign */ + 0 /* rsa_verify */ + }; + +static DSA_METHOD capi_dsa_method = + { + "CryptoAPI DSA method", + capi_dsa_do_sign, /* dsa_do_sign */ + 0, /* dsa_sign_setup */ + 0, /* dsa_do_verify */ + 0, /* dsa_mod_exp */ + 0, /* bn_mod_exp */ + 0, /* init */ + capi_dsa_free, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + 0, /* dsa_paramgen */ + 0 /* dsa_keygen */ + }; + +static int capi_init(ENGINE *e) + { + CAPI_CTX *ctx; + const RSA_METHOD *ossl_rsa_meth; + const DSA_METHOD *ossl_dsa_meth; + capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); + cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); + + ctx = capi_ctx_new(); + if (!ctx || (capi_idx < 0)) + goto memerr; + + ENGINE_set_ex_data(e, capi_idx, ctx); + /* Setup RSA_METHOD */ + rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); + ossl_rsa_meth = RSA_PKCS1_SSLeay(); + capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc; + capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec; + capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp; + capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp; + + /* Setup DSA Method */ + dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); + ossl_dsa_meth = DSA_OpenSSL(); + capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify; + capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp; + capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp; + +#ifdef OPENSSL_CAPIENG_DIALOG + { + HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL")); + HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL")); + if (cryptui) + ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore"); + if (kernel) + ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow"); + if (cryptui && !OPENSSL_isservice()) + ctx->client_cert_select = cert_select_dialog; + } +#endif + + + return 1; + + memerr: + CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE); + return 0; + + return 1; + } + +static int capi_destroy(ENGINE *e) + { + ERR_unload_CAPI_strings(); + return 1; + } + +static int capi_finish(ENGINE *e) + { + CAPI_CTX *ctx; + ctx = ENGINE_get_ex_data(e, capi_idx); + capi_ctx_free(ctx); + ENGINE_set_ex_data(e, capi_idx, NULL); + return 1; + } + + +/* CryptoAPI key application data. This contains + * a handle to the private key container (for sign operations) + * and a handle to the key (for decrypt operations). + */ + +struct CAPI_KEY_st + { + /* Associated certificate context (if any) */ + PCCERT_CONTEXT pcert; + HCRYPTPROV hprov; + HCRYPTKEY key; + DWORD keyspec; + }; + +static int bind_capi(ENGINE *e) + { + if (!ENGINE_set_id(e, engine_capi_id) + || !ENGINE_set_name(e, engine_capi_name) + || !ENGINE_set_init_function(e, capi_init) + || !ENGINE_set_finish_function(e, capi_finish) + || !ENGINE_set_destroy_function(e, capi_destroy) + || !ENGINE_set_RSA(e, &capi_rsa_method) + || !ENGINE_set_DSA(e, &capi_dsa_method) + || !ENGINE_set_load_privkey_function(e, capi_load_privkey) + || !ENGINE_set_load_ssl_client_cert_function(e, + capi_load_ssl_client_cert) + || !ENGINE_set_cmd_defns(e, capi_cmd_defns) + || !ENGINE_set_ctrl_function(e, capi_ctrl)) + return 0; + ERR_load_CAPI_strings(); + + return 1; + + } + +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_helper(ENGINE *e, const char *id) + { + if(id && (strcmp(id, engine_capi_id) != 0)) + return 0; + if(!bind_capi(e)) + return 0; + return 1; + } +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) +#else +static ENGINE *engine_capi(void) + { + ENGINE *ret = ENGINE_new(); + if(!ret) + return NULL; + if(!bind_capi(ret)) + { + ENGINE_free(ret); + return NULL; + } + return ret; + } + +void ENGINE_load_capi(void) + { + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_capi(); + if(!toadd) return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); + } +#endif + + +static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) + { + int i; + /* Reverse buffer in place: since this is a keyblob structure + * that will be freed up after conversion anyway it doesn't + * matter if we change it. + */ + for(i = 0; i < binlen / 2; i++) + { + unsigned char c; + c = bin[i]; + bin[i] = bin[binlen - i - 1]; + bin[binlen - i - 1] = c; + } + + if (!BN_bin2bn(bin, binlen, bn)) + return 0; + return 1; + } + +/* Given a CAPI_KEY get an EVP_PKEY structure */ + +static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key) + { + unsigned char *pubkey = NULL; + DWORD len; + BLOBHEADER *bh; + RSA *rkey = NULL; + DSA *dkey = NULL; + EVP_PKEY *ret = NULL; + if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) + { + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); + capi_addlasterror(); + return NULL; + } + + pubkey = OPENSSL_malloc(len); + + if (!pubkey) + goto memerr; + + if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) + { + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); + capi_addlasterror(); + goto err; + } + + bh = (BLOBHEADER *)pubkey; + if (bh->bType != PUBLICKEYBLOB) + { + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); + goto err; + } + if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) + { + RSAPUBKEY *rp; + DWORD rsa_modlen; + unsigned char *rsa_modulus; + rp = (RSAPUBKEY *)(bh + 1); + if (rp->magic != 0x31415352) + { + char magstr[10]; + BIO_snprintf(magstr, 10, "%lx", rp->magic); + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); + ERR_add_error_data(2, "magic=0x", magstr); + goto err; + } + rsa_modulus = (unsigned char *)(rp + 1); + rkey = RSA_new_method(eng); + if (!rkey) + goto memerr; + + rkey->e = BN_new(); + rkey->n = BN_new(); + + if (!rkey->e || !rkey->n) + goto memerr; + + if (!BN_set_word(rkey->e, rp->pubexp)) + goto memerr; + + rsa_modlen = rp->bitlen / 8; + if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen)) + goto memerr; + + RSA_set_ex_data(rkey, rsa_capi_idx, key); + + if (!(ret = EVP_PKEY_new())) + goto memerr; + + EVP_PKEY_assign_RSA(ret, rkey); + rkey = NULL; + + } + else if (bh->aiKeyAlg == CALG_DSS_SIGN) + { + DSSPUBKEY *dp; + DWORD dsa_plen; + unsigned char *btmp; + dp = (DSSPUBKEY *)(bh + 1); + if (dp->magic != 0x31535344) + { + char magstr[10]; + BIO_snprintf(magstr, 10, "%lx", dp->magic); + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); + ERR_add_error_data(2, "magic=0x", magstr); + goto err; + } + dsa_plen = dp->bitlen / 8; + btmp = (unsigned char *)(dp + 1); + dkey = DSA_new_method(eng); + if (!dkey) + goto memerr; + dkey->p = BN_new(); + dkey->q = BN_new(); + dkey->g = BN_new(); + dkey->pub_key = BN_new(); + if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key) + goto memerr; + if (!lend_tobn(dkey->p, btmp, dsa_plen)) + goto memerr; + btmp += dsa_plen; + if (!lend_tobn(dkey->q, btmp, 20)) + goto memerr; + btmp += 20; + if (!lend_tobn(dkey->g, btmp, dsa_plen)) + goto memerr; + btmp += dsa_plen; + if (!lend_tobn(dkey->pub_key, btmp, dsa_plen)) + goto memerr; + btmp += dsa_plen; + + DSA_set_ex_data(dkey, dsa_capi_idx, key); + + if (!(ret = EVP_PKEY_new())) + goto memerr; + + EVP_PKEY_assign_DSA(ret, dkey); + dkey = NULL; + } + else + { + char algstr[10]; + BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); + ERR_add_error_data(2, "aiKeyAlg=0x", algstr); + goto err; + } + + + err: + if (pubkey) + OPENSSL_free(pubkey); + if (!ret) + { + if (rkey) + RSA_free(rkey); + if (dkey) + DSA_free(dkey); + } + + return ret; + +memerr: + CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE); + goto err; + + } + +static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) + { + CAPI_CTX *ctx; + CAPI_KEY *key; + EVP_PKEY *ret; + ctx = ENGINE_get_ex_data(eng, capi_idx); + + if (!ctx) + { + CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); + return NULL; + } + + key = capi_find_key(ctx, key_id); + + if (!key) + return NULL; + + ret = capi_get_pkey(eng, key); + + if (!ret) + capi_free_key(key); + return ret; + + } + +/* CryptoAPI RSA operations */ + +int capi_rsa_priv_enc(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED); + return -1; + } + +int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa) + { + ALG_ID alg; + HCRYPTHASH hash; + DWORD slen; + unsigned int i; + int ret = -1; + CAPI_KEY *capi_key; + CAPI_CTX *ctx; + + ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); + + CAPI_trace(ctx, "Called CAPI_rsa_sign()\n"); + + capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); + if (!capi_key) + { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY); + return -1; + } +/* Convert the signature type to a CryptoAPI algorithm ID */ + switch(dtype) + { + case NID_sha1: + alg = CALG_SHA1; + break; + + case NID_md5: + alg = CALG_MD5; + break; + + case NID_md5_sha1: + alg = CALG_SSL3_SHAMD5; + break; + default: + { + char algstr[10]; + BIO_snprintf(algstr, 10, "%lx", dtype); + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID); + ERR_add_error_data(2, "NID=0x", algstr); + return -1; + } + } + + + +/* Create the hash object */ + if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) + { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); + capi_addlasterror(); + return -1; + } +/* Set the hash value to the value passed */ + + if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) + { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE); + capi_addlasterror(); + goto err; + } + + +/* Finally sign it */ + slen = RSA_size(rsa); + if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) + { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); + capi_addlasterror(); + goto err; + } + else + { + ret = 1; + /* Inplace byte reversal of signature */ + for(i = 0; i < slen / 2; i++) + { + unsigned char c; + c = sigret[i]; + sigret[i] = sigret[slen - i - 1]; + sigret[slen - i - 1] = c; + } + *siglen = slen; + } + + /* Now cleanup */ + +err: + CryptDestroyHash(hash); + + return ret; + } + +int capi_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + int i; + unsigned char *tmpbuf; + CAPI_KEY *capi_key; + CAPI_CTX *ctx; + ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); + + CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); + + + capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); + if (!capi_key) + { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY); + return -1; + } + + if(padding != RSA_PKCS1_PADDING) + { + char errstr[10]; + BIO_snprintf(errstr, 10, "%d", padding); + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); + ERR_add_error_data(2, "padding=", errstr); + return -1; + } + + /* Create temp reverse order version of input */ + if(!(tmpbuf = OPENSSL_malloc(flen)) ) + { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE); + return -1; + } + for(i = 0; i < flen; i++) + tmpbuf[flen - i - 1] = from[i]; + + /* Finally decrypt it */ + if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen)) + { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); + capi_addlasterror(); + OPENSSL_free(tmpbuf); + return -1; + } + else memcpy(to, tmpbuf, flen); + + OPENSSL_free(tmpbuf); + + return flen; + } + +static int capi_rsa_free(RSA *rsa) + { + CAPI_KEY *capi_key; + capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); + capi_free_key(capi_key); + RSA_set_ex_data(rsa, rsa_capi_idx, 0); + return 1; + } + +/* CryptoAPI DSA operations */ + +static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, + DSA *dsa) + { + HCRYPTHASH hash; + DWORD slen; + DSA_SIG *ret = NULL; + CAPI_KEY *capi_key; + CAPI_CTX *ctx; + unsigned char csigbuf[40]; + + ctx = ENGINE_get_ex_data(dsa->engine, capi_idx); + + CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n"); + + capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); + + if (!capi_key) + { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY); + return NULL; + } + + if (dlen != 20) + { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH); + return NULL; + } + + /* Create the hash object */ + if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) + { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); + capi_addlasterror(); + return NULL; + } + + /* Set the hash value to the value passed */ + if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) + { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE); + capi_addlasterror(); + goto err; + } + + + /* Finally sign it */ + slen = sizeof(csigbuf); + if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) + { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); + capi_addlasterror(); + goto err; + } + else + { + ret = DSA_SIG_new(); + if (!ret) + goto err; + ret->r = BN_new(); + ret->s = BN_new(); + if (!ret->r || !ret->s) + goto err; + if (!lend_tobn(ret->r, csigbuf, 20) + || !lend_tobn(ret->s, csigbuf + 20, 20)) + { + DSA_SIG_free(ret); + ret = NULL; + goto err; + } + } + + /* Now cleanup */ + +err: + OPENSSL_cleanse(csigbuf, 40); + CryptDestroyHash(hash); + return ret; + } + +static int capi_dsa_free(DSA *dsa) + { + CAPI_KEY *capi_key; + capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); + capi_free_key(capi_key); + DSA_set_ex_data(dsa, dsa_capi_idx, 0); + return 1; + } + +static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr) + { + BIO *out; + + if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file)) + return; + out = BIO_new_file(ctx->debug_file, "a+"); + BIO_vprintf(out, format, argptr); + BIO_free(out); + } + +static void CAPI_trace(CAPI_CTX *ctx, char *format, ...) + { + va_list args; + va_start(args, format); + capi_vtrace(ctx, CAPI_DBG_TRACE, format, args); + va_end(args); + } + +static void capi_addlasterror(void) + { + capi_adderror(GetLastError()); + } + +static void capi_adderror(DWORD err) + { + char errstr[10]; + BIO_snprintf(errstr, 10, "%lX", err); + ERR_add_error_data(2, "Error code= 0x", errstr); + } + +static char *wide_to_asc(LPWSTR wstr) + { + char *str; + int len_0,sz; + + if (!wstr) + return NULL; + len_0 = (int)wcslen(wstr)+1; /* WideCharToMultiByte expects int */ + sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL); + if (!sz) + { + CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); + return NULL; + } + str = OPENSSL_malloc(sz); + if (!str) + { + CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL)) + { + OPENSSL_free(str); + CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); + return NULL; + } + return str; + } + +static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx) + { + LPSTR name; + DWORD len, err; + CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx); + if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len)) + { + err = GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + return 2; + CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); + capi_adderror(err); + return 0; + } + name = OPENSSL_malloc(len); + if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len)) + { + err = GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + return 2; + CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); + capi_adderror(err); + return 0; + } + *pname = name; + CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype); + + return 1; + } + +static int capi_list_providers(CAPI_CTX *ctx, BIO *out) + { + DWORD idx, ptype; + int ret; + LPSTR provname = NULL; + CAPI_trace(ctx, "capi_list_providers\n"); + BIO_printf(out, "Available CSPs:\n"); + for(idx = 0; ; idx++) + { + ret = capi_get_provname(ctx, &provname, &ptype, idx); + if (ret == 2) + break; + if (ret == 0) + break; + BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype); + OPENSSL_free(provname); + } + return 1; + } + +static int capi_list_containers(CAPI_CTX *ctx, BIO *out) + { + int ret = 1; + HCRYPTPROV hprov; + DWORD err, idx, flags, buflen = 0, clen; + LPSTR cname; + CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype); + if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) + { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); + capi_addlasterror(); + return 0; + } + if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST)) + { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); + capi_addlasterror(); + return 0; + } + CAPI_trace(ctx, "Got max container len %d\n", buflen); + if (buflen == 0) + buflen = 1024; + cname = OPENSSL_malloc(buflen); + if (!cname) + { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (idx = 0;;idx++) + { + clen = buflen; + cname[0] = 0; + + if (idx == 0) + flags = CRYPT_FIRST; + else + flags = 0; + if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags)) + { + err = GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + goto done; + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); + capi_adderror(err); + goto err; + } + CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags); + if (!cname[0] && (clen == buflen)) + { + CAPI_trace(ctx, "Enumerate bug: using workaround\n"); + goto done; + } + BIO_printf(out, "%d. %s\n", idx, cname); + } + err: + + ret = 0; + + done: + if (cname) + OPENSSL_free(cname); + CryptReleaseContext(hprov, 0); + + return ret; + } + +CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert) + { + DWORD len; + CRYPT_KEY_PROV_INFO *pinfo; + + if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) + return NULL; + pinfo = OPENSSL_malloc(len); + if (!pinfo) + { + CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE); + return NULL; + } + if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) + { + CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO); + capi_addlasterror(); + OPENSSL_free(pinfo); + return NULL; + } + return pinfo; + } + +static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo) + { + char *provname = NULL, *contname = NULL; + if (!pinfo) + { + BIO_printf(out, " No Private Key\n"); + return; + } + provname = wide_to_asc(pinfo->pwszProvName); + contname = wide_to_asc(pinfo->pwszContainerName); + if (!provname || !contname) + goto err; + + BIO_printf(out, " Private Key Info:\n"); + BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, pinfo->dwProvType); + BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec); + err: + if (provname) + OPENSSL_free(provname); + if (contname) + OPENSSL_free(contname); + } + +char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert) + { + LPWSTR wfname; + DWORD dlen; + + CAPI_trace(ctx, "capi_cert_get_fname\n"); + if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen)) + return NULL; + wfname = OPENSSL_malloc(dlen); + if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) + { + char *fname = wide_to_asc(wfname); + OPENSSL_free(wfname); + return fname; + } + CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME); + capi_addlasterror(); + + OPENSSL_free(wfname); + return NULL; + } + + +void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert) + { + X509 *x; + unsigned char *p; + unsigned long flags = ctx->dump_flags; + if (flags & CAPI_DMP_FNAME) + { + char *fname; + fname = capi_cert_get_fname(ctx, cert); + if (fname) + { + BIO_printf(out, " Friendly Name \"%s\"\n", fname); + OPENSSL_free(fname); + } + else + BIO_printf(out, " \n"); + } + + p = cert->pbCertEncoded; + x = d2i_X509(NULL, &p, cert->cbCertEncoded); + if (!x) + BIO_printf(out, " \n"); + if (flags & CAPI_DMP_SUMMARY) + { + BIO_printf(out, " Subject: "); + X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); + BIO_printf(out, "\n Issuer: "); + X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); + BIO_printf(out, "\n"); + } + if (flags & CAPI_DMP_FULL) + X509_print_ex(out, x, XN_FLAG_ONELINE,0); + + if (flags & CAPI_DMP_PKEYINFO) + { + CRYPT_KEY_PROV_INFO *pinfo; + pinfo = capi_get_prov_info(ctx, cert); + capi_dump_prov_info(ctx, out, pinfo); + if (pinfo) + OPENSSL_free(pinfo); + } + + if (flags & CAPI_DMP_PEM) + PEM_write_bio_X509(out, x); + X509_free(x); + } + +HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename) + { + HCERTSTORE hstore; + + if (!storename) + storename = ctx->storename; + if (!storename) + storename = "MY"; + CAPI_trace(ctx, "Opening certificate store %s\n", storename); + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, + ctx->store_flags, storename); + if (!hstore) + { + CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE); + capi_addlasterror(); + } + return hstore; + } + +int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id) + { + char *storename; + int idx; + int ret = 1; + HCERTSTORE hstore; + PCCERT_CONTEXT cert = NULL; + + storename = ctx->storename; + if (!storename) + storename = "MY"; + CAPI_trace(ctx, "Listing certs for store %s\n", storename); + + hstore = capi_open_store(ctx, storename); + if (!hstore) + return 0; + if (id) + { + cert = capi_find_cert(ctx, id, hstore); + if (!cert) + { + ret = 0; + goto err; + } + capi_dump_cert(ctx, out, cert); + CertFreeCertificateContext(cert); + } + else + { + for(idx = 0;;idx++) + { + LPWSTR fname = NULL; + cert = CertEnumCertificatesInStore(hstore, cert); + if (!cert) + break; + BIO_printf(out, "Certificate %d\n", idx); + capi_dump_cert(ctx, out, cert); + } + } + err: + CertCloseStore(hstore, 0); + return ret; + } + +static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore) + { + PCCERT_CONTEXT cert = NULL; + char *fname = NULL; + int match; + switch(ctx->lookup_method) + { + case CAPI_LU_SUBSTR: + return CertFindCertificateInStore(hstore, + X509_ASN_ENCODING, 0, + CERT_FIND_SUBJECT_STR_A, id, NULL); + case CAPI_LU_FNAME: + for(;;) + { + cert = CertEnumCertificatesInStore(hstore, cert); + if (!cert) + return NULL; + fname = capi_cert_get_fname(ctx, cert); + if (fname) + { + if (strcmp(fname, id)) + match = 0; + else + match = 1; + OPENSSL_free(fname); + if (match) + return cert; + } + } + default: + return NULL; + } + } + +static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec) + { + CAPI_KEY *key; + key = OPENSSL_malloc(sizeof(CAPI_KEY)); + CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", + contname, provname, ptype); + if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0)) + { + CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); + capi_addlasterror(); + goto err; + } + if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) + { + CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR); + capi_addlasterror(); + CryptReleaseContext(key->hprov, 0); + goto err; + } + key->keyspec = keyspec; + key->pcert = NULL; + return key; + + err: + OPENSSL_free(key); + return NULL; + } + +static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert) + { + CAPI_KEY *key = NULL; + CRYPT_KEY_PROV_INFO *pinfo = NULL; + char *provname = NULL, *contname = NULL; + pinfo = capi_get_prov_info(ctx, cert); + if (!pinfo) + goto err; + provname = wide_to_asc(pinfo->pwszProvName); + contname = wide_to_asc(pinfo->pwszContainerName); + if (!provname || !contname) + goto err; + key = capi_get_key(ctx, contname, provname, + pinfo->dwProvType, pinfo->dwKeySpec); + + err: + if (pinfo) + OPENSSL_free(pinfo); + if (provname) + OPENSSL_free(provname); + if (contname) + OPENSSL_free(contname); + return key; + } + +CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id) + { + PCCERT_CONTEXT cert; + HCERTSTORE hstore; + CAPI_KEY *key = NULL; + switch (ctx->lookup_method) + { + case CAPI_LU_SUBSTR: + case CAPI_LU_FNAME: + hstore = capi_open_store(ctx, NULL); + if (!hstore) + return NULL; + cert = capi_find_cert(ctx, id, hstore); + if (cert) + { + key = capi_get_cert_key(ctx, cert); + CertFreeCertificateContext(cert); + } + CertCloseStore(hstore, 0); + break; + + case CAPI_LU_CONTNAME: + key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype, + ctx->keytype); + break; + } + + return key; + } + +void capi_free_key(CAPI_KEY *key) + { + if (!key) + return; + CryptDestroyKey(key->key); + CryptReleaseContext(key->hprov, 0); + if (key->pcert) + CertFreeCertificateContext(key->pcert); + OPENSSL_free(key); + } + + +/* Initialize a CAPI_CTX structure */ + +static CAPI_CTX *capi_ctx_new() + { + CAPI_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(CAPI_CTX)); + if (!ctx) + { + CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ctx->cspname = NULL; + ctx->csptype = PROV_RSA_FULL; + ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME; + ctx->keytype = AT_KEYEXCHANGE; + ctx->storename = NULL; + ctx->ssl_client_store = NULL; + ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG | + CERT_STORE_READONLY_FLAG | + CERT_SYSTEM_STORE_CURRENT_USER; + ctx->lookup_method = CAPI_LU_SUBSTR; + ctx->debug_level = 0; + ctx->debug_file = NULL; + ctx->client_cert_select = cert_select_simple; + return ctx; + } + +static void capi_ctx_free(CAPI_CTX *ctx) + { + CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx); + if (!ctx) + return; + if (ctx->cspname) + OPENSSL_free(ctx->cspname); + if (ctx->debug_file) + OPENSSL_free(ctx->debug_file); + if (ctx->storename) + OPENSSL_free(ctx->storename); + if (ctx->ssl_client_store) + OPENSSL_free(ctx->ssl_client_store); + OPENSSL_free(ctx); + } + +static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check) + { + CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type); + if (check) + { + HCRYPTPROV hprov; + if (!CryptAcquireContextA(&hprov, NULL, pname, type, + CRYPT_VERIFYCONTEXT)) + { + CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); + capi_addlasterror(); + return 0; + } + CryptReleaseContext(hprov, 0); + } + ctx->cspname = BUF_strdup(pname); + ctx->csptype = type; + return 1; + } + +static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx) + { + LPSTR pname; + DWORD type; + if (capi_get_provname(ctx, &pname, &type, idx) != 1) + return 0; + return capi_ctx_set_provname(ctx, pname, type, 0); + } + +static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) + { + int i; + X509_NAME *nm; + /* Special case: empty list: match anything */ + if (sk_X509_NAME_num(ca_dn) <= 0) + return 1; + for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) + { + nm = sk_X509_NAME_value(ca_dn, i); + if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) + return 1; + } + return 0; + } + + + +static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data) + { + STACK_OF(X509) *certs = NULL; + X509 *x; + char *storename; + const char *p; + int i, client_cert_idx; + HCERTSTORE hstore; + PCCERT_CONTEXT cert = NULL, excert = NULL; + CAPI_CTX *ctx; + CAPI_KEY *key; + ctx = ENGINE_get_ex_data(e, capi_idx); + + *pcert = NULL; + *pkey = NULL; + + storename = ctx->ssl_client_store; + if (!storename) + storename = "MY"; + + hstore = capi_open_store(ctx, storename); + if (!hstore) + return 0; + /* Enumerate all certificates collect any matches */ + for(i = 0;;i++) + { + cert = CertEnumCertificatesInStore(hstore, cert); + if (!cert) + break; + p = cert->pbCertEncoded; + x = d2i_X509(NULL, &p, cert->cbCertEncoded); + if (!x) + { + CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); + continue; + } + if (cert_issuer_match(ca_dn, x) + && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0)) + { + key = capi_get_cert_key(ctx, cert); + if (!key) + { + X509_free(x); + continue; + } + /* Match found: attach extra data to it so + * we can retrieve the key later. + */ + excert = CertDuplicateCertificateContext(cert); + key->pcert = excert; + X509_set_ex_data(x, cert_capi_idx, key); + + if (!certs) + certs = sk_X509_new_null(); + + sk_X509_push(certs, x); + } + else + X509_free(x); + + } + + if (cert) + CertFreeCertificateContext(cert); + if (hstore) + CertCloseStore(hstore, 0); + + if (!certs) + return 0; + + + /* Select the appropriate certificate */ + + client_cert_idx = ctx->client_cert_select(e, ssl, certs); + + /* Set the selected certificate and free the rest */ + + for(i = 0; i < sk_X509_num(certs); i++) + { + x = sk_X509_value(certs, i); + if (i == client_cert_idx) + *pcert = x; + else + { + key = X509_get_ex_data(x, cert_capi_idx); + capi_free_key(key); + X509_free(x); + } + } + + sk_X509_free(certs); + + if (!*pcert) + return 0; + + /* Setup key for selected certificate */ + + key = X509_get_ex_data(*pcert, cert_capi_idx); + *pkey = capi_get_pkey(e, key); + X509_set_ex_data(*pcert, cert_capi_idx, NULL); + + return 1; + + } + + +/* Simple client cert selection function: always select first */ + +static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) + { + return 0; + } + +#ifdef OPENSSL_CAPIENG_DIALOG + +/* More complex cert selection function, using standard function + * CryptUIDlgSelectCertificateFromStore() to produce a dialog box. + */ + +/* Definitions which are in cryptuiapi.h but this is not present in older + * versions of headers. + */ + +#ifndef CRYPTUI_SELECT_LOCATION_COLUMN +#define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010 +#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004 +#endif + +#define dlg_title L"OpenSSL Application SSL Client Certificate Selection" +#define dlg_prompt L"Select a certificate to use for authentication" +#define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \ + |CRYPTUI_SELECT_INTENDEDUSE_COLUMN + +static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) + { + X509 *x; + HCERTSTORE dstore; + PCCERT_CONTEXT cert; + CAPI_CTX *ctx; + CAPI_KEY *key; + HWND hwnd; + int i, idx = -1; + if (sk_X509_num(certs) == 1) + return 0; + ctx = ENGINE_get_ex_data(e, capi_idx); + /* Create an in memory store of certificates */ + dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + if (!dstore) + { + CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE); + capi_addlasterror(); + goto err; + } + /* Add all certificates to store */ + for(i = 0; i < sk_X509_num(certs); i++) + { + x = sk_X509_value(certs, i); + key = X509_get_ex_data(x, cert_capi_idx); + + if (!CertAddCertificateContextToStore(dstore, key->pcert, + CERT_STORE_ADD_NEW, NULL)) + { + CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT); + capi_addlasterror(); + goto err; + } + + } + hwnd = GetForegroundWindow(); + if (!hwnd) + hwnd = GetActiveWindow(); + if (!hwnd && ctx->getconswindow) + hwnd = ctx->getconswindow(); + /* Call dialog to select one */ + cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt, + dlg_columns, 0, NULL); + + /* Find matching cert from list */ + if (cert) + { + for(i = 0; i < sk_X509_num(certs); i++) + { + x = sk_X509_value(certs, i); + key = X509_get_ex_data(x, cert_capi_idx); + if (CertCompareCertificate( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + cert->pCertInfo, + key->pcert->pCertInfo)) + { + idx = i; + break; + } + } + } + + err: + if (dstore) + CertCloseStore(dstore, 0); + return idx; + + } +#endif + +#else /* !__COMPILE_CAPIENG */ +#include +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +OPENSSL_EXPORT +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; } +IMPLEMENT_DYNAMIC_CHECK_FN() +#else +void ENGINE_load_capi(void){} +#endif +#endif diff --git a/crypto/openssl/engines/e_capi_err.c b/crypto/openssl/engines/e_capi_err.c new file mode 100644 index 0000000000..a1fbd04cb8 --- /dev/null +++ b/crypto/openssl/engines/e_capi_err.c @@ -0,0 +1,184 @@ +/* e_capi_err.c */ +/* ==================================================================== + * Copyright (c) 1999-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). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include "e_capi_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(0,func,0) +#define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA CAPI_str_functs[]= + { +{ERR_FUNC(CAPI_F_CAPI_CERT_GET_FNAME), "CAPI_CERT_GET_FNAME"}, +{ERR_FUNC(CAPI_F_CAPI_CTRL), "CAPI_CTRL"}, +{ERR_FUNC(CAPI_F_CAPI_CTX_NEW), "CAPI_CTX_NEW"}, +{ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME), "CAPI_CTX_SET_PROVNAME"}, +{ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN), "CAPI_DSA_DO_SIGN"}, +{ERR_FUNC(CAPI_F_CAPI_GET_KEY), "CAPI_GET_KEY"}, +{ERR_FUNC(CAPI_F_CAPI_GET_PKEY), "CAPI_GET_PKEY"}, +{ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME), "CAPI_GET_PROVNAME"}, +{ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO), "CAPI_GET_PROV_INFO"}, +{ERR_FUNC(CAPI_F_CAPI_INIT), "CAPI_INIT"}, +{ERR_FUNC(CAPI_F_CAPI_LIST_CONTAINERS), "CAPI_LIST_CONTAINERS"}, +{ERR_FUNC(CAPI_F_CAPI_LOAD_PRIVKEY), "CAPI_LOAD_PRIVKEY"}, +{ERR_FUNC(CAPI_F_CAPI_OPEN_STORE), "CAPI_OPEN_STORE"}, +{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_DEC), "CAPI_RSA_PRIV_DEC"}, +{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_ENC), "CAPI_RSA_PRIV_ENC"}, +{ERR_FUNC(CAPI_F_CAPI_RSA_SIGN), "CAPI_RSA_SIGN"}, +{ERR_FUNC(CAPI_F_CERT_SELECT_DIALOG), "CERT_SELECT_DIALOG"}, +{ERR_FUNC(CAPI_F_CLIENT_CERT_SELECT), "CLIENT_CERT_SELECT"}, +{ERR_FUNC(CAPI_F_WIDE_TO_ASC), "WIDE_TO_ASC"}, +{0,NULL} + }; + +static ERR_STRING_DATA CAPI_str_reasons[]= + { +{ERR_REASON(CAPI_R_CANT_CREATE_HASH_OBJECT),"cant create hash object"}, +{ERR_REASON(CAPI_R_CANT_FIND_CAPI_CONTEXT),"cant find capi context"}, +{ERR_REASON(CAPI_R_CANT_GET_KEY) ,"cant get key"}, +{ERR_REASON(CAPI_R_CANT_SET_HASH_VALUE) ,"cant set hash value"}, +{ERR_REASON(CAPI_R_CRYPTACQUIRECONTEXT_ERROR),"cryptacquirecontext error"}, +{ERR_REASON(CAPI_R_CRYPTENUMPROVIDERS_ERROR),"cryptenumproviders error"}, +{ERR_REASON(CAPI_R_DECRYPT_ERROR) ,"decrypt error"}, +{ERR_REASON(CAPI_R_ENGINE_NOT_INITIALIZED),"engine not initialized"}, +{ERR_REASON(CAPI_R_ENUMCONTAINERS_ERROR) ,"enumcontainers error"}, +{ERR_REASON(CAPI_R_ERROR_ADDING_CERT) ,"error adding cert"}, +{ERR_REASON(CAPI_R_ERROR_CREATING_STORE) ,"error creating store"}, +{ERR_REASON(CAPI_R_ERROR_GETTING_FRIENDLY_NAME),"error getting friendly name"}, +{ERR_REASON(CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO),"error getting key provider info"}, +{ERR_REASON(CAPI_R_ERROR_OPENING_STORE) ,"error opening store"}, +{ERR_REASON(CAPI_R_ERROR_SIGNING_HASH) ,"error signing hash"}, +{ERR_REASON(CAPI_R_FUNCTION_NOT_SUPPORTED),"function not supported"}, +{ERR_REASON(CAPI_R_GETUSERKEY_ERROR) ,"getuserkey error"}, +{ERR_REASON(CAPI_R_INVALID_DIGEST_LENGTH),"invalid digest length"}, +{ERR_REASON(CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid dsa public key blob magic number"}, +{ERR_REASON(CAPI_R_INVALID_LOOKUP_METHOD),"invalid lookup method"}, +{ERR_REASON(CAPI_R_INVALID_PUBLIC_KEY_BLOB),"invalid public key blob"}, +{ERR_REASON(CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid rsa public key blob magic number"}, +{ERR_REASON(CAPI_R_PUBKEY_EXPORT_ERROR) ,"pubkey export error"}, +{ERR_REASON(CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR),"pubkey export length error"}, +{ERR_REASON(CAPI_R_UNKNOWN_COMMAND) ,"unknown command"}, +{ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID),"unsupported algorithm nid"}, +{ERR_REASON(CAPI_R_UNSUPPORTED_PADDING) ,"unsupported padding"}, +{ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM),"unsupported public key algorithm"}, +{ERR_REASON(CAPI_R_WIN32_ERROR) ,"win32 error"}, +{0,NULL} + }; + +#endif + +#ifdef CAPI_LIB_NAME +static ERR_STRING_DATA CAPI_lib_name[]= + { +{0 ,CAPI_LIB_NAME}, +{0,NULL} + }; +#endif + + +static int CAPI_lib_error_code=0; +static int CAPI_error_init=1; + +static void ERR_load_CAPI_strings(void) + { + if (CAPI_lib_error_code == 0) + CAPI_lib_error_code=ERR_get_next_error_library(); + + if (CAPI_error_init) + { + CAPI_error_init=0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(CAPI_lib_error_code,CAPI_str_functs); + ERR_load_strings(CAPI_lib_error_code,CAPI_str_reasons); +#endif + +#ifdef CAPI_LIB_NAME + CAPI_lib_name->error = ERR_PACK(CAPI_lib_error_code,0,0); + ERR_load_strings(0,CAPI_lib_name); +#endif + } + } + +static void ERR_unload_CAPI_strings(void) + { + if (CAPI_error_init == 0) + { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(CAPI_lib_error_code,CAPI_str_functs); + ERR_unload_strings(CAPI_lib_error_code,CAPI_str_reasons); +#endif + +#ifdef CAPI_LIB_NAME + ERR_unload_strings(0,CAPI_lib_name); +#endif + CAPI_error_init=1; + } + } + +static void ERR_CAPI_error(int function, int reason, char *file, int line) + { + if (CAPI_lib_error_code == 0) + CAPI_lib_error_code=ERR_get_next_error_library(); + ERR_PUT_error(CAPI_lib_error_code,function,reason,file,line); + } diff --git a/crypto/openssl/engines/e_capi_err.h b/crypto/openssl/engines/e_capi_err.h new file mode 100644 index 0000000000..4c749ec43d --- /dev/null +++ b/crypto/openssl/engines/e_capi_err.h @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2001-2008 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). + * + */ + +#ifndef HEADER_CAPI_ERR_H +#define HEADER_CAPI_ERR_H + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_CAPI_strings(void); +static void ERR_unload_CAPI_strings(void); +static void ERR_CAPI_error(int function, int reason, char *file, int line); +#define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the CAPI functions. */ + +/* Function codes. */ +#define CAPI_F_CAPI_CERT_GET_FNAME 99 +#define CAPI_F_CAPI_CTRL 100 +#define CAPI_F_CAPI_CTX_NEW 101 +#define CAPI_F_CAPI_CTX_SET_PROVNAME 102 +#define CAPI_F_CAPI_DSA_DO_SIGN 114 +#define CAPI_F_CAPI_GET_KEY 103 +#define CAPI_F_CAPI_GET_PKEY 115 +#define CAPI_F_CAPI_GET_PROVNAME 104 +#define CAPI_F_CAPI_GET_PROV_INFO 105 +#define CAPI_F_CAPI_INIT 106 +#define CAPI_F_CAPI_LIST_CONTAINERS 107 +#define CAPI_F_CAPI_LOAD_PRIVKEY 108 +#define CAPI_F_CAPI_OPEN_STORE 109 +#define CAPI_F_CAPI_RSA_PRIV_DEC 110 +#define CAPI_F_CAPI_RSA_PRIV_ENC 111 +#define CAPI_F_CAPI_RSA_SIGN 112 +#define CAPI_F_CERT_SELECT_DIALOG 117 +#define CAPI_F_CLIENT_CERT_SELECT 116 +#define CAPI_F_WIDE_TO_ASC 113 + +/* Reason codes. */ +#define CAPI_R_CANT_CREATE_HASH_OBJECT 99 +#define CAPI_R_CANT_FIND_CAPI_CONTEXT 100 +#define CAPI_R_CANT_GET_KEY 101 +#define CAPI_R_CANT_SET_HASH_VALUE 102 +#define CAPI_R_CRYPTACQUIRECONTEXT_ERROR 103 +#define CAPI_R_CRYPTENUMPROVIDERS_ERROR 104 +#define CAPI_R_DECRYPT_ERROR 105 +#define CAPI_R_ENGINE_NOT_INITIALIZED 106 +#define CAPI_R_ENUMCONTAINERS_ERROR 107 +#define CAPI_R_ERROR_ADDING_CERT 125 +#define CAPI_R_ERROR_CREATING_STORE 126 +#define CAPI_R_ERROR_GETTING_FRIENDLY_NAME 108 +#define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO 109 +#define CAPI_R_ERROR_OPENING_STORE 110 +#define CAPI_R_ERROR_SIGNING_HASH 111 +#define CAPI_R_FUNCTION_NOT_SUPPORTED 112 +#define CAPI_R_GETUSERKEY_ERROR 113 +#define CAPI_R_INVALID_DIGEST_LENGTH 124 +#define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 122 +#define CAPI_R_INVALID_LOOKUP_METHOD 114 +#define CAPI_R_INVALID_PUBLIC_KEY_BLOB 115 +#define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 123 +#define CAPI_R_PUBKEY_EXPORT_ERROR 116 +#define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR 117 +#define CAPI_R_UNKNOWN_COMMAND 118 +#define CAPI_R_UNSUPPORTED_ALGORITHM_NID 119 +#define CAPI_R_UNSUPPORTED_PADDING 120 +#define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 121 +#define CAPI_R_WIN32_ERROR 127 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/openssl/engines/e_chil.c b/crypto/openssl/engines/e_chil.c index e1847622ea..9c2729c96d 100644 --- a/crypto/openssl/engines/e_chil.c +++ b/crypto/openssl/engines/e_chil.c @@ -111,11 +111,10 @@ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, #ifndef OPENSSL_NO_RSA /* RSA stuff */ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); -#endif -#ifndef OPENSSL_NO_RSA /* This function is aliased to mod_exp (with the mont stuff dropped). */ static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int hwcrhk_rsa_finish(RSA *rsa); #endif #ifndef OPENSSL_NO_DH @@ -135,10 +134,6 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data); static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data); -#ifndef OPENSSL_NO_RSA -static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int ind,long argl, void *argp); -#endif /* Interaction stuff */ static int hwcrhk_insert_card(const char *prompt_info, @@ -193,7 +188,7 @@ static RSA_METHOD hwcrhk_rsa = hwcrhk_rsa_mod_exp, hwcrhk_mod_exp_mont, NULL, - NULL, + hwcrhk_rsa_finish, 0, NULL, NULL, @@ -232,7 +227,6 @@ static RAND_METHOD hwcrhk_rand = /* Constants used when creating the ENGINE */ static const char *engine_hwcrhk_id = "chil"; static const char *engine_hwcrhk_name = "CHIL hardware engine support"; - #ifndef OPENSSL_NO_DYNAMIC_ENGINE /* Compatibility hack, the dynamic library uses this form in the path */ static const char *engine_hwcrhk_id_alt = "ncipher"; @@ -603,7 +597,7 @@ static int hwcrhk_init(ENGINE *e) if (hndidx_rsa == -1) hndidx_rsa = RSA_get_ex_new_index(0, "nFast HWCryptoHook RSA key handle", - NULL, NULL, hwcrhk_ex_free); + NULL, NULL, NULL); #endif return 1; err: @@ -847,8 +841,6 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, return res; err: - if (res) - EVP_PKEY_free(res); #ifndef OPENSSL_NO_RSA if (rtmp) RSA_free(rtmp); @@ -1081,6 +1073,21 @@ static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, { return hwcrhk_mod_exp(r, a, p, m, ctx); } + +static int hwcrhk_rsa_finish(RSA *rsa) + { + HWCryptoHook_RSAKeyHandle *hptr; + int ret; + hptr = RSA_get_ex_data(rsa, hndidx_rsa); + if (hptr) + { + ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); + OPENSSL_free(hptr); + RSA_set_ex_data(rsa, hndidx_rsa, NULL); + } + return 1; + } + #endif #ifndef OPENSSL_NO_DH @@ -1139,34 +1146,6 @@ static int hwcrhk_rand_status(void) return 1; } -/* This cleans up an RSA KM key, called when ex_data is freed */ -#ifndef OPENSSL_NO_RSA -static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int ind,long argl, void *argp) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; -#ifndef OPENSSL_NO_RSA - HWCryptoHook_RSAKeyHandle *hptr; -#endif -#if !defined(OPENSSL_NO_RSA) - int ret; -#endif - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - -#ifndef OPENSSL_NO_RSA - hptr = (HWCryptoHook_RSAKeyHandle *) item; - if(hptr) - { - ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); - OPENSSL_free(hptr); - } -#endif -} -#endif - /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model * these just wrap the POSIX functions and add some logging. */ @@ -1204,6 +1183,11 @@ static int hwcrhk_get_pass(const char *prompt_info, pem_password_cb *callback = NULL; void *callback_data = NULL; UI_METHOD *ui_method = NULL; + /* Despite what the documentation says prompt_info can be + * an empty string. + */ + if (prompt_info && !*prompt_info) + prompt_info = NULL; if (cactx) { @@ -1305,10 +1289,14 @@ static int hwcrhk_insert_card(const char *prompt_info, { char answer; char buf[BUFSIZ]; - - if (wrong_info) + /* Despite what the documentation says wrong_info can be + * an empty string. + */ + if (wrong_info && *wrong_info) BIO_snprintf(buf, sizeof(buf)-1, "Current card: \"%s\"\n", wrong_info); + else + buf[0] = 0; ok = UI_dup_info_string(ui, buf); if (ok >= 0 && prompt_info) { diff --git a/crypto/openssl/engines/e_gmp.c b/crypto/openssl/engines/e_gmp.c index a1a2d2bda6..c1f5601b62 100644 --- a/crypto/openssl/engines/e_gmp.c +++ b/crypto/openssl/engines/e_gmp.c @@ -85,7 +85,9 @@ #include #include #include +#ifndef OPENSSL_NO_RSA #include +#endif #include #ifndef OPENSSL_NO_HW @@ -471,6 +473,6 @@ IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) OPENSSL_EXPORT int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; } #endif -#endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +#endif /* !OPENSSL_NO_DYNAMIC_ENGINE */ #endif /* !OPENSSL_NO_HW */ diff --git a/crypto/openssl/crypto/engine/eng_padlock.c b/crypto/openssl/engines/e_padlock.c similarity index 98% rename from crypto/openssl/crypto/engine/eng_padlock.c rename to crypto/openssl/engines/e_padlock.c index 743558ab33..381a746058 100644 --- a/crypto/openssl/crypto/engine/eng_padlock.c +++ b/crypto/openssl/engines/e_padlock.c @@ -123,14 +123,16 @@ void ENGINE_load_padlock (void) #ifdef COMPILE_HW_PADLOCK /* We do these includes here to avoid header problems on platforms that do not have the VIA padlock anyway... */ -#ifdef _MSC_VER +#include +#ifdef _WIN32 # include -# define alloca _alloca -#elif defined(NETWARE_CLIB) && defined(__GNUC__) - void *alloca(size_t); -# define alloca(s) __builtin_alloca(s) -#else -# include +# ifndef alloca +# define alloca _alloca +# endif +#elif defined(__GNUC__) +# ifndef alloca +# define alloca(s) __builtin_alloca(s) +# endif #endif /* Function for ENGINE detection and control */ @@ -234,7 +236,7 @@ padlock_bind_fn(ENGINE *e, const char *id) return 1; } -IMPLEMENT_DYNAMIC_CHECK_FN () +IMPLEMENT_DYNAMIC_CHECK_FN() IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn) #endif /* DYNAMIC_ENGINE */ @@ -1213,6 +1215,12 @@ static RAND_METHOD padlock_rand = { padlock_rand_status, /* rand status */ }; +#else /* !COMPILE_HW_PADLOCK */ +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +OPENSSL_EXPORT +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; } +IMPLEMENT_DYNAMIC_CHECK_FN() +#endif #endif /* COMPILE_HW_PADLOCK */ #endif /* !OPENSSL_NO_HW_PADLOCK */ diff --git a/crypto/openssl/engines/e_sureware.c b/crypto/openssl/engines/e_sureware.c index 58fa9a98ee..cd0fa4c397 100644 --- a/crypto/openssl/engines/e_sureware.c +++ b/crypto/openssl/engines/e_sureware.c @@ -758,8 +758,6 @@ static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,un } return res; err: - if (res) - EVP_PKEY_free(res); #ifndef OPENSSL_NO_RSA if (rsatmp) RSA_free(rsatmp); diff --git a/crypto/openssl/engines/e_ubsec.c b/crypto/openssl/engines/e_ubsec.c index a0f320caf5..9b747b9aea 100644 --- a/crypto/openssl/engines/e_ubsec.c +++ b/crypto/openssl/engines/e_ubsec.c @@ -95,14 +95,14 @@ static int ubsec_finish(ENGINE *e); static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx); +#ifndef OPENSSL_NO_RSA static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dp, const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx); -#ifndef OPENSSL_NO_RSA static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); -#endif static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +#endif #ifndef OPENSSL_NO_DSA #ifdef NOT_USED static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, @@ -302,10 +302,10 @@ static t_UBSEC_diffie_hellman_generate_ioctl *p_UBSEC_diffie_hellman_generate_ioctl = NULL; static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL; #endif -/* #ifndef OPENSSL_NO_RSA */ +#ifndef OPENSSL_NO_RSA static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL; static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; -/* #endif */ +#endif #ifndef OPENSSL_NO_DSA static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL; static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL; @@ -624,7 +624,6 @@ static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) err: return to_return; } -#endif static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dp, @@ -672,6 +671,7 @@ static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2; return 1; } +#endif #ifndef OPENSSL_NO_DSA #ifdef NOT_USED @@ -704,6 +704,8 @@ static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, #endif #endif +#ifndef OPENSSL_NO_RSA + /* * This function is aliased to mod_exp (with the mont stuff dropped). */ @@ -712,7 +714,6 @@ static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, { int ret = 0; -#ifndef OPENSSL_NO_RSA /* Do in software if the key is too large for the hardware. */ if (BN_num_bits(m) > max_key_len) { @@ -720,13 +721,13 @@ static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx); } else -#endif { ret = ubsec_mod_exp(r, a, p, m, ctx); } return ret; } +#endif #ifndef OPENSSL_NO_DH /* This function is aliased to mod_exp (with the dh and mont dropped). */ diff --git a/crypto/openssl/ssl/bio_ssl.c b/crypto/openssl/ssl/bio_ssl.c index 420deb7fc9..af319af302 100644 --- a/crypto/openssl/ssl/bio_ssl.c +++ b/crypto/openssl/ssl/bio_ssl.c @@ -398,17 +398,19 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) } break; case BIO_CTRL_POP: - /* ugly bit of a hack */ - if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */ + /* Only detach if we are the BIO explicitly being popped */ + if (b == ptr) { - BIO_free_all(ssl->wbio); - } - if (b->next_bio != NULL) - { - CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO); + /* Shouldn't happen in practice because the + * rbio and wbio are the same when pushed. + */ + if (ssl->rbio != ssl->wbio) + BIO_free_all(ssl->wbio); + if (b->next_bio != NULL) + CRYPTO_add(&b->next_bio->references,-1,CRYPTO_LOCK_BIO); + ssl->wbio=NULL; + ssl->rbio=NULL; } - ssl->wbio=NULL; - ssl->rbio=NULL; break; case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); @@ -543,7 +545,6 @@ BIO *BIO_new_ssl_connect(SSL_CTX *ctx) return(ret); err: if (con != NULL) BIO_free(con); - if (ret != NULL) BIO_free(ret); return(NULL); } diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c index 0a5c08d713..4ce4064cc9 100644 --- a/crypto/openssl/ssl/d1_both.c +++ b/crypto/openssl/ssl/d1_both.c @@ -123,6 +123,37 @@ #include #include +#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) + +#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ + if ((end) - (start) <= 8) { \ + long ii; \ + for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ + } else { \ + long ii; \ + bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ + for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ + bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ + } } + +#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ + long ii; \ + OPENSSL_assert((msg_len) > 0); \ + is_complete = 1; \ + if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ + if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ + if (bitmask[ii] != 0xff) { is_complete = 0; break; } } + +#if 0 +#define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ + long ii; \ + printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ + printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ + printf("\n"); } +#endif + +static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; +static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; /* XDTLS: figure out the right values */ static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; @@ -140,10 +171,11 @@ static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok); static hm_fragment * -dtls1_hm_fragment_new(unsigned long frag_len) +dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) { hm_fragment *frag = NULL; unsigned char *buf = NULL; + unsigned char *bitmask = NULL; frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); if ( frag == NULL) @@ -162,6 +194,21 @@ dtls1_hm_fragment_new(unsigned long frag_len) /* zero length fragment gets zero frag->fragment */ frag->fragment = buf; + /* Initialize reassembly bitmask if necessary */ + if (reassembly) + { + bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); + if (bitmask == NULL) + { + if (buf != NULL) OPENSSL_free(buf); + OPENSSL_free(frag); + return NULL; + } + memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); + } + + frag->reassembly = bitmask; + return frag; } @@ -169,6 +216,7 @@ static void dtls1_hm_fragment_free(hm_fragment *frag) { if (frag->fragment) OPENSSL_free(frag->fragment); + if (frag->reassembly) OPENSSL_free(frag->reassembly); OPENSSL_free(frag); } @@ -226,7 +274,7 @@ int dtls1_do_write(SSL *s, int type) (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); if (s->write_hash) - mac_size = EVP_MD_size(s->write_hash); + mac_size = EVP_MD_CTX_size(s->write_hash); else mac_size = 0; @@ -312,7 +360,7 @@ int dtls1_do_write(SSL *s, int type) const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; int xlen; - if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) + if (frag_off == 0 && s->version != DTLS1_BAD_VER) { /* reconstruct message header is if it * is being sent in single fragment */ @@ -363,6 +411,8 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) { int i, al; struct hm_header_st *msg_hdr; + unsigned char *p; + unsigned long msg_len; /* s3->tmp is used to store messages that are unexpected, caused * by the absence of an optional handshake message */ @@ -382,76 +432,55 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) } msg_hdr = &s->d1->r_msg_hdr; - do - { - if ( msg_hdr->frag_off == 0) - { - /* s->d1->r_message_header.msg_len = 0; */ - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - } + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - i = dtls1_get_message_fragment(s, st1, stn, max, ok); - if ( i == DTLS1_HM_BAD_FRAGMENT || - i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ - continue; - else if ( i <= 0 && !*ok) - return i; +again: + i = dtls1_get_message_fragment(s, st1, stn, max, ok); + if ( i == DTLS1_HM_BAD_FRAGMENT || + i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ + goto again; + else if ( i <= 0 && !*ok) + return i; - /* Note that s->init_sum is used as a counter summing - * up fragments' lengths: as soon as they sum up to - * handshake packet length, we assume we have got all - * the fragments. Overlapping fragments would cause - * premature termination, so we don't expect overlaps. - * Well, handling overlaps would require something more - * drastic. Indeed, as it is now there is no way to - * tell if out-of-order fragment from the middle was - * the last. '>=' is the best/least we can do to control - * the potential damage caused by malformed overlaps. */ - if ((unsigned int)s->init_num >= msg_hdr->msg_len) - { - unsigned char *p = (unsigned char *)s->init_buf->data; - unsigned long msg_len = msg_hdr->msg_len; - - /* reconstruct message header as if it was - * sent in single fragment */ - *(p++) = msg_hdr->type; - l2n3(msg_len,p); - s2n (msg_hdr->seq,p); - l2n3(0,p); - l2n3(msg_len,p); - if (s->client_version != DTLS1_BAD_VER) - p -= DTLS1_HM_HEADER_LENGTH, - msg_len += DTLS1_HM_HEADER_LENGTH; - - ssl3_finish_mac(s, p, msg_len); - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, msg_len, - s, s->msg_callback_arg); - - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - - s->d1->handshake_read_seq++; - /* we just read a handshake message from the other side: - * this means that we don't need to retransmit of the - * buffered messages. - * XDTLS: may be able clear out this - * buffer a little sooner (i.e if an out-of-order - * handshake message/record is received at the record - * layer. - * XDTLS: exception is that the server needs to - * know that change cipher spec and finished messages - * have been received by the client before clearing this - * buffer. this can simply be done by waiting for the - * first data segment, but is there a better way? */ - dtls1_clear_record_buffer(s); - - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - return s->init_num; - } - else - msg_hdr->frag_off = i; - } while(1) ; + p = (unsigned char *)s->init_buf->data; + msg_len = msg_hdr->msg_len; + + /* reconstruct message header */ + *(p++) = msg_hdr->type; + l2n3(msg_len,p); + s2n (msg_hdr->seq,p); + l2n3(0,p); + l2n3(msg_len,p); + if (s->version != DTLS1_BAD_VER) { + p -= DTLS1_HM_HEADER_LENGTH; + msg_len += DTLS1_HM_HEADER_LENGTH; + } + + ssl3_finish_mac(s, p, msg_len); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + p, msg_len, + s, s->msg_callback_arg); + + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + s->d1->handshake_read_seq++; + /* we just read a handshake message from the other side: + * this means that we don't need to retransmit of the + * buffered messages. + * XDTLS: may be able clear out this + * buffer a little sooner (i.e if an out-of-order + * handshake message/record is received at the record + * layer. + * XDTLS: exception is that the server needs to + * know that change cipher spec and finished messages + * have been received by the client before clearing this + * buffer. this can simply be done by waiting for the + * first data segment, but is there a better way? */ + dtls1_clear_record_buffer(s); + + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + return s->init_num; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); @@ -485,7 +514,7 @@ static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max { /* msg_len is limited to 2^24, but is effectively checked * against max above */ - if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) + if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENGTH)) { SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); return SSL_AD_INTERNAL_ERROR; @@ -527,6 +556,10 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) return 0; frag = (hm_fragment *)item->data; + + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; if ( s->d1->handshake_read_seq == frag->msg_header.seq) { @@ -561,24 +594,133 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) } +static int +dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) + { + hm_fragment *frag = NULL; + pitem *item = NULL; + int i = -1, is_complete; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len, max_len; + + if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) + goto err; + + /* Determine maximum allowed message size. Depends on (user set) + * maximum certificate length, but 16k is minimum. + */ + if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list) + max_len = s->max_cert_list; + else + max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + + if ((msg_hdr->frag_off+frag_len) > max_len) + goto err; + + /* Try to find item in queue */ + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char) (msg_hdr->seq>>8); + seq64be[7] = (unsigned char) msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + if (item == NULL) + { + frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); + if ( frag == NULL) + goto err; + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + frag->msg_header.frag_len = frag->msg_header.msg_len; + frag->msg_header.frag_off = 0; + } + else + frag = (hm_fragment*) item->data; + + /* If message is already reassembled, this must be a + * retransmit and can be dropped. + */ + if (frag->reassembly == NULL) + { + unsigned char devnull [256]; + + while (frag_len) + { + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, + devnull, + frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); + if (i<=0) goto err; + frag_len -= i; + } + return DTLS1_HM_FRAGMENT_RETRY; + } + + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, + frag->fragment + msg_hdr->frag_off,frag_len,0); + if (i<=0 || (unsigned long)i!=frag_len) + goto err; + + RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, + (long)(msg_hdr->frag_off + frag_len)); + + RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, + is_complete); + + if (is_complete) + { + OPENSSL_free(frag->reassembly); + frag->reassembly = NULL; + } + + if (item == NULL) + { + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq>>8); + seq64be[7] = (unsigned char)(msg_hdr->seq); + + item = pitem_new(seq64be, frag); + if (item == NULL) + { + goto err; + i = -1; + } + + pqueue_insert(s->d1->buffered_messages, item); + } + + return DTLS1_HM_FRAGMENT_RETRY; + +err: + if (frag != NULL) dtls1_hm_fragment_free(frag); + if (item != NULL) OPENSSL_free(item); + *ok = 0; + return i; + } + + static int dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) { int i=-1; hm_fragment *frag = NULL; pitem *item = NULL; - PQ_64BIT seq64; + unsigned char seq64be[8]; unsigned long frag_len = msg_hdr->frag_len; if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) goto err; /* Try to find item in queue, to prevent duplicate entries */ - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, msg_hdr->seq); - item = pqueue_find(s->d1->buffered_messages, seq64); - pq_64bit_free(&seq64); - + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char) (msg_hdr->seq>>8); + seq64be[7] = (unsigned char) msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + /* If we already have an entry and this one is a fragment, + * don't discard it and rather try to reassemble it. + */ + if (item != NULL && frag_len < msg_hdr->msg_len) + item = NULL; + /* Discard the message if sequence number was already there, is * too far in the future, already in the queue or if we received * a FINISHED before the SERVER_HELLO, which then must be a stale @@ -599,31 +741,36 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) frag_len -= i; } } + else + { + if (frag_len && frag_len < msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); - if (frag_len) - { - frag = dtls1_hm_fragment_new(frag_len); + frag = dtls1_hm_fragment_new(frag_len, 0); if ( frag == NULL) goto err; memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - /* read the body of the fragment (header has already been read) */ - i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, - frag->fragment,frag_len,0); - if (i<=0 || (unsigned long)i!=frag_len) - goto err; + if (frag_len) + { + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, + frag->fragment,frag_len,0); + if (i<=0 || (unsigned long)i!=frag_len) + goto err; + } - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, msg_hdr->seq); + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq>>8); + seq64be[7] = (unsigned char)(msg_hdr->seq); - item = pitem_new(seq64, frag); - pq_64bit_free(&seq64); + item = pitem_new(seq64be, frag); if ( item == NULL) goto err; pqueue_insert(s->d1->buffered_messages, item); - } + } return DTLS1_HM_FRAGMENT_RETRY; @@ -639,14 +786,14 @@ static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) { unsigned char wire[DTLS1_HM_HEADER_LENGTH]; - unsigned long l, frag_off, frag_len; + unsigned long len, frag_off, frag_len; int i,al; struct hm_header_st msg_hdr; /* see if we have the required fragment already */ if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) { - if (*ok) s->init_num += frag_len; + if (*ok) s->init_num = frag_len; return frag_len; } @@ -671,10 +818,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) if ( msg_hdr.seq != s->d1->handshake_read_seq) return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); - l = msg_hdr.msg_len; + len = msg_hdr.msg_len; frag_off = msg_hdr.frag_off; frag_len = msg_hdr.frag_len; + if (frag_len && frag_len < len) + return dtls1_reassemble_fragment(s, &msg_hdr, ok); + if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && wire[0] == SSL3_MT_HELLO_REQUEST) { @@ -734,7 +884,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) * s->init_buf->data, but as a counter summing up fragments' * lengths: as soon as they sum up to handshake packet * length, we assume we have got all the fragments. */ - s->init_num += frag_len; + s->init_num = frag_len; return frag_len; f_err: @@ -757,8 +907,6 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) p= &(d[DTLS1_HM_HEADER_LENGTH]); i=s->method->ssl3_enc->final_finish_mac(s, - &(s->s3->finish_dgst1), - &(s->s3->finish_dgst2), sender,slen,s->s3->tmp.finish_md); s->s3->tmp.finish_md_len = i; memcpy(p, s->s3->tmp.finish_md, i); @@ -823,12 +971,11 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; s->init_num=DTLS1_CCS_HEADER_LENGTH; - if (s->client_version == DTLS1_BAD_VER) - { + if (s->version == DTLS1_BAD_VER) { s->d1->next_handshake_write_seq++; s2n(s->d1->handshake_write_seq,p); s->init_num+=2; - } + } s->init_off=0; @@ -847,21 +994,21 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) { - int n; - unsigned char *p; + int n; + unsigned char *p; - n=i2d_X509(x,NULL); - if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) - { - SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); - return 0; - } - p=(unsigned char *)&(buf->data[*l]); - l2n3(n,p); - i2d_X509(x,&p); - *l+=n+3; + n=i2d_X509(x,NULL); + if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) + { + SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); + return 0; + } + p=(unsigned char *)&(buf->data[*l]); + l2n3(n,p); + i2d_X509(x,&p); + *l+=n+3; - return 1; + return 1; } unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) { @@ -880,7 +1027,7 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) if (x != NULL) { X509_STORE_CTX xs_ctx; - + if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL)) { SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); @@ -888,6 +1035,8 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) } X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); for (i=0; i < sk_X509_num(xs_ctx.chain); i++) { x = sk_X509_value(xs_ctx.chain, i); @@ -900,7 +1049,7 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) } X509_STORE_CTX_cleanup(&xs_ctx); } - /* Thawte special :-) */ + /* Thawte special :-) */ for (i=0; ictx->extra_certs); i++) { x=sk_X509_value(s->ctx->extra_certs,i); @@ -1004,20 +1153,20 @@ dtls1_buffer_message(SSL *s, int is_ccs) { pitem *item; hm_fragment *frag; - PQ_64BIT seq64; + unsigned char seq64be[8]; /* this function is called immediately after a message has * been serialized */ OPENSSL_assert(s->init_off == 0); - frag = dtls1_hm_fragment_new(s->init_num); + frag = dtls1_hm_fragment_new(s->init_num, 0); memcpy(frag->fragment, s->init_buf->data, s->init_num); if ( is_ccs) { OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); + ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num); } else { @@ -1038,15 +1187,14 @@ dtls1_buffer_message(SSL *s, int is_ccs) frag->msg_header.saved_retransmit_state.compress = s->compress; frag->msg_header.saved_retransmit_state.session = s->session; frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; + + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq, + frag->msg_header.is_ccs)>>8); + seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq, + frag->msg_header.is_ccs)); - pq_64bit_init(&seq64); - - pq_64bit_assign_word(&seq64, - dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs)); - - item = pitem_new(seq64, frag); - pq_64bit_free(&seq64); + item = pitem_new(seq64be, frag); if ( item == NULL) { dtls1_hm_fragment_free(frag); @@ -1072,7 +1220,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, pitem *item; hm_fragment *frag ; unsigned long header_length; - PQ_64BIT seq64; + unsigned char seq64be[8]; struct dtls1_retransmit_state saved_state; unsigned char save_write_sequence[8]; @@ -1082,11 +1230,11 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, */ /* XDTLS: the requested message ought to be found, otherwise error */ - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, seq); + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char)(seq>>8); + seq64be[7] = (unsigned char)seq; - item = pqueue_find(s->d1->sent_messages, seq64); - pq_64bit_free(&seq64); + item = pqueue_find(s->d1->sent_messages, seq64be); if ( item == NULL) { fprintf(stderr, "retransmit: message %d non-existant\n", seq); @@ -1237,7 +1385,7 @@ dtls1_min_mtu(void) static unsigned int dtls1_guess_mtu(unsigned int curr_mtu) { - size_t i; + unsigned int i; if ( curr_mtu == 0 ) return g_probable_mtu[0] ; diff --git a/crypto/openssl/ssl/d1_clnt.c b/crypto/openssl/ssl/d1_clnt.c index 223d116279..5bc9eb6603 100644 --- a/crypto/openssl/ssl/d1_clnt.c +++ b/crypto/openssl/ssl/d1_clnt.c @@ -4,7 +4,7 @@ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -115,20 +115,23 @@ #include #include "ssl_locl.h" +#ifndef OPENSSL_NO_KRB5 #include "kssl_lcl.h" +#endif #include #include #include #include #include +#include #ifndef OPENSSL_NO_DH #include #endif -static SSL_METHOD *dtls1_get_client_method(int ver); +static const SSL_METHOD *dtls1_get_client_method(int ver); static int dtls1_get_hello_verify(SSL *s); -static SSL_METHOD *dtls1_get_client_method(int ver) +static const SSL_METHOD *dtls1_get_client_method(int ver) { if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) return(DTLSv1_client_method()); @@ -144,7 +147,7 @@ IMPLEMENT_dtls1_meth_func(DTLSv1_client_method, int dtls1_connect(SSL *s) { BUF_MEM *buf=NULL; - unsigned long Time=(unsigned long)time(NULL),l; + unsigned long Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0;; @@ -296,8 +299,9 @@ int dtls1_connect(SSL *s) break; } #endif - /* Check if it is anon DH */ - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) + /* Check if it is anon DH or PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { ret=ssl3_get_server_certificate(s); if (ret <= 0) goto end; @@ -374,7 +378,6 @@ int dtls1_connect(SSL *s) dtls1_start_timer(s); ret=dtls1_send_client_key_exchange(s); if (ret <= 0) goto end; - l=s->s3->tmp.new_cipher->algorithms; /* EAY EAY EAY need to check for DH fix cert * sent back */ /* For TLS, cert_req is set to 2, so a cert chain @@ -471,7 +474,6 @@ int dtls1_connect(SSL *s) s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; } s->init_num=0; - break; #ifndef OPENSSL_NO_TLSEXT @@ -617,6 +619,7 @@ int dtls1_client_hello(SSL *s) /* else use the pre-loaded session */ p=s->s3->client_random; + /* if client_random is initialized, reuse it, we are * required to use same upon reply to HelloVerify */ for (i=0;p[i]=='\0' && is3->client_random);i++) ; @@ -624,7 +627,7 @@ int dtls1_client_hello(SSL *s) { Time=(unsigned long)time(NULL); /* Time */ l2n(Time,p); - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4); + RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4); } /* Do the message type and length last */ @@ -771,7 +774,7 @@ int dtls1_send_client_key_exchange(SSL *s) { unsigned char *p,*d; int n; - unsigned long l; + unsigned long alg_k; #ifndef OPENSSL_NO_RSA unsigned char *q; EVP_PKEY *pkey=NULL; @@ -779,18 +782,26 @@ int dtls1_send_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_KRB5 KSSL_ERR kssl_err; #endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_ECDH + EC_KEY *clnt_ecdh = NULL; + const EC_POINT *srvr_ecpoint = NULL; + EVP_PKEY *srvr_pub_pkey = NULL; + unsigned char *encodedPoint = NULL; + int encoded_pt_len = 0; + BN_CTX * bn_ctx = NULL; +#endif if (s->state == SSL3_ST_CW_KEY_EXCH_A) { d=(unsigned char *)s->init_buf->data; p= &(d[DTLS1_HM_HEADER_LENGTH]); - - l=s->s3->tmp.new_cipher->algorithms; + + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; /* Fool emacs indentation */ if (0) {} #ifndef OPENSSL_NO_RSA - else if (l & SSL_kRSA) + else if (alg_k & SSL_kRSA) { RSA *rsa; unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; @@ -849,7 +860,7 @@ int dtls1_send_client_key_exchange(SSL *s) } #endif #ifndef OPENSSL_NO_KRB5 - else if (l & SSL_kKRB5) + else if (alg_k & SSL_kKRB5) { krb5_error_code krb5rc; KSSL_CTX *kssl_ctx = s->kssl_ctx; @@ -857,7 +868,7 @@ int dtls1_send_client_key_exchange(SSL *s) krb5_data *enc_ticket; krb5_data authenticator, *authp = NULL; EVP_CIPHER_CTX ciph_ctx; - EVP_CIPHER *enc = NULL; + const EVP_CIPHER *enc = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH @@ -868,7 +879,7 @@ int dtls1_send_client_key_exchange(SSL *s) #ifdef KSSL_DEBUG printf("ssl3_send_client_key_exchange(%lx & %lx)\n", - l, SSL_kKRB5); + alg_k, SSL_kKRB5); #endif /* KSSL_DEBUG */ authp = NULL; @@ -958,7 +969,7 @@ int dtls1_send_client_key_exchange(SSL *s) sizeof tmp_buf); EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); outl += padl; - if (outl > sizeof epms) + if (outl > (int)sizeof epms) { SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; @@ -981,7 +992,7 @@ int dtls1_send_client_key_exchange(SSL *s) } #endif #ifndef OPENSSL_NO_DH - else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { DH *dh_srvr,*dh_clnt; @@ -1035,6 +1046,274 @@ int dtls1_send_client_key_exchange(SSL *s) /* perhaps clean things up a bit EAY EAY EAY EAY*/ } +#endif +#ifndef OPENSSL_NO_ECDH + else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) + { + const EC_GROUP *srvr_group = NULL; + EC_KEY *tkey; + int ecdh_clnt_cert = 0; + int field_size = 0; + + /* Did we send out the client's + * ECDH share for use in premaster + * computation as part of client certificate? + * If so, set ecdh_clnt_cert to 1. + */ + if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) + { + /* XXX: For now, we do not support client + * authentication using ECDH certificates. + * To add such support, one needs to add + * code that checks for appropriate + * conditions and sets ecdh_clnt_cert to 1. + * For example, the cert have an ECC + * key on the same curve as the server's + * and the key should be authorized for + * key agreement. + * + * One also needs to add code in ssl3_connect + * to skip sending the certificate verify + * message. + * + * if ((s->cert->key->privatekey != NULL) && + * (s->cert->key->privatekey->type == + * EVP_PKEY_EC) && ...) + * ecdh_clnt_cert = 1; + */ + } + + if (s->session->sess_cert->peer_ecdh_tmp != NULL) + { + tkey = s->session->sess_cert->peer_ecdh_tmp; + } + else + { + /* Get the Server Public Key from Cert */ + srvr_pub_pkey = X509_get_pubkey(s->session-> \ + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); + if ((srvr_pub_pkey == NULL) || + (srvr_pub_pkey->type != EVP_PKEY_EC) || + (srvr_pub_pkey->pkey.ec == NULL)) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + tkey = srvr_pub_pkey->pkey.ec; + } + + srvr_group = EC_KEY_get0_group(tkey); + srvr_ecpoint = EC_KEY_get0_public_key(tkey); + + if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((clnt_ecdh=EC_KEY_new()) == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); + goto err; + } + if (ecdh_clnt_cert) + { + /* Reuse key info from our certificate + * We only need our private key to perform + * the ECDH computation. + */ + const BIGNUM *priv_key; + tkey = s->cert->key->privatekey->pkey.ec; + priv_key = EC_KEY_get0_private_key(tkey); + if (priv_key == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); + goto err; + } + } + else + { + /* Generate a new ECDH key pair */ + if (!(EC_KEY_generate_key(clnt_ecdh))) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + } + + /* use the 'p' output buffer for the ECDH key, but + * make sure to clear it out afterwards + */ + + field_size = EC_GROUP_get_degree(srvr_group); + if (field_size <= 0) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL); + if (n <= 0) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = s->method->ssl3_enc \ + -> generate_master_secret(s, + s->session->master_key, + p, n); + + memset(p, 0, n); /* clean up */ + + if (ecdh_clnt_cert) + { + /* Send empty client key exch message */ + n = 0; + } + else + { + /* First check the size of encoding and + * allocate memory accordingly. + */ + encoded_pt_len = + EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encoded_pt_len * + sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || + (bn_ctx == NULL)) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Encode the public key */ + n = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encoded_pt_len, bn_ctx); + + *p = n; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + /* copy the point */ + memcpy((unsigned char *)p, encodedPoint, n); + /* increment n to account for length field */ + n += 1; + } + + /* Free allocated memory */ + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); + } +#endif /* !OPENSSL_NO_ECDH */ + +#ifndef OPENSSL_NO_PSK + else if (alg_k & SSL_kPSK) + { + char identity[PSK_MAX_IDENTITY_LEN]; + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + + n = 0; + if (s->psk_client_callback == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_CLIENT_CB); + goto err; + } + + psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, + identity, PSK_MAX_IDENTITY_LEN, + psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_len > PSK_MAX_PSK_LEN) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + else if (psk_len == 0) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + goto psk_err; + } + + /* create PSK pre_master_secret */ + pre_ms_len = 2+psk_len+2+psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t+=psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL && + s->session->psk_identity_hint == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(identity); + if (s->session->psk_identity == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, + psk_or_pre_ms, pre_ms_len); + n = strlen(identity); + s2n(n, p); + memcpy(p, identity, n); + n+=2; + psk_err = 0; + psk_err: + OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN); + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) + { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + } #endif else { @@ -1064,6 +1343,13 @@ int dtls1_send_client_key_exchange(SSL *s) /* SSL3_ST_CW_KEY_EXCH_B */ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); err: +#ifndef OPENSSL_NO_ECDH + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); +#endif return(-1); } @@ -1076,7 +1362,7 @@ int dtls1_send_client_verify(SSL *s) unsigned u=0; #endif unsigned long n; -#ifndef OPENSSL_NO_DSA +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) int j; #endif @@ -1086,14 +1372,16 @@ int dtls1_send_client_verify(SSL *s) p= &(d[DTLS1_HM_HEADER_LENGTH]); pkey=s->cert->key->privatekey; - s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2), + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, &(data[MD5_DIGEST_LENGTH])); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst1),&(data[0])); + NID_md5, + &(data[0])); if (RSA_sign(NID_md5_sha1, data, MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, &(p[2]), &u, pkey->pkey.rsa) <= 0 ) @@ -1121,6 +1409,23 @@ int dtls1_send_client_verify(SSL *s) n=j+2; } else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) + { + if (!ECDSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH,&(p[2]), + (unsigned int *)&j,pkey->pkey.ec)) + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, + ERR_R_ECDSA_LIB); + goto err; + } + s2n(j,p); + n=j+2; + } + else #endif { SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR); diff --git a/crypto/openssl/ssl/d1_enc.c b/crypto/openssl/ssl/d1_enc.c index 3dfa5adba3..8fa57347a9 100644 --- a/crypto/openssl/ssl/d1_enc.c +++ b/crypto/openssl/ssl/d1_enc.c @@ -136,8 +136,12 @@ int dtls1_enc(SSL *s, int send) if (send) { - if (s->write_hash != NULL) - n=EVP_MD_size(s->write_hash); + if (EVP_MD_CTX_md(s->write_hash)) + { + n=EVP_MD_CTX_size(s->write_hash); + if (n < 0) + return -1; + } ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) @@ -158,8 +162,12 @@ int dtls1_enc(SSL *s, int send) } else { - if (s->read_hash != NULL) - n=EVP_MD_size(s->read_hash); + if (EVP_MD_CTX_md(s->read_hash)) + { + n=EVP_MD_CTX_size(s->read_hash); + if (n < 0) + return -1; + } ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) @@ -206,11 +214,10 @@ int dtls1_enc(SSL *s, int send) { unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - (void *)ds,rec->data,rec->input,l); - printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", + ds,rec->data,rec->input,l); + printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", ds->buf_len, ds->cipher->key_len, - (unsigned long)DES_KEY_SZ, - (unsigned long)DES_SCHEDULE_SZ, + DES_KEY_SZ, DES_SCHEDULE_SZ, ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; icipher->iv_len; i++) printf("%02X", ds->iv[i]); @@ -235,10 +242,10 @@ int dtls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long ki; + unsigned long i; printf("\trec->data="); - for (ki=0; kidata[ki]); printf("\n"); + for (i=0; idata[i]); printf("\n"); } #endif /* KSSL_DEBUG */ diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c index 63bfbacc82..96b220e87c 100644 --- a/crypto/openssl/ssl/d1_lib.c +++ b/crypto/openssl/ssl/d1_lib.c @@ -91,11 +91,6 @@ long dtls1_default_timeout(void) return(60*60*2); } -IMPLEMENT_dtls1_meth_func(dtlsv1_base_method, - ssl_undefined_function, - ssl_undefined_function, - ssl_bad_method) - int dtls1_new(SSL *s) { DTLS1_STATE *d1; @@ -105,17 +100,6 @@ int dtls1_new(SSL *s) memset(d1,0, sizeof *d1); /* d1->handshake_epoch=0; */ -#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST) - d1->bitmap.length=64; -#else - d1->bitmap.length=sizeof(d1->bitmap.map) * 8; -#endif - pq_64bit_init(&(d1->bitmap.map)); - pq_64bit_init(&(d1->bitmap.max_seq_num)); - - d1->next_bitmap.length = d1->bitmap.length; - pq_64bit_init(&(d1->next_bitmap.map)); - pq_64bit_init(&(d1->next_bitmap.max_seq_num)); d1->unprocessed_rcds.q=pqueue_new(); d1->processed_rcds.q=pqueue_new(); @@ -185,19 +169,13 @@ void dtls1_free(SSL *s) pqueue_free(s->d1->sent_messages); while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) - { + { frag = (hm_fragment *)item->data; OPENSSL_free(frag->fragment); OPENSSL_free(frag); pitem_free(item); - } + } pqueue_free(s->d1->buffered_app_data.q); - - pq_64bit_free(&(s->d1->bitmap.map)); - pq_64bit_free(&(s->d1->bitmap.max_seq_num)); - - pq_64bit_free(&(s->d1->next_bitmap.map)); - pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); OPENSSL_free(s->d1); } @@ -244,13 +222,13 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) * to explicitly list their SSL_* codes. Currently RC4 is the only one * available, but if new ones emerge, they will have to be added... */ -SSL_CIPHER *dtls1_get_cipher(unsigned int u) +const SSL_CIPHER *dtls1_get_cipher(unsigned int u) { - SSL_CIPHER *ciph = ssl3_get_cipher(u); + const SSL_CIPHER *ciph = ssl3_get_cipher(u); if (ciph != NULL) { - if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) + if (ciph->algorithm_enc == SSL_RC4) return NULL; } @@ -305,6 +283,16 @@ struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft) timeleft->tv_usec += 1000000; } + /* If remaining time is less than 15 ms, set it to 0 + * to prevent issues because of small devergences with + * socket timeouts. + */ + if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) + { + memset(timeleft, 0, sizeof(struct timeval)); + } + + return timeleft; } diff --git a/crypto/openssl/ssl/d1_meth.c b/crypto/openssl/ssl/d1_meth.c index 8a6cf31947..5c4004bfe3 100644 --- a/crypto/openssl/ssl/d1_meth.c +++ b/crypto/openssl/ssl/d1_meth.c @@ -61,8 +61,8 @@ #include #include "ssl_locl.h" -static SSL_METHOD *dtls1_get_method(int ver); -static SSL_METHOD *dtls1_get_method(int ver) +static const SSL_METHOD *dtls1_get_method(int ver); +static const SSL_METHOD *dtls1_get_method(int ver) { if (ver == DTLS1_VERSION) return(DTLSv1_method()); diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c index ca2d73f02e..a5439d544f 100644 --- a/crypto/openssl/ssl/d1_pkt.c +++ b/crypto/openssl/ssl/d1_pkt.c @@ -122,10 +122,53 @@ #include #include +/* mod 128 saturating subtract of two 64-bit values in big-endian order */ +static int satsub64be(const unsigned char *v1,const unsigned char *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 have_handshake_fragment(SSL *s, int type, unsigned char *buf, int len, int peek); -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, - PQ_64BIT *seq_num); +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch); @@ -134,11 +177,8 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority, unsigned long *offset); #endif static int dtls1_buffer_record(SSL *s, record_pqueue *q, - PQ_64BIT *priority); + unsigned char *priority); static int dtls1_process_record(SSL *s); -#if PQ_64BIT_IS_INTEGER -static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num); -#endif static void dtls1_clear_timeouts(SSL *s); /* copy buffered record into SSL structure */ @@ -156,15 +196,18 @@ dtls1_copy_record(SSL *s, pitem *item) s->packet_length = rdata->packet_length; memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + + /* Set proper sequence number for mac calculation */ + memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); return(1); } static int -dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority) -{ - DTLS1_RECORD_DATA *rdata; +dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) + { + DTLS1_RECORD_DATA *rdata; pitem *item; /* Limit the size of the queue to prevent DOS attacks */ @@ -172,7 +215,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority) return 0; rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); - item = pitem_new(*priority, rdata); + item = pitem_new(priority, rdata); if (rdata == NULL || item == NULL) { if (rdata != NULL) OPENSSL_free(rdata); @@ -211,7 +254,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority) } return(1); - } + } static int @@ -267,7 +310,7 @@ dtls1_process_buffered_records(SSL *s) if ( ! dtls1_process_record(s)) return(0); dtls1_buffer_record(s, &(s->d1->processed_rcds), - &s->s3->rrec.seq_num); + s->s3->rrec.seq_num); } } @@ -328,17 +371,17 @@ dtls1_get_buffered_record(SSL *s) static int dtls1_process_record(SSL *s) { - int i,al; + int i,al; int clear=0; - int enc_err; + int enc_err; SSL_SESSION *sess; - SSL3_RECORD *rr; + SSL3_RECORD *rr; unsigned int mac_size; unsigned char md[EVP_MAX_MD_SIZE]; rr= &(s->s3->rrec); - sess = s->session; + sess = s->session; /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, * and we have that many bytes in s->packet @@ -374,7 +417,7 @@ dtls1_process_record(SSL *s) goto err; /* otherwise enc_err == -1 */ - goto decryption_failed_or_bad_record_mac; + goto err; } #ifdef TLS_DEBUG @@ -384,14 +427,18 @@ printf("\n"); #endif /* r->length is now the compressed data plus mac */ -if ( (sess == NULL) || + if ( (sess == NULL) || (s->enc_read_ctx == NULL) || (s->read_hash == NULL)) - clear=1; + clear=1; if (!clear) { - mac_size=EVP_MD_size(s->read_hash); + /* !clear => s->read_hash != NULL => mac_size != -1 */ + int t; + t=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(t >= 0); + mac_size=t; if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) { @@ -400,7 +447,7 @@ if ( (sess == NULL) || SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); goto f_err; #else - goto decryption_failed_or_bad_record_mac; + goto err; #endif } /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ @@ -411,14 +458,14 @@ if ( (sess == NULL) || SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; #else - goto decryption_failed_or_bad_record_mac; + goto err; #endif } rr->length-=mac_size; i=s->method->ssl3_enc->mac(s,md,0); - if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) + if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0) { - goto decryption_failed_or_bad_record_mac; + goto err; } } @@ -457,17 +504,9 @@ if ( (sess == NULL) || /* we have pulled in a full packet so zero things */ s->packet_length=0; - dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ - return(1); + dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ + return(1); -decryption_failed_or_bad_record_mac: - /* Separate 'decryption_failed' alert was introduced with TLS 1.0, - * SSL 3.0 only has 'bad_record_mac'. But unless a decryption - * failure is directly visible from the ciphertext anyway, - * we should not reveal which kind of error occured -- this - * might become visible to an attacker (e.g. via logfile) */ - al=SSL_AD_BAD_RECORD_MAC; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: @@ -498,10 +537,9 @@ int dtls1_get_record(SSL *s) rr= &(s->s3->rrec); sess=s->session; - /* The epoch may have changed. If so, process all the - * pending records. This is a non-blocking operation. */ - if ( ! dtls1_process_buffered_records(s)) - return 0; + /* The epoch may have changed. If so, process all the + * pending records. This is a non-blocking operation. */ + dtls1_process_buffered_records(s); /* if we're renegotiating, then there may be buffered records */ if (dtls1_get_processed_record(s)) @@ -545,7 +583,7 @@ again: /* Lets check version */ if (!s->first_packet) { - if (version != s->version && version != DTLS1_BAD_VER) + if (version != s->version) { /* unexpected version, silently discard */ rr->length = 0; @@ -554,8 +592,7 @@ again: } } - if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && - (version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) + if ((version & 0xff00) != (s->version & 0xff00)) { /* wrong version, silently discard record */ rr->length = 0; @@ -571,7 +608,6 @@ again: goto again; } - s->client_version = version; /* now s->rstate == SSL_ST_READ_BODY */ } @@ -600,13 +636,13 @@ again: /* match epochs. NULL means the packet is dropped on the floor */ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); if ( bitmap == NULL) - { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ + { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ } - /* Check whether this is a repeat, or aged record. + /* Check whether this is a repeat, or aged record. * Don't check if we're listening and this message is * a ClientHello. They can look as if they're replayed, * since they arrive from different connections and @@ -614,7 +650,7 @@ again: */ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && *p == SSL3_MT_CLIENT_HELLO) && - ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) + !dtls1_record_replay_check(s, bitmap)) { rr->length = 0; s->packet_length=0; /* dump this record */ @@ -624,21 +660,26 @@ again: /* just read a 0 length packet */ if (rr->length == 0) goto again; - /* If this record is from the next epoch (either HM or ALERT), buffer it - * since it cannot be processed at this time. - * Records from the next epoch are marked as received even though they are - * not processed, so as to prevent any potential resource DoS attack */ - if (is_next_epoch) - { - dtls1_record_bitmap_update(s, bitmap); - dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num); - rr->length = 0; - s->packet_length = 0; - goto again; - } + /* If this record is from the next epoch (either HM or ALERT), + * and a handshake is currently in progress, buffer it since it + * cannot be processed at this time. */ + if (is_next_epoch) + { + if (SSL_in_init(s) || s->in_handshake) + { + dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); + } + rr->length = 0; + s->packet_length = 0; + goto again; + } - if ( ! dtls1_process_record(s)) - return(0); + if (!dtls1_process_record(s)) + { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } dtls1_clear_timeouts(s); /* done waiting */ return(1); @@ -766,7 +807,7 @@ start: * buffer the application data for later processing rather * than dropping the connection. */ - dtls1_buffer_record(s, &(s->d1->buffered_app_data), 0); + dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num); rr->length = 0; goto start; } @@ -1048,13 +1089,14 @@ start: dtls1_get_ccs_header(rr->data, &ccs_hdr); + if (s->version == DTLS1_BAD_VER) + ccs_hdr_len = 3; + /* 'Change Cipher Spec' is just a single byte, so we know * exactly what the record payload has to look like */ /* XDTLS: check that epoch is consistent */ - if (s->client_version == DTLS1_BAD_VER || s->version == DTLS1_BAD_VER) - ccs_hdr_len = 3; - - if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) + if ( (rr->length != ccs_hdr_len) || + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { i=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); @@ -1084,7 +1126,7 @@ start: /* do this whenever CCS is processed */ dtls1_reset_seq_numbers(s, SSL3_CC_READ); - if (s->client_version == DTLS1_BAD_VER) + if (s->version == DTLS1_BAD_VER) s->d1->handshake_read_seq++; goto start; @@ -1327,13 +1369,17 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, if ( (sess == NULL) || (s->enc_write_ctx == NULL) || - (s->write_hash == NULL)) + (EVP_MD_CTX_md(s->write_hash) == NULL)) clear=1; if (clear) mac_size=0; else - mac_size=EVP_MD_size(s->write_hash); + { + mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } /* DTLS implements explicit IV, so no need for empty fragments */ #if 0 @@ -1366,7 +1412,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, s->s3->empty_fragment_done = 1; } #endif - p = wb->buf + prefix_len; /* write the header */ @@ -1374,12 +1419,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, *(p++)=type&0xff; wr->type=type; - if (s->client_version == DTLS1_BAD_VER) - *(p++) = DTLS1_BAD_VER>>8, - *(p++) = DTLS1_BAD_VER&0xff; - else - *(p++)=(s->version>>8), - *(p++)=s->version&0xff; + *(p++)=(s->version>>8); + *(p++)=s->version&0xff; /* field where we are to write out packet epoch, seq num and len */ pseq=p; @@ -1424,7 +1465,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, if (mac_size != 0) { - s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1); + if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0) + goto err; wr->length+=mac_size; } @@ -1501,111 +1543,50 @@ err: -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, - PQ_64BIT *seq_num) +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) { -#if PQ_64BIT_IS_INTEGER - PQ_64BIT mask = 0x0000000000000001L; -#endif - PQ_64BIT rcd_num, tmp; - - pq_64bit_init(&rcd_num); - pq_64bit_init(&tmp); - - /* this is the sequence number for the record just read */ - pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8); - - - if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || - pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) - { - pq_64bit_assign(seq_num, &rcd_num); - pq_64bit_free(&rcd_num); - pq_64bit_free(&tmp); - return 1; /* this record is new */ - } - - pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); - - if ( pq_64bit_get_word(&tmp) > bitmap->length) - { - pq_64bit_free(&rcd_num); - pq_64bit_free(&tmp); - return 0; /* stale, outside the window */ - } + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; -#if PQ_64BIT_IS_BIGNUM - { - int offset; - pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); - pq_64bit_sub_word(&tmp, 1); - offset = pq_64bit_get_word(&tmp); - if ( pq_64bit_is_bit_set(&(bitmap->map), offset)) + cmp = satsub64be(seq,bitmap->max_seq_num); + if (cmp > 0) { - pq_64bit_free(&rcd_num); - pq_64bit_free(&tmp); - return 0; + memcpy (s->s3->rrec.seq_num,seq,8); + return 1; /* this record in new */ } - } -#else - mask <<= (bitmap->max_seq_num - rcd_num - 1); - if (bitmap->map & mask) + shift = -cmp; + if (shift >= sizeof(bitmap->map)*8) + return 0; /* stale, outside the window */ + else if (bitmap->map & (1UL<s3->rrec.seq_num,seq,8); return 1; } static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) { + int cmp; unsigned int shift; - PQ_64BIT rcd_num; - PQ_64BIT tmp; - PQ_64BIT_CTX *ctx; + const unsigned char *seq = s->s3->read_sequence; - pq_64bit_init(&rcd_num); - pq_64bit_init(&tmp); - - pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8); - - /* unfortunate code complexity due to 64-bit manipulation support - * on 32-bit machines */ - if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || - pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) + cmp = satsub64be(seq,bitmap->max_seq_num); + if (cmp > 0) { - pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num)); - pq_64bit_add_word(&tmp, 1); - - shift = (unsigned int)pq_64bit_get_word(&tmp); - - pq_64bit_lshift(&(tmp), &(bitmap->map), shift); - pq_64bit_assign(&(bitmap->map), &tmp); - - pq_64bit_set_bit(&(bitmap->map), 0); - pq_64bit_add_word(&rcd_num, 1); - pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num); - - pq_64bit_assign_word(&tmp, 1); - pq_64bit_lshift(&tmp, &tmp, bitmap->length); - ctx = pq_64bit_ctx_new(&ctx); - pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx); - pq_64bit_ctx_free(ctx); + 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 - { - pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); - pq_64bit_sub_word(&tmp, 1); - shift = (unsigned int)pq_64bit_get_word(&tmp); - - pq_64bit_set_bit(&(bitmap->map), shift); + else { + shift = -cmp; + if (shift < sizeof(bitmap->map)*8) + bitmap->map |= 1UL<s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE #endif - ) + ) (void)BIO_flush(s->wbio); if (s->msg_callback) @@ -1771,17 +1752,8 @@ dtls1_reset_seq_numbers(SSL *s, int rw) { seq = s->s3->read_sequence; s->d1->r_epoch++; - - pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map)); - s->d1->bitmap.length = s->d1->next_bitmap.length; - pq_64bit_assign(&(s->d1->bitmap.max_seq_num), - &(s->d1->next_bitmap.max_seq_num)); - - pq_64bit_free(&(s->d1->next_bitmap.map)); - pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); - pq_64bit_init(&(s->d1->next_bitmap.map)); - pq_64bit_init(&(s->d1->next_bitmap.max_seq_num)); } else { @@ -1793,26 +1765,6 @@ dtls1_reset_seq_numbers(SSL *s, int rw) memset(seq, 0x00, seq_bytes); } -#if PQ_64BIT_IS_INTEGER -static PQ_64BIT -bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num) - { - PQ_64BIT _num; - - _num = (((PQ_64BIT)bytes[0]) << 56) | - (((PQ_64BIT)bytes[1]) << 48) | - (((PQ_64BIT)bytes[2]) << 40) | - (((PQ_64BIT)bytes[3]) << 32) | - (((PQ_64BIT)bytes[4]) << 24) | - (((PQ_64BIT)bytes[5]) << 16) | - (((PQ_64BIT)bytes[6]) << 8) | - (((PQ_64BIT)bytes[7]) ); - - *num = _num ; - return _num; - } -#endif - static void dtls1_clear_timeouts(SSL *s) diff --git a/crypto/openssl/ssl/d1_srvr.c b/crypto/openssl/ssl/d1_srvr.c index 5b313664dd..301ceda7a5 100644 --- a/crypto/openssl/ssl/d1_srvr.c +++ b/crypto/openssl/ssl/d1_srvr.c @@ -4,7 +4,7 @@ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -121,14 +121,15 @@ #include #include #include +#include #ifndef OPENSSL_NO_DH #include #endif -static SSL_METHOD *dtls1_get_server_method(int ver); +static const SSL_METHOD *dtls1_get_server_method(int ver); static int dtls1_send_hello_verify_request(SSL *s); -static SSL_METHOD *dtls1_get_server_method(int ver) +static const SSL_METHOD *dtls1_get_server_method(int ver) { if (ver == DTLS1_VERSION) return(DTLSv1_server_method()); @@ -144,8 +145,9 @@ IMPLEMENT_dtls1_meth_func(DTLSv1_server_method, int dtls1_accept(SSL *s) { BUF_MEM *buf; - unsigned long l,Time=(unsigned long)time(NULL); + unsigned long Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; + unsigned long alg_k; int ret= -1; int new_state,state,skip=0; @@ -290,8 +292,8 @@ int dtls1_accept(SSL *s) s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; - /* HelloVerifyRequests resets Finished MAC */ - if (s->client_version != DTLS1_BAD_VER) + /* HelloVerifyRequest resets Finished MAC */ + if (s->version != DTLS1_BAD_VER) ssl3_init_finished_mac(s); break; @@ -321,8 +323,9 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH */ - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) + /* Check if it is anon DH or normal PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { dtls1_start_timer(s); ret=dtls1_send_server_certificate(s); @@ -350,13 +353,13 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: - l=s->s3->tmp.new_cipher->algorithms; + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; /* clear this, it may get reset by * send_server_key_exchange */ if ((s->options & SSL_OP_EPHEMERAL_RSA) #ifndef OPENSSL_NO_KRB5 - && !(l & SSL_KRB5) + && !(alg_k & SSL_kKRB5) #endif /* OPENSSL_NO_KRB5 */ ) /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key @@ -367,11 +370,17 @@ int dtls1_accept(SSL *s) else s->s3->tmp.use_rsa_tmp=0; - /* only send if a DH key exchange, fortezza or + /* only send if a DH key exchange or * RSA but we have a sign only certificate */ if (s->s3->tmp.use_rsa_tmp - || (l & (SSL_DH|SSL_kFZA)) - || ((l & SSL_kRSA) + /* PSK: send ServerKeyExchange if PSK identity + * hint if provided */ +#ifndef OPENSSL_NO_PSK + || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) +#endif + || (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + || (alg_k & SSL_kEECDH) + || ((alg_k & SSL_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) @@ -402,12 +411,15 @@ int dtls1_accept(SSL *s) /* never request cert in anonymous ciphersuites * (see section "Certificate request" in SSL 3 drafts * and in RFC 2246): */ - ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) && + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && /* ... except when the application insists on verification * (against the specs, but s3_clnt.c accepts this for SSL 3) */ !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* never request cert in Kerberos ciphersuites */ - (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) + /* never request cert in Kerberos ciphersuites */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) + /* With normal PSK Certificates and + * Certificate Requests are omitted */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { /* no cert request */ skip=1; @@ -479,15 +491,30 @@ int dtls1_accept(SSL *s) s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; - /* We need to get hashes here so if there is - * a client cert, it can be verified */ - s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst1), - &(s->s3->tmp.cert_verify_md[0])); - s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst2), - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); + if (ret == 2) + { + /* For the ECDH ciphersuites when + * the client sends its ECDH pub key in + * a certificate, the CertificateVerify + * message is not sent. + */ + s->state=SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + } + else + { + s->state=SSL3_ST_SR_CERT_VRFY_A; + s->init_num=0; + /* We need to get hashes here so if there is + * a client cert, it can be verified */ + s->method->ssl3_enc->cert_verify_mac(s, + NID_md5, + &(s->s3->tmp.cert_verify_md[0])); + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); + } break; case SSL3_ST_SR_CERT_VRFY_A: @@ -686,12 +713,8 @@ int dtls1_send_hello_verify_request(SSL *s) buf = (unsigned char *)s->init_buf->data; msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); - if (s->client_version == DTLS1_BAD_VER) - *(p++) = DTLS1_BAD_VER>>8, - *(p++) = DTLS1_BAD_VER&0xff; - else - *(p++) = s->version >> 8, - *(p++) = s->version & 0xFF; + *(p++) = s->version >> 8; + *(p++) = s->version & 0xFF; if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, s->d1->cookie, @@ -740,12 +763,8 @@ int dtls1_send_server_hello(SSL *s) /* Do the message type and length last */ d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); - if (s->client_version == DTLS1_BAD_VER) - *(p++)=DTLS1_BAD_VER>>8, - *(p++)=DTLS1_BAD_VER&0xff; - else - *(p++)=s->version>>8, - *(p++)=s->version&0xff; + *(p++)=s->version>>8; + *(p++)=s->version&0xff; /* Random stuff */ memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); @@ -850,6 +869,13 @@ int dtls1_send_server_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_DH DH *dh=NULL,*dhp; +#endif +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh=NULL, *ecdhp; + unsigned char *encodedPoint = NULL; + int encodedlen = 0; + int curve_id = 0; + BN_CTX *bn_ctx = NULL; #endif EVP_PKEY *pkey; unsigned char *p,*d; @@ -865,7 +891,7 @@ int dtls1_send_server_key_exchange(SSL *s) EVP_MD_CTX_init(&md_ctx); if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; + type=s->s3->tmp.new_cipher->algorithm_mkey; cert=s->cert; buf=s->init_buf; @@ -959,6 +985,142 @@ int dtls1_send_server_key_exchange(SSL *s) } else #endif +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) + { + const EC_GROUP *group; + + ecdhp=cert->ecdh_tmp; + if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) + { + ecdhp=s->cert->ecdh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); + } + if (ecdhp == NULL) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + + if (s->s3->tmp.ecdh != NULL) + { + EC_KEY_free(s->s3->tmp.ecdh); + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Duplicate the ECDH structure. */ + if (ecdhp == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; + } + if (!EC_KEY_up_ref(ecdhp)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; + } + ecdh = ecdhp; + + s->s3->tmp.ecdh=ecdh; + if ((EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL) || + (s->options & SSL_OP_SINGLE_ECDH_USE)) + { + if(!EC_KEY_generate_key(ecdh)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; + } + } + + if (((group = EC_KEY_get0_group(ecdh)) == NULL) || + (EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; + } + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + (EC_GROUP_get_degree(group) > 163)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + goto err; + } + + /* XXX: For now, we only support ephemeral ECDH + * keys over named (not generic) curves. For + * supported named curves, curve_id is non-zero. + */ + if ((curve_id = + tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) + == 0) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + goto err; + } + + /* Encode the public key. + * First check the size of encoding and + * allocate memory accordingly. + */ + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encodedlen*sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); + goto err; + } + + + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encodedlen, bn_ctx); + + if (encodedlen == 0) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; + } + + BN_CTX_free(bn_ctx); bn_ctx=NULL; + + /* XXX: For now, we only support named (not + * generic) curves in ECDH ephemeral key exchanges. + * In this situation, we need four additional bytes + * to encode the entire ServerECDHParams + * structure. + */ + n = 4 + encodedlen; + + /* We'll generate the serverKeyExchange message + * explicitly so we can set these to NULLs + */ + r[0]=NULL; + r[1]=NULL; + r[2]=NULL; + r[3]=NULL; + } + else +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) + { + /* reserve size for record length and PSK identity hint*/ + n+=2+strlen(s->ctx->psk_identity_hint); + } + else +#endif /* !OPENSSL_NO_PSK */ { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); @@ -970,7 +1132,8 @@ int dtls1_send_server_key_exchange(SSL *s) n+=2+nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) == NULL) @@ -1001,6 +1164,41 @@ int dtls1_send_server_key_exchange(SSL *s) p+=nr[i]; } +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) + { + /* XXX: For now, we only support named (not generic) curves. + * In this situation, the serverKeyExchange message has: + * [1 byte CurveType], [2 byte CurveName] + * [1 byte length of encoded point], followed by + * the actual encoded point itself + */ + *p = NAMED_CURVE_TYPE; + p += 1; + *p = 0; + p += 1; + *p = curve_id; + p += 1; + *p = encodedlen; + p += 1; + memcpy((unsigned char*)p, + (unsigned char *)encodedPoint, + encodedlen); + OPENSSL_free(encodedPoint); + p += encodedlen; + } +#endif + +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) + { + /* copy PSK identity hint */ + s2n(strlen(s->ctx->psk_identity_hint), p); + strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); + p+=strlen(s->ctx->psk_identity_hint); + } +#endif + /* not anonymous */ if (pkey != NULL) { @@ -1053,6 +1251,25 @@ int dtls1_send_server_key_exchange(SSL *s) n+=i+2; } else +#endif +#if !defined(OPENSSL_NO_ECDSA) + if (pkey->type == EVP_PKEY_EC) + { + /* let's do ECDSA */ + EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL); + EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx,&(d[4]),n); + if (!EVP_SignFinal(&md_ctx,&(p[2]), + (unsigned int *)&i,pkey)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA); + goto err; + } + s2n(i,p); + n+=i+2; + } + else #endif { /* Is this error check actually needed? */ @@ -1080,6 +1297,10 @@ int dtls1_send_server_key_exchange(SSL *s) f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: +#ifndef OPENSSL_NO_ECDH + if (encodedPoint != NULL) OPENSSL_free(encodedPoint); + BN_CTX_free(bn_ctx); +#endif EVP_MD_CTX_cleanup(&md_ctx); return(-1); } @@ -1193,14 +1414,15 @@ int dtls1_send_server_certificate(SSL *s) if (s->state == SSL3_ST_SW_CERT_A) { x=ssl_get_server_send_cert(s); - if (x == NULL && - /* VRS: allow null cert if auth == KRB5 */ - (s->s3->tmp.new_cipher->algorithms - & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - != (SSL_aKRB5|SSL_kKRB5)) + if (x == NULL) { - SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); - return(0); + /* VRS: allow null cert if auth == KRB5 */ + if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) || + (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5)) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); + return(0); + } } l=dtls1_output_cert_chain(s,x); diff --git a/crypto/openssl/ssl/dtls1.h b/crypto/openssl/ssl/dtls1.h index a8ce51ac3e..2900d1d8ae 100644 --- a/crypto/openssl/ssl/dtls1.h +++ b/crypto/openssl/ssl/dtls1.h @@ -108,15 +108,17 @@ extern "C" { typedef struct dtls1_bitmap_st { - PQ_64BIT map; - unsigned long length; /* sizeof the bitmap in bits */ - PQ_64BIT max_seq_num; /* max record number seen so far */ + unsigned long map; /* track 32 packets on 32-bit systems + and 64 - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, + 64-bit value in big-endian + encoding */ } DTLS1_BITMAP; struct dtls1_retransmit_state { EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - const EVP_MD *write_hash; /* used for mac generation */ + EVP_MD_CTX *write_hash; /* used for mac generation */ #ifndef OPENSSL_NO_COMP COMP_CTX *compress; /* compression */ #else @@ -165,6 +167,7 @@ typedef struct hm_fragment_st { struct hm_header_st msg_header; unsigned char *fragment; + unsigned char *reassembly; } hm_fragment; typedef struct dtls1_state_st diff --git a/crypto/openssl/ssl/kssl.c b/crypto/openssl/ssl/kssl.c index 73401c92a3..b820e37464 100644 --- a/crypto/openssl/ssl/kssl.c +++ b/crypto/openssl/ssl/kssl.c @@ -76,6 +76,7 @@ #include #include #include +#include "kssl_lcl.h" #ifndef OPENSSL_NO_KRB5 @@ -131,7 +132,7 @@ #define krb5_principal_compare kssl_krb5_principal_compare #define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part #define krb5_timeofday kssl_krb5_timeofday -#define krb5_rc_default kssl_krb5_rc_default +#define krb5_rc_default kssl_krb5_rc_default #ifdef krb5_rc_initialize #undef krb5_rc_initialize @@ -839,7 +840,7 @@ kssl_map_enc(krb5_enctype enctype) ** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and ** xx and yy are possibly multi-byte length fields. */ -int kssl_test_confound(unsigned char *p) +static int kssl_test_confound(unsigned char *p) { int len = 2; int xx = 0, yy = 0; @@ -874,7 +875,7 @@ int kssl_test_confound(unsigned char *p) ** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 ** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. */ -size_t *populate_cksumlens(void) +static size_t *populate_cksumlens(void) { int i, j, n; static size_t *cklens = NULL; @@ -1025,7 +1026,7 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk) /* Display contents of krb5_principal_data struct, for debugging ** (krb5_principal is typedef'd == krb5_principal_data *) */ -void +static void print_krb5_princ(char *label, krb5_principal_data *princ) { int i, ui, uj; @@ -1224,7 +1225,7 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, ** code here. This tkt should alloc/free just ** like the real thing. */ -krb5_error_code +static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, /* IN */ KRB5_TKTBODY *asn1ticket, /* OUT */ krb5_ticket **krb5ticket, @@ -1802,6 +1803,9 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx) kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC, KRB5_NT_SRV_HST, &princ); + if (krb5rc) + goto exit; + krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, 0 /* IGNORE_VNO */, @@ -1899,7 +1903,7 @@ void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) ** Return pointer to the (partially) filled in struct tm on success, ** return NULL on failure. */ -struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) +static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) { char c, *p; @@ -1925,7 +1929,7 @@ struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) ** So we try to sneek the clockskew out through the replay cache. ** If that fails just return a likely default (300 seconds). */ -krb5_deltat get_rc_clockskew(krb5_context context) +static krb5_deltat get_rc_clockskew(krb5_context context) { krb5_rcache rc; krb5_deltat clockskew; @@ -2089,9 +2093,12 @@ krb5_error_code kssl_check_authent( EVP_CIPHER_CTX_cleanup(&ciph_ctx); #ifdef KSSL_DEBUG + { + int padl; printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); printf("\n"); + } #endif /* KSSL_DEBUG */ if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) @@ -2121,7 +2128,7 @@ krb5_error_code kssl_check_authent( tm_g = gmtime(&now); tg = mktime(tm_g); tz_offset = tg - tl; - *atimep = tr - tz_offset; + *atimep = (krb5_timestamp)(tr - tz_offset); } #ifdef KSSL_DEBUG diff --git a/crypto/openssl/ssl/kssl_lcl.h b/crypto/openssl/ssl/kssl_lcl.h index 4cd8dd2d7f..c039c91b4e 100644 --- a/crypto/openssl/ssl/kssl_lcl.h +++ b/crypto/openssl/ssl/kssl_lcl.h @@ -75,7 +75,7 @@ void print_krb5_keyblock(char *label, krb5_keyblock *keyblk); char *kstring(char *string); char *knumber(int len, krb5_octet *contents); -EVP_CIPHER *kssl_map_enc(krb5_enctype enctype); +const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype); int kssl_keytab_is_available(KSSL_CTX *kssl_ctx); int kssl_tgt_is_available(KSSL_CTX *kssl_ctx); diff --git a/crypto/openssl/ssl/s23_clnt.c b/crypto/openssl/ssl/s23_clnt.c index de0238935a..c4d8bf2eb3 100644 --- a/crypto/openssl/ssl/s23_clnt.c +++ b/crypto/openssl/ssl/s23_clnt.c @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 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 #include "ssl_locl.h" @@ -63,10 +116,10 @@ #include #include -static SSL_METHOD *ssl23_get_client_method(int ver); +static const SSL_METHOD *ssl23_get_client_method(int ver); static int ssl23_client_hello(SSL *s); static int ssl23_get_server_hello(SSL *s); -static SSL_METHOD *ssl23_get_client_method(int ver) +static const SSL_METHOD *ssl23_get_client_method(int ver) { #ifndef OPENSSL_NO_SSL2 if (ver == SSL2_VERSION) @@ -197,6 +250,20 @@ end: return(ret); } +static int ssl23_no_ssl2_ciphers(SSL *s) + { + SSL_CIPHER *cipher; + STACK_OF(SSL_CIPHER) *ciphers; + int i; + ciphers = SSL_get_ciphers(s); + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) + { + cipher = sk_SSL_CIPHER_value(ciphers, i); + if (cipher->algorithm_ssl == SSL_SSLV2) + return 0; + } + return 1; + } static int ssl23_client_hello(SSL *s) { @@ -214,6 +281,9 @@ static int ssl23_client_hello(SSL *s) ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1; + if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) + ssl2_compat = 0; + if (!(s->options & SSL_OP_NO_TLSv1)) { version = TLS1_VERSION; @@ -226,7 +296,7 @@ static int ssl23_client_hello(SSL *s) { version = SSL2_VERSION; } -#ifndef OPENSSL_NO_TLSEXT +#ifndef OPENSSL_NO_TLSEXT if (version != SSL2_VERSION) { /* have to disable SSL 2.0 compatibility if we need TLS extensions */ @@ -235,6 +305,10 @@ static int ssl23_client_hello(SSL *s) ssl2_compat = 0; if (s->tlsext_status_type != -1) ssl2_compat = 0; +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL) + ssl2_compat = 0; +#endif } #endif @@ -260,14 +334,6 @@ static int ssl23_client_hello(SSL *s) version_major = TLS1_VERSION_MAJOR; version_minor = TLS1_VERSION_MINOR; } -#ifdef OPENSSL_FIPS - else if(FIPS_mode()) - { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return -1; - } -#endif else if (version == SSL3_VERSION) { version_major = SSL3_VERSION_MAJOR; @@ -321,6 +387,10 @@ static int ssl23_client_hello(SSL *s) ch_len=SSL2_MAX_CHALLENGE_LENGTH; /* write out sslv2 challenge */ + /* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), + because it is one of SSL2_MAX_CHALLENGE_LENGTH (32) + or SSL2_MAX_CHALLENGE_LENGTH (16), but leave the + check in for futurproofing */ if (SSL3_RANDOM_SIZE < ch_len) i=SSL3_RANDOM_SIZE; else @@ -371,7 +441,11 @@ static int ssl23_client_hello(SSL *s) p+=i; /* COMPRESSION */ - if (s->ctx->comp_methods == NULL) +#ifdef OPENSSL_NO_COMP + *(p++)=1; +#else + if ((s->options & SSL_OP_NO_COMPRESSION) + || !s->ctx->comp_methods) j=0; else j=sk_SSL_COMP_num(s->ctx->comp_methods); @@ -381,8 +455,16 @@ static int ssl23_client_hello(SSL *s) comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); *(p++)=comp->id; } +#endif *(p++)=0; /* Add the NULL method */ + #ifndef OPENSSL_NO_TLSEXT + /* TLS extensions*/ + if (ssl_prepare_clienthello_tlsext(s) <= 0) + { + SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); + return -1; + } if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); @@ -391,7 +473,6 @@ static int ssl23_client_hello(SSL *s) #endif l = p-d; - *p = 42; /* fill in 4-byte handshake header */ d=&(buf[5]); @@ -486,6 +567,10 @@ static int ssl23_get_server_hello(SSL *s) ch_len=SSL2_MAX_CHALLENGE_LENGTH; /* write out sslv2 challenge */ + /* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because + it is one of SSL2_MAX_CHALLENGE_LENGTH (32) or + SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for + futurproofing */ i=(SSL3_RANDOM_SIZE < ch_len) ?SSL3_RANDOM_SIZE:ch_len; s->s2->challenge_length=i; @@ -506,7 +591,7 @@ static int ssl23_get_server_hello(SSL *s) /* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */ s->s2->ssl2_rollback=1; - /* setup the 5 bytes we have read so we get them from + /* setup the 7 bytes we have read so we get them from * the sslv2 buffer */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; @@ -522,39 +607,16 @@ static int ssl23_get_server_hello(SSL *s) s->handshake_func=s->method->ssl_connect; #endif } - else if ((p[0] == SSL3_RT_HANDSHAKE) && - (p[1] == SSL3_VERSION_MAJOR) && - ((p[2] == SSL3_VERSION_MINOR) || - (p[2] == TLS1_VERSION_MINOR)) && - (p[5] == SSL3_MT_SERVER_HELLO)) + else if (p[1] == SSL3_VERSION_MAJOR && + (p[2] == SSL3_VERSION_MINOR || p[2] == TLS1_VERSION_MINOR) && + ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || + (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { - /* we have sslv3 or tls1 */ - - if (!ssl_init_wbio_buffer(s,1)) goto err; - - /* we are in this state */ - s->state=SSL3_ST_CR_SRVR_HELLO_A; - - /* put the 5 bytes we have read into the input buffer - * for SSLv3 */ - s->rstate=SSL_ST_READ_HEADER; - s->packet_length=n; - s->packet= &(s->s3->rbuf.buf[0]); - memcpy(s->packet,buf,n); - s->s3->rbuf.left=n; - s->s3->rbuf.offset=0; + /* we have sslv3 or tls1 (server hello or alert) */ if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { -#ifdef OPENSSL_FIPS - if(FIPS_mode()) - { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; - } -#endif s->version=SSL3_VERSION; s->method=SSLv3_client_method(); } @@ -569,35 +631,52 @@ static int ssl23_get_server_hello(SSL *s) SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); goto err; } - - s->handshake_func=s->method->ssl_connect; - } - else if ((p[0] == SSL3_RT_ALERT) && - (p[1] == SSL3_VERSION_MAJOR) && - ((p[2] == SSL3_VERSION_MINOR) || - (p[2] == TLS1_VERSION_MINOR)) && - (p[3] == 0) && - (p[4] == 2)) - { - void (*cb)(const SSL *ssl,int type,int val)=NULL; - int j; - - /* An alert */ - if (s->info_callback != NULL) - cb=s->info_callback; - else if (s->ctx->info_callback != NULL) - cb=s->ctx->info_callback; - - i=p[5]; - if (cb != NULL) + + if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { - j=(i<<8)|p[6]; - cb(s,SSL_CB_READ_ALERT,j); + /* fatal alert */ + + void (*cb)(const SSL *ssl,int type,int val)=NULL; + int j; + + if (s->info_callback != NULL) + cb=s->info_callback; + else if (s->ctx->info_callback != NULL) + cb=s->ctx->info_callback; + + i=p[5]; + if (cb != NULL) + { + j=(i<<8)|p[6]; + cb(s,SSL_CB_READ_ALERT,j); + } + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg); + + s->rwstate=SSL_NOTHING; + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); + goto err; } - s->rwstate=SSL_NOTHING; - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); - goto err; + if (!ssl_init_wbio_buffer(s,1)) goto err; + + /* we are in this state */ + s->state=SSL3_ST_CR_SRVR_HELLO_A; + + /* put the 7 bytes we have read into the input buffer + * for SSLv3 */ + s->rstate=SSL_ST_READ_HEADER; + s->packet_length=n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + s->packet= &(s->s3->rbuf.buf[0]); + memcpy(s->packet,buf,n); + s->s3->rbuf.left=n; + s->s3->rbuf.offset=0; + + s->handshake_func=s->method->ssl_connect; } else { @@ -615,4 +694,3 @@ static int ssl23_get_server_hello(SSL *s) err: return(-1); } - diff --git a/crypto/openssl/ssl/s23_lib.c b/crypto/openssl/ssl/s23_lib.c index fc2981308d..e3fce53430 100644 --- a/crypto/openssl/ssl/s23_lib.c +++ b/crypto/openssl/ssl/s23_lib.c @@ -65,11 +65,6 @@ long ssl23_default_timeout(void) return(300); } -IMPLEMENT_ssl23_meth_func(sslv23_base_method, - ssl_undefined_function, - ssl_undefined_function, - ssl_bad_method) - int ssl23_num_ciphers(void) { return(ssl3_num_ciphers() @@ -79,7 +74,7 @@ int ssl23_num_ciphers(void) ); } -SSL_CIPHER *ssl23_get_cipher(unsigned int u) +const SSL_CIPHER *ssl23_get_cipher(unsigned int u) { unsigned int uu=ssl3_num_ciphers(); @@ -95,9 +90,10 @@ SSL_CIPHER *ssl23_get_cipher(unsigned int u) /* This function needs to check if the ciphers required are actually * available */ -SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p) +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p) { - SSL_CIPHER c,*cp; + SSL_CIPHER c; + const SSL_CIPHER *cp; unsigned long id; int n; diff --git a/crypto/openssl/ssl/s23_meth.c b/crypto/openssl/ssl/s23_meth.c index 950d9aab3d..c6099efcf7 100644 --- a/crypto/openssl/ssl/s23_meth.c +++ b/crypto/openssl/ssl/s23_meth.c @@ -60,8 +60,8 @@ #include #include "ssl_locl.h" -static SSL_METHOD *ssl23_get_method(int ver); -static SSL_METHOD *ssl23_get_method(int ver) +static const SSL_METHOD *ssl23_get_method(int ver); +static const SSL_METHOD *ssl23_get_method(int ver) { #ifndef OPENSSL_NO_SSL2 if (ver == SSL2_VERSION) diff --git a/crypto/openssl/ssl/s23_srvr.c b/crypto/openssl/ssl/s23_srvr.c index be05911e96..836dd1f1cf 100644 --- a/crypto/openssl/ssl/s23_srvr.c +++ b/crypto/openssl/ssl/s23_srvr.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -116,9 +116,9 @@ #include #include -static SSL_METHOD *ssl23_get_server_method(int ver); +static const SSL_METHOD *ssl23_get_server_method(int ver); int ssl23_get_client_hello(SSL *s); -static SSL_METHOD *ssl23_get_server_method(int ver) +static const SSL_METHOD *ssl23_get_server_method(int ver) { #ifndef OPENSSL_NO_SSL2 if (ver == SSL2_VERSION) @@ -393,15 +393,6 @@ int ssl23_get_client_hello(SSL *s) } } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && (s->version < TLS1_VERSION)) - { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; - } -#endif - if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header @@ -432,7 +423,9 @@ int ssl23_get_client_hello(SSL *s) n2s(p,sil); n2s(p,cl); d=(unsigned char *)s->init_buf->data; - if ((csl+sil+cl+11) != s->packet_length) + if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format + * Client Hello, can we? Error condition should be + * '>' otherweise */ { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); goto err; @@ -475,6 +468,15 @@ int ssl23_get_client_hello(SSL *s) *(d++)=1; *(d++)=0; +#if 0 + /* copy any remaining data with may be extensions */ + p = p+csl+sil+cl; + while (p < s->packet+s->packet_length) + { + *(d++)=*(p++); + } +#endif + i = (d-(unsigned char *)s->init_buf->data) - 4; l2n3((long)i, d_len); @@ -550,6 +552,10 @@ int ssl23_get_client_hello(SSL *s) * for SSLv3 */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + s->packet= &(s->s3->rbuf.buf[0]); memcpy(s->packet,buf,n); s->s3->rbuf.left=n; diff --git a/crypto/openssl/ssl/s2_clnt.c b/crypto/openssl/ssl/s2_clnt.c index 782129cd5d..00ac158f9b 100644 --- a/crypto/openssl/ssl/s2_clnt.c +++ b/crypto/openssl/ssl/s2_clnt.c @@ -117,7 +117,7 @@ #include #include -static SSL_METHOD *ssl2_get_client_method(int ver); +static const SSL_METHOD *ssl2_get_client_method(int ver); static int get_server_finished(SSL *s); static int get_server_verify(SSL *s); static int get_server_hello(SSL *s); @@ -129,7 +129,7 @@ static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, unsigned char *to,int padding); #define BREAK break -static SSL_METHOD *ssl2_get_client_method(int ver) +static const SSL_METHOD *ssl2_get_client_method(int ver) { if (ver == SSL2_VERSION) return(SSLv2_client_method()); @@ -621,7 +621,7 @@ static int client_master_key(SSL *s) if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { - if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) + if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); @@ -863,8 +863,10 @@ static int client_certificate(SSL *s) EVP_SignUpdate(&ctx,s->s2->key_material, s->s2->key_material_length); EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len); - n=i2d_X509(s->session->sess_cert->peer_key->x509,&p); - EVP_SignUpdate(&ctx,buf,(unsigned int)n); + i=i2d_X509(s->session->sess_cert->peer_key->x509,&p); + /* Don't update the signature if it fails - FIXME: probably should handle this better */ + if(i > 0) + EVP_SignUpdate(&ctx,buf,(unsigned int)i); p=buf; d=p+6; diff --git a/crypto/openssl/ssl/s2_enc.c b/crypto/openssl/ssl/s2_enc.c index 1f62acd5b1..ff3395f459 100644 --- a/crypto/openssl/ssl/s2_enc.c +++ b/crypto/openssl/ssl/s2_enc.c @@ -68,15 +68,14 @@ int ssl2_enc_init(SSL *s, int client) const EVP_MD *md; int num; - if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) + if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_SSL2_ENC_INIT,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); return(0); } - - s->read_hash=md; - s->write_hash=md; + ssl_replace_hash(&s->read_hash,md); + ssl_replace_hash(&s->write_hash,md); if ((s->enc_read_ctx == NULL) && ((s->enc_read_ctx=(EVP_CIPHER_CTX *) @@ -176,7 +175,7 @@ void ssl2_mac(SSL *s, unsigned char *md, int send) /* There has to be a MAC algorithm. */ EVP_MD_CTX_init(&c); - EVP_DigestInit_ex(&c, s->read_hash, NULL); + EVP_MD_CTX_copy(&c, s->read_hash); EVP_DigestUpdate(&c,sec, EVP_CIPHER_CTX_key_length(s->enc_read_ctx)); EVP_DigestUpdate(&c,act,len); diff --git a/crypto/openssl/ssl/s2_lib.c b/crypto/openssl/ssl/s2_lib.c index 10751b22ba..9914604109 100644 --- a/crypto/openssl/ssl/s2_lib.c +++ b/crypto/openssl/ssl/s2_lib.c @@ -55,6 +55,59 @@ * 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 "ssl_locl.h" #ifndef OPENSSL_NO_SSL2 @@ -68,143 +121,172 @@ const char ssl2_version_str[]="SSLv2" OPENSSL_VERSION_PTEXT; #define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) /* list of available SSLv2 ciphers (sorted by id) */ -OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[]={ -/* NULL_WITH_MD5 v3 */ +OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[]={ #if 0 +/* NULL_WITH_MD5 v3 */ { 1, SSL2_TXT_NULL_WITH_MD5, SSL2_CK_NULL_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_MD5, + SSL_SSLV2, SSL_EXPORT|SSL_EXP40|SSL_STRONG_NONE, 0, 0, 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif + /* RC4_128_WITH_MD5 */ { 1, SSL2_TXT_RC4_128_WITH_MD5, SSL2_CK_RC4_128_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* RC4_128_EXPORT40_WITH_MD5 */ { 1, SSL2_TXT_RC4_128_EXPORT40_WITH_MD5, SSL2_CK_RC4_128_EXPORT40_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, SSL_EXPORT|SSL_EXP40, SSL2_CF_5_BYTE_ENC, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* RC2_128_CBC_WITH_MD5 */ { 1, SSL2_TXT_RC2_128_CBC_WITH_MD5, SSL2_CK_RC2_128_CBC_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV2, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* RC2_128_CBC_EXPORT40_WITH_MD5 */ { 1, SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5, SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV2, SSL_EXPORT|SSL_EXP40, SSL2_CF_5_BYTE_ENC, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, -/* IDEA_128_CBC_WITH_MD5 */ + #ifndef OPENSSL_NO_IDEA +/* IDEA_128_CBC_WITH_MD5 */ { 1, SSL2_TXT_IDEA_128_CBC_WITH_MD5, SSL2_CK_IDEA_128_CBC_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_IDEA|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_IDEA, + SSL_MD5, + SSL_SSLV2, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif + /* DES_64_CBC_WITH_MD5 */ { 1, SSL2_TXT_DES_64_CBC_WITH_MD5, SSL2_CK_DES_64_CBC_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_DES|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_MD5, + SSL_SSLV2, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* DES_192_EDE3_CBC_WITH_MD5 */ { 1, SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5, SSL2_CK_DES_192_EDE3_CBC_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_MD5, + SSL_SSLV2, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, -/* RC4_64_WITH_MD5 */ + #if 0 +/* RC4_64_WITH_MD5 */ { 1, SSL2_TXT_RC4_64_WITH_MD5, SSL2_CK_RC4_64_WITH_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_SSLV2, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, SSL_NOT_EXP|SSL_LOW, SSL2_CF_8_BYTE_ENC, 64, 64, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif -/* NULL SSLeay (testing) */ + #if 0 +/* NULL SSLeay (testing) */ { 0, SSL2_TXT_NULL, SSL2_CK_NULL, 0, + 0, + 0, + 0, + SSL_SSLV2, SSL_STRONG_NONE, 0, 0, 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif @@ -216,17 +298,12 @@ long ssl2_default_timeout(void) return(300); } -IMPLEMENT_ssl2_meth_func(sslv2_base_method, - ssl_undefined_function, - ssl_undefined_function, - ssl_bad_method) - int ssl2_num_ciphers(void) { return(SSL2_NUM_CIPHERS); } -SSL_CIPHER *ssl2_get_cipher(unsigned int u) +const SSL_CIPHER *ssl2_get_cipher(unsigned int u) { if (u < SSL2_NUM_CIPHERS) return(&(ssl2_ciphers[SSL2_NUM_CIPHERS-1-u])); @@ -337,18 +414,16 @@ long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) /* This function needs to check if the ciphers required are actually * available */ -SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p) +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p) { - SSL_CIPHER c,*cp; + SSL_CIPHER c; + const SSL_CIPHER *cp; unsigned long id; id=0x02000000L|((unsigned long)p[0]<<16L)| ((unsigned long)p[1]<<8L)|(unsigned long)p[2]; c.id=id; - cp = (SSL_CIPHER *)OBJ_bsearch((char *)&c, - (char *)ssl2_ciphers, - SSL2_NUM_CIPHERS,sizeof(SSL_CIPHER), - FP_ICC ssl_cipher_id_cmp); + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS); if ((cp == NULL) || (cp->valid == 0)) return NULL; else @@ -377,6 +452,7 @@ int ssl2_generate_key_material(SSL *s) unsigned char *km; unsigned char c='0'; const EVP_MD *md5; + int md_size; md5 = EVP_md5(); @@ -393,10 +469,12 @@ int ssl2_generate_key_material(SSL *s) SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); return 0; } - - for (i=0; is2->key_material_length; i += EVP_MD_size(md5)) + md_size = EVP_MD_size(md5); + if (md_size < 0) + return 0; + for (i=0; is2->key_material_length; i += md_size) { - if (((km - s->s2->key_material) + EVP_MD_size(md5)) > + if (((km - s->s2->key_material) + md_size) > (int)sizeof(s->s2->key_material)) { /* EVP_DigestFinal_ex() below would write beyond buffer */ @@ -415,7 +493,7 @@ int ssl2_generate_key_material(SSL *s) EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length); EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length); EVP_DigestFinal_ex(&ctx,km,NULL); - km += EVP_MD_size(md5); + km += md_size; } EVP_MD_CTX_cleanup(&ctx); diff --git a/crypto/openssl/ssl/s2_meth.c b/crypto/openssl/ssl/s2_meth.c index a35e435b71..f0e8ca593d 100644 --- a/crypto/openssl/ssl/s2_meth.c +++ b/crypto/openssl/ssl/s2_meth.c @@ -61,8 +61,8 @@ #include #include -static SSL_METHOD *ssl2_get_method(int ver); -static SSL_METHOD *ssl2_get_method(int ver) +static const SSL_METHOD *ssl2_get_method(int ver); +static const SSL_METHOD *ssl2_get_method(int ver) { if (ver == SSL2_VERSION) return(SSLv2_method()); @@ -71,9 +71,9 @@ static SSL_METHOD *ssl2_get_method(int ver) } IMPLEMENT_ssl2_meth_func(SSLv2_method, - ssl2_accept, - ssl2_connect, - ssl2_get_method) + ssl2_accept, + ssl2_connect, + ssl2_get_method) #else /* !OPENSSL_NO_SSL2 */ diff --git a/crypto/openssl/ssl/s2_pkt.c b/crypto/openssl/ssl/s2_pkt.c index a10929a757..ac963b2d47 100644 --- a/crypto/openssl/ssl/s2_pkt.c +++ b/crypto/openssl/ssl/s2_pkt.c @@ -116,7 +116,7 @@ #define USE_SOCKETS static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend); -static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); static int ssl_mt_error(int n); @@ -130,7 +130,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) unsigned char mac[MAX_MAC_SIZE]; unsigned char *p; int i; - unsigned int mac_size; + int mac_size; ssl2_read_again: if (SSL_in_init(s) && !s->in_handshake) @@ -246,7 +246,9 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) } else { - mac_size=EVP_MD_size(s->read_hash); + mac_size=EVP_MD_CTX_size(s->read_hash); + if (mac_size < 0) + return -1; OPENSSL_assert(mac_size <= MAX_MAC_SIZE); s->s2->mac_data=p; s->s2->ract_data= &p[mac_size]; @@ -261,7 +263,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) /* added a check for length > max_size in case * encryption was not turned on yet due to an error */ if ((!s->s2->clear_text) && - (s->s2->rlength >= mac_size)) + (s->s2->rlength >= (unsigned int)mac_size)) { ssl2_enc(s,0); s->s2->ract_data_length-=mac_size; @@ -447,7 +449,7 @@ int ssl2_write(SSL *s, const void *_buf, int len) n=(len-tot); for (;;) { - i=do_ssl_write(s,&(buf[tot]),n); + i=n_do_ssl_write(s,&(buf[tot]),n); if (i <= 0) { s->s2->wnum=tot; @@ -511,9 +513,10 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) } } -static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) { - unsigned int j,k,olen,p,mac_size,bs; + unsigned int j,k,olen,p,bs; + int mac_size; register unsigned char *pp; olen=len; @@ -529,7 +532,11 @@ static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) if (s->s2->clear_text) mac_size=0; else - mac_size=EVP_MD_size(s->write_hash); + { + mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } /* lets set the pad p */ if (s->s2->clear_text) diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c index 01d62fad11..1434e734dd 100644 --- a/crypto/openssl/ssl/s2_srvr.c +++ b/crypto/openssl/ssl/s2_srvr.c @@ -117,7 +117,7 @@ #include #include -static SSL_METHOD *ssl2_get_server_method(int ver); +static const SSL_METHOD *ssl2_get_server_method(int ver); static int get_client_master_key(SSL *s); static int get_client_hello(SSL *s); static int server_hello(SSL *s); @@ -129,7 +129,7 @@ static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, unsigned char *to,int padding); #define BREAK break -static SSL_METHOD *ssl2_get_server_method(int ver) +static const SSL_METHOD *ssl2_get_server_method(int ver) { if (ver == SSL2_VERSION) return(SSLv2_server_method()); @@ -366,7 +366,7 @@ static int get_client_master_key(SSL *s) int is_export,i,n,keya,ek; unsigned long len; unsigned char *p; - SSL_CIPHER *cp; + const SSL_CIPHER *cp; const EVP_CIPHER *c; const EVP_MD *md; @@ -451,7 +451,7 @@ static int get_client_master_key(SSL *s) is_export=SSL_C_IS_EXPORT(s->session->cipher); - if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) + if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); diff --git a/crypto/openssl/ssl/s3_both.c b/crypto/openssl/ssl/s3_both.c index 7f462250c7..a6d869df59 100644 --- a/crypto/openssl/ssl/s3_both.c +++ b/crypto/openssl/ssl/s3_both.c @@ -160,8 +160,6 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) p= &(d[4]); i=s->method->ssl3_enc->final_finish_mac(s, - &(s->s3->finish_dgst1), - &(s->s3->finish_dgst2), sender,slen,s->s3->tmp.finish_md); s->s3->tmp.finish_md_len = i; memcpy(p, s->s3->tmp.finish_md, i); @@ -300,21 +298,21 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b) static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) { - int n; - unsigned char *p; + int n; + unsigned char *p; - n=i2d_X509(x,NULL); - if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) - { - SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); - return(-1); - } - p=(unsigned char *)&(buf->data[*l]); - l2n3(n,p); - i2d_X509(x,&p); - *l+=n+3; + n=i2d_X509(x,NULL); + if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) + { + SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); + return(-1); + } + p=(unsigned char *)&(buf->data[*l]); + l2n3(n,p); + i2d_X509(x,&p); + *l+=n+3; - return(0); + return(0); } unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) @@ -354,6 +352,8 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) return(0); } X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); for (i=0; i < sk_X509_num(xs_ctx.chain); i++) { x = sk_X509_value(xs_ctx.chain, i); @@ -550,9 +550,16 @@ int ssl_cert_type(X509 *x, EVP_PKEY *pkey) else if (i == EVP_PKEY_EC) { ret = SSL_PKEY_ECC; - } + } #endif - + else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) + { + ret = SSL_PKEY_GOST94; + } + else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) + { + ret = SSL_PKEY_GOST01; + } err: if(!pkey) EVP_PKEY_free(pk); return(ret); @@ -618,42 +625,189 @@ int ssl_verify_alarm_type(long type) return(al); } -int ssl3_setup_buffers(SSL *s) +#ifndef OPENSSL_NO_BUF_FREELISTS +/* On some platforms, malloc() performance is bad enough that you can't just + * free() and malloc() buffers all the time, so we need to use freelists from + * unused buffers. Currently, each freelist holds memory chunks of only a + * given size (list->chunklen); other sized chunks are freed and malloced. + * This doesn't help much if you're using many different SSL option settings + * with a given context. (The options affecting buffer size are + * max_send_fragment, read buffer vs write buffer, + * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.) Using a separate freelist for every + * possible size is not an option, since max_send_fragment can take on many + * different values. + * + * If you are on a platform with a slow malloc(), and you're using SSL + * connections with many different settings for these options, and you need to + * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options: + * - Link against a faster malloc implementation. + * - Use a separate SSL_CTX for each option set. + * - Improve this code. + */ +static void * +freelist_extract(SSL_CTX *ctx, int for_read, int sz) { - unsigned char *p; - unsigned int extra,headerlen; - size_t len; + SSL3_BUF_FREELIST *list; + SSL3_BUF_FREELIST_ENTRY *ent = NULL; + void *result = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; + if (list != NULL && sz == (int)list->chunklen) + ent = list->head; + if (ent != NULL) + { + list->head = ent->next; + result = ent; + if (--list->len == 0) + list->chunklen = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + if (!result) + result = OPENSSL_malloc(sz); + return result; +} + +static void +freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem) + { + SSL3_BUF_FREELIST *list; + SSL3_BUF_FREELIST_ENTRY *ent; + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; + if (list != NULL && + (sz == list->chunklen || list->chunklen == 0) && + list->len < ctx->freelist_max_len && + sz >= sizeof(*ent)) + { + list->chunklen = sz; + ent = mem; + ent->next = list->head; + list->head = ent; + ++list->len; + mem = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + if (mem) + OPENSSL_free(mem); + } +#else +#define freelist_extract(c,fr,sz) OPENSSL_malloc(sz) +#define freelist_insert(c,fr,sz,m) OPENSSL_free(m) +#endif + +int ssl3_setup_read_buffer(SSL *s) + { + unsigned char *p; + size_t len,align=0,headerlen; + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) 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_PLAIN_LENGTH + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + + headerlen + align; if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) - extra=SSL3_RT_MAX_EXTRA; - else - extra=0; - len = SSL3_RT_MAX_PACKET_SIZE + extra; - if ((p=OPENSSL_malloc(len)) == NULL) + { + s->s3->init_extra = 1; + len += SSL3_RT_MAX_EXTRA; + } +#ifndef OPENSSL_NO_COMP + if (!(s->options & SSL_OP_NO_COMPRESSION)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + if ((p=freelist_extract(s->ctx, 1, len)) == NULL) goto err; s->s3->rbuf.buf = p; s->s3->rbuf.len = len; } + s->packet= &(s->s3->rbuf.buf[0]); + return 1; + +err: + SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER,ERR_R_MALLOC_FAILURE); + return 0; + } + +int ssl3_setup_write_buffer(SSL *s) + { + unsigned char *p; + size_t len,align=0,headerlen; + + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + 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 = SSL3_RT_MAX_PACKET_SIZE; - len += headerlen + 256; /* extra space for empty fragment */ - if ((p=OPENSSL_malloc(len)) == NULL) + len = s->max_send_fragment + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + + headerlen + align; +#ifndef OPENSSL_NO_COMP + if (!(s->options & SSL_OP_NO_COMPRESSION)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) + len += headerlen + align + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; + + if ((p=freelist_extract(s->ctx, 0, len)) == NULL) goto err; s->s3->wbuf.buf = p; s->s3->wbuf.len = len; } - s->packet= &(s->s3->rbuf.buf[0]); - return(1); + + return 1; + err: - SSLerr(SSL_F_SSL3_SETUP_BUFFERS,ERR_R_MALLOC_FAILURE); - return(0); + SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER,ERR_R_MALLOC_FAILURE); + return 0; } + + +int ssl3_setup_buffers(SSL *s) + { + if (!ssl3_setup_read_buffer(s)) + return 0; + if (!ssl3_setup_write_buffer(s)) + return 0; + return 1; + } + +int ssl3_release_write_buffer(SSL *s) + { + if (s->s3->wbuf.buf != NULL) + { + freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf); + s->s3->wbuf.buf = NULL; + } + return 1; + } + +int ssl3_release_read_buffer(SSL *s) + { + if (s->s3->rbuf.buf != NULL) + { + freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf); + s->s3->rbuf.buf = NULL; + } + return 1; + } + diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c index e5138b6e5e..41769febab 100644 --- a/crypto/openssl/ssl/s3_clnt.c +++ b/crypto/openssl/ssl/s3_clnt.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * 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 @@ -121,6 +121,32 @@ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include "ssl_locl.h" @@ -130,10 +156,6 @@ #include #include #include -#ifdef OPENSSL_FIPS -#include -#endif - #ifndef OPENSSL_NO_DH #include #endif @@ -142,15 +164,10 @@ #include #endif -static SSL_METHOD *ssl3_get_client_method(int ver); +static const SSL_METHOD *ssl3_get_client_method(int ver); static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); -#ifndef OPENSSL_NO_ECDH -static int curve_id2nid(int curve_id); -int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs); -#endif - -static SSL_METHOD *ssl3_get_client_method(int ver) +static const SSL_METHOD *ssl3_get_client_method(int ver) { if (ver == SSL3_VERSION) return(SSLv3_client_method()); @@ -166,7 +183,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_client_method, int ssl3_connect(SSL *s) { BUF_MEM *buf=NULL; - unsigned long Time=(unsigned long)time(NULL),l; + unsigned long Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; @@ -261,6 +278,7 @@ int ssl3_connect(SSL *s) case SSL3_ST_CR_SRVR_HELLO_B: ret=ssl3_get_server_hello(s); if (ret <= 0) goto end; + if (s->hit) s->state=SSL3_ST_CR_FINISHED_A; else @@ -285,7 +303,9 @@ int ssl3_connect(SSL *s) } #endif /* Check if it is anon DH/ECDH */ - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) + /* or PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { ret=ssl3_get_server_certificate(s); if (ret <= 0) goto end; @@ -360,7 +380,6 @@ int ssl3_connect(SSL *s) case SSL3_ST_CW_KEY_EXCH_B: ret=ssl3_send_client_key_exchange(s); if (ret <= 0) goto end; - l=s->s3->tmp.new_cipher->algorithms; /* EAY EAY EAY need to check for DH fix cert * sent back */ /* For TLS, cert_req is set to 2, so a cert chain @@ -381,6 +400,11 @@ int ssl3_connect(SSL *s) s->state=SSL3_ST_CW_CHANGE_A; s->s3->change_cipher_spec=0; } + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) + { + s->state=SSL3_ST_CW_CHANGE_A; + s->s3->change_cipher_spec=0; + } s->init_num=0; break; @@ -650,7 +674,9 @@ int ssl3_client_hello(SSL *s) #ifdef OPENSSL_NO_COMP *(p++)=1; #else - if (s->ctx->comp_methods == NULL) + + if ((s->options & SSL_OP_NO_COMPRESSION) + || !s->ctx->comp_methods) j=0; else j=sk_SSL_COMP_num(s->ctx->comp_methods); @@ -662,13 +688,21 @@ int ssl3_client_hello(SSL *s) } #endif *(p++)=0; /* Add the NULL method */ + #ifndef OPENSSL_NO_TLSEXT + /* TLS extensions*/ + if (ssl_prepare_clienthello_tlsext(s) <= 0) + { + SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); goto err; } -#endif +#endif + l=(p-d); d=buf; *(d++)=SSL3_MT_CLIENT_HELLO; @@ -689,7 +723,7 @@ err: int ssl3_get_server_hello(SSL *s) { STACK_OF(SSL_CIPHER) *sk; - SSL_CIPHER *c; + const SSL_CIPHER *c; unsigned char *p,*d; int i,al,ok; unsigned int j; @@ -758,6 +792,23 @@ int ssl3_get_server_hello(SSL *s) goto f_err; } +#ifndef OPENSSL_NO_TLSEXT + /* check if we want to resume the session based on external pre-shared secret */ + if (s->version >= TLS1_VERSION && s->tls_session_secret_cb) + { + SSL_CIPHER *pref_cipher=NULL; + s->session->master_key_length=sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, + NULL, &pref_cipher, + s->tls_session_secret_cb_arg)) + { + s->session->cipher = pref_cipher ? + pref_cipher : ssl_get_cipher_by_char(s, p+j); + } + } +#endif /* OPENSSL_NO_TLSEXT */ + if (j != 0 && j == s->session->session_id_length && memcmp(p,s->session->session_id,j) == 0) { @@ -824,6 +875,8 @@ int ssl3_get_server_hello(SSL *s) } } s->s3->tmp.new_cipher=c; + if (!ssl3_digest_cached_records(s)) + goto f_err; /* lets get the compression algorithm */ /* COMPRESSION */ @@ -834,10 +887,31 @@ int ssl3_get_server_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); goto f_err; } + /* If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } #else j= *(p++); + if (s->hit && j != s->session->compress_meth) + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); + goto f_err; + } if (j == 0) comp=NULL; + else if (s->options & SSL_OP_NO_COMPRESSION) + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED); + goto f_err; + } else comp=ssl3_comp_find(s->ctx->comp_methods,j); @@ -852,6 +926,7 @@ int ssl3_get_server_hello(SSL *s) s->s3->tmp.new_compression=comp; } #endif + #ifndef OPENSSL_NO_TLSEXT /* TLS extensions*/ if (s->version >= SSL3_VERSION) @@ -870,7 +945,6 @@ int ssl3_get_server_hello(SSL *s) } #endif - if (p != (d+n)) { /* wrong packet length */ @@ -908,7 +982,7 @@ int ssl3_get_server_certificate(SSL *s) if (!ok) return((int)n); if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || - ((s->s3->tmp.new_cipher->algorithms & SSL_aKRB5) && + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { s->s3->tmp.reuse_message=1; @@ -973,10 +1047,10 @@ int ssl3_get_server_certificate(SSL *s) i=ssl_verify_cert_chain(s,sk); if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) #ifndef OPENSSL_NO_KRB5 - && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - != (SSL_aKRB5|SSL_kKRB5) + && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) #endif /* OPENSSL_NO_KRB5 */ - ) + ) { al=ssl_verify_alarm_type(s->verify_result); SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); @@ -1000,15 +1074,15 @@ int ssl3_get_server_certificate(SSL *s) pkey=X509_get_pubkey(x); /* VRS: allow null cert if auth == KRB5 */ - need_cert = ((s->s3->tmp.new_cipher->algorithms - & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - == (SSL_aKRB5|SSL_kKRB5))? 0: 1; + need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) + ? 0 : 1; #ifdef KSSL_DEBUG - printf("pkey,x = %p, %p\n", (void *)pkey,(void *)x); + printf("pkey,x = %p, %p\n", pkey,x); printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey)); - printf("cipher, alg, nc = %s, %lx, %d\n", s->s3->tmp.new_cipher->name, - s->s3->tmp.new_cipher->algorithms, need_cert); + printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name, + s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert); #endif /* KSSL_DEBUG */ if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) @@ -1080,7 +1154,7 @@ int ssl3_get_key_exchange(SSL *s) EVP_MD_CTX md_ctx; unsigned char *param,*p; int al,i,j,param_len,ok; - long n,alg; + long n,alg_k,alg_a; EVP_PKEY *pkey=NULL; #ifndef OPENSSL_NO_RSA RSA *rsa=NULL; @@ -1104,17 +1178,28 @@ int ssl3_get_key_exchange(SSL *s) -1, s->max_cert_list, &ok); - if (!ok) return((int)n); if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { +#ifndef OPENSSL_NO_PSK + /* In plain PSK ciphersuite, ServerKeyExchange can be + omitted if no identity hint is sent. Set + session->sess_cert anyway to avoid problems + later.*/ + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) + { + s->session->sess_cert=ssl_sess_cert_new(); + if (s->ctx->psk_identity_hint) + OPENSSL_free(s->ctx->psk_identity_hint); + s->ctx->psk_identity_hint = NULL; + } +#endif s->s3->tmp.reuse_message=1; return(1); } param=p=(unsigned char *)s->init_msg; - if (s->session->sess_cert != NULL) { #ifndef OPENSSL_NO_RSA @@ -1145,11 +1230,57 @@ int ssl3_get_key_exchange(SSL *s) } param_len=0; - alg=s->s3->tmp.new_cipher->algorithms; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; + alg_a=s->s3->tmp.new_cipher->algorithm_auth; EVP_MD_CTX_init(&md_ctx); +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) + { + char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1]; + + al=SSL_AD_HANDSHAKE_FAILURE; + n2s(p,i); + param_len=i+2; + /* Store PSK identity hint for later use, hint is used + * in ssl3_send_client_key_exchange. Assume that the + * maximum length of a PSK identity hint can be as + * long as the maximum length of a PSK identity. */ + if (i > PSK_MAX_IDENTITY_LEN) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); + goto f_err; + } + /* If received PSK identity hint contains NULL + * characters, the hint is truncated from the first + * NULL. p may not be ending with NULL, so create a + * NULL-terminated string. */ + memcpy(tmp_id_hint, p, i); + memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i); + if (s->ctx->psk_identity_hint != NULL) + OPENSSL_free(s->ctx->psk_identity_hint); + s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint); + if (s->ctx->psk_identity_hint == NULL) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + p+=i; + n-=param_len; + } + else +#endif /* !OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_RSA - if (alg & SSL_kRSA) + if (alg_k & SSL_kRSA) { if ((rsa=RSA_new()) == NULL) { @@ -1188,7 +1319,7 @@ int ssl3_get_key_exchange(SSL *s) n-=param_len; /* this should be because we are using an export cipher */ - if (alg & SSL_aRSA) + if (alg_a & SSL_aRSA) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); else { @@ -1203,7 +1334,7 @@ int ssl3_get_key_exchange(SSL *s) ; #endif #ifndef OPENSSL_NO_DH - else if (alg & SSL_kEDH) + else if (alg_k & SSL_kEDH) { if ((dh=DH_new()) == NULL) { @@ -1257,14 +1388,14 @@ int ssl3_get_key_exchange(SSL *s) n-=param_len; #ifndef OPENSSL_NO_RSA - if (alg & SSL_aRSA) + if (alg_a & SSL_aRSA) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); #else if (0) ; #endif #ifndef OPENSSL_NO_DSA - else if (alg & SSL_aDSS) + else if (alg_a & SSL_aDSS) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509); #endif /* else anonymous DH, so no certificate or pkey. */ @@ -1272,7 +1403,7 @@ int ssl3_get_key_exchange(SSL *s) s->session->sess_cert->peer_dh_tmp=dh; dh=NULL; } - else if ((alg & SSL_kDHr) || (alg & SSL_kDHd)) + else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd)) { al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); @@ -1281,7 +1412,7 @@ int ssl3_get_key_exchange(SSL *s) #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH - else if (alg & SSL_kECDHE) + else if (alg_k & SSL_kEECDH) { EC_GROUP *ngroup; const EC_GROUP *group; @@ -1304,7 +1435,7 @@ int ssl3_get_key_exchange(SSL *s) param_len=3; if ((param_len > n) || (*p != NAMED_CURVE_TYPE) || - ((curve_nid = curve_id2nid(*(p + 2))) == 0)) + ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) { al=SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); @@ -1365,11 +1496,11 @@ int ssl3_get_key_exchange(SSL *s) */ if (0) ; #ifndef OPENSSL_NO_RSA - else if (alg & SSL_aRSA) + else if (alg_a & SSL_aRSA) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); #endif #ifndef OPENSSL_NO_ECDSA - else if (alg & SSL_aECDSA) + else if (alg_a & SSL_aECDSA) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); #endif /* else anonymous ECDH, so no certificate or pkey. */ @@ -1380,19 +1511,13 @@ int ssl3_get_key_exchange(SSL *s) EC_POINT_free(srvr_ecpoint); srvr_ecpoint = NULL; } - else if (alg & SSL_kECDH) + else if (alg_k) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); goto f_err; } #endif /* !OPENSSL_NO_ECDH */ - if (alg & SSL_aFZA) - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); - goto f_err; - } /* p points to the next byte, there are 'n' bytes left */ @@ -1421,8 +1546,6 @@ int ssl3_get_key_exchange(SSL *s) q=md_buf; for (num=2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); @@ -1493,12 +1616,13 @@ int ssl3_get_key_exchange(SSL *s) } else { - /* still data left over */ - if (!(alg & SSL_aNULL)) + if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK)) + /* aNULL or kPSK do not need public keys */ { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); goto err; } + /* still data left over */ if (n != 0) { al=SSL_AD_DECODE_ERROR; @@ -1568,8 +1692,7 @@ int ssl3_get_certificate_request(SSL *s) /* TLS does not like anon-DH with client cert */ if (s->version > SSL3_VERSION) { - l=s->s3->tmp.new_cipher->algorithms; - if (l & SSL_aNULL) + if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); @@ -1771,8 +1894,7 @@ err: int ssl3_get_cert_status(SSL *s) { int ok, al; - unsigned long resplen; - long n; + unsigned long resplen,n; const unsigned char *p; n=s->method->ssl_get_message(s, @@ -1798,7 +1920,7 @@ int ssl3_get_cert_status(SSL *s) goto f_err; } n2l3(p, resplen); - if (resplen + 4 != (unsigned long)n) + if (resplen + 4 != n) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH); @@ -1867,7 +1989,7 @@ int ssl3_send_client_key_exchange(SSL *s) { unsigned char *p,*d; int n; - unsigned long l; + unsigned long alg_k; #ifndef OPENSSL_NO_RSA unsigned char *q; EVP_PKEY *pkey=NULL; @@ -1889,12 +2011,12 @@ int ssl3_send_client_key_exchange(SSL *s) d=(unsigned char *)s->init_buf->data; p= &(d[4]); - l=s->s3->tmp.new_cipher->algorithms; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; /* Fool emacs indentation */ if (0) {} #ifndef OPENSSL_NO_RSA - else if (l & SSL_kRSA) + else if (alg_k & SSL_kRSA) { RSA *rsa; unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; @@ -1953,7 +2075,7 @@ int ssl3_send_client_key_exchange(SSL *s) } #endif #ifndef OPENSSL_NO_KRB5 - else if (l & SSL_kKRB5) + else if (alg_k & SSL_kKRB5) { krb5_error_code krb5rc; KSSL_CTX *kssl_ctx = s->kssl_ctx; @@ -1961,7 +2083,7 @@ int ssl3_send_client_key_exchange(SSL *s) krb5_data *enc_ticket; krb5_data authenticator, *authp = NULL; EVP_CIPHER_CTX ciph_ctx; - EVP_CIPHER *enc = NULL; + const EVP_CIPHER *enc = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH @@ -1972,7 +2094,7 @@ int ssl3_send_client_key_exchange(SSL *s) #ifdef KSSL_DEBUG printf("ssl3_send_client_key_exchange(%lx & %lx)\n", - l, SSL_kKRB5); + alg_k, SSL_kKRB5); #endif /* KSSL_DEBUG */ authp = NULL; @@ -2064,7 +2186,7 @@ int ssl3_send_client_key_exchange(SSL *s) sizeof tmp_buf); EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); outl += padl; - if (outl > sizeof epms) + if (outl > (int)sizeof epms) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; @@ -2078,7 +2200,7 @@ int ssl3_send_client_key_exchange(SSL *s) n+=outl + 2; s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, + s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, tmp_buf, sizeof tmp_buf); @@ -2087,7 +2209,7 @@ int ssl3_send_client_key_exchange(SSL *s) } #endif #ifndef OPENSSL_NO_DH - else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { DH *dh_srvr,*dh_clnt; @@ -2096,7 +2218,7 @@ int ssl3_send_client_key_exchange(SSL *s) ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); goto err; - } + } if (s->session->sess_cert->peer_dh_tmp != NULL) dh_srvr=s->session->sess_cert->peer_dh_tmp; @@ -2151,7 +2273,7 @@ int ssl3_send_client_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_ECDH - else if ((l & SSL_kECDH) || (l & SSL_kECDHE)) + else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) { const EC_GROUP *srvr_group = NULL; EC_KEY *tkey; @@ -2163,7 +2285,7 @@ int ssl3_send_client_key_exchange(SSL *s) * computation as part of client certificate? * If so, set ecdh_clnt_cert to 1. */ - if ((l & SSL_kECDH) && (s->cert != NULL)) + if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) { /* XXX: For now, we do not support client * authentication using ECDH certificates. @@ -2335,6 +2457,178 @@ int ssl3_send_client_key_exchange(SSL *s) EVP_PKEY_free(srvr_pub_pkey); } #endif /* !OPENSSL_NO_ECDH */ + else if (alg_k & SSL_kGOST) + { + /* GOST key exchange message creation */ + EVP_PKEY_CTX *pkey_ctx; + X509 *peer_cert; + size_t msglen; + unsigned int md_len; + int keytype; + unsigned char premaster_secret[32],shared_ukm[32], tmp[256]; + EVP_MD_CTX *ukm_hash; + EVP_PKEY *pub_key; + + /* Get server sertificate PKEY and create ctx from it */ + peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST01)].x509; + if (!peer_cert) + peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST94)].x509; + if (!peer_cert) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + goto err; + } + + pkey_ctx=EVP_PKEY_CTX_new(pub_key=X509_get_pubkey(peer_cert),NULL); + /* If we have send a certificate, and certificate key + + * parameters match those of server certificate, use + * certificate key for key exchange + */ + + /* Otherwise, generate ephemeral key pair */ + + EVP_PKEY_encrypt_init(pkey_ctx); + /* Generate session key */ + RAND_bytes(premaster_secret,32); + /* If we have client certificate, use its secret as peer key */ + if (s->s3->tmp.cert_req && s->cert->key->privatekey) { + if (EVP_PKEY_derive_set_peer(pkey_ctx,s->cert->key->privatekey) <=0) { + /* If there was an error - just ignore it. Ephemeral key + * would be used + */ + ERR_clear_error(); + } + } + /* Compute shared IV and store it in algorithm-specific + * context data */ + ukm_hash = EVP_MD_CTX_create(); + EVP_DigestInit(ukm_hash,EVP_get_digestbynid(NID_id_GostR3411_94)); + EVP_DigestUpdate(ukm_hash,s->s3->client_random,SSL3_RANDOM_SIZE); + EVP_DigestUpdate(ukm_hash,s->s3->server_random,SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len); + EVP_MD_CTX_destroy(ukm_hash); + if (EVP_PKEY_CTX_ctrl(pkey_ctx,-1,EVP_PKEY_OP_ENCRYPT,EVP_PKEY_CTRL_SET_IV, + 8,shared_ukm)<0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_LIBRARY_BUG); + goto err; + } + /* Make GOST keytransport blob message */ + /*Encapsulate it into sequence */ + *(p++)=V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; + msglen=255; + if (EVP_PKEY_encrypt(pkey_ctx,tmp,&msglen,premaster_secret,32)<0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_LIBRARY_BUG); + goto err; + } + if (msglen >= 0x80) + { + *(p++)=0x81; + *(p++)= msglen & 0xff; + n=msglen+3; + } + else + { + *(p++)= msglen & 0xff; + n=msglen+2; + } + memcpy(p, tmp, msglen); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + { + /* Set flag "skip certificate verify" */ + s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; + } + EVP_PKEY_CTX_free(pkey_ctx); + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key,premaster_secret,32); + EVP_PKEY_free(pub_key); + + } +#ifndef OPENSSL_NO_PSK + else if (alg_k & SSL_kPSK) + { + char identity[PSK_MAX_IDENTITY_LEN]; + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + + n = 0; + if (s->psk_client_callback == NULL) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_CLIENT_CB); + goto err; + } + + psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, + identity, PSK_MAX_IDENTITY_LEN, + psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_len > PSK_MAX_PSK_LEN) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + else if (psk_len == 0) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + goto psk_err; + } + + /* create PSK pre_master_secret */ + pre_ms_len = 2+psk_len+2+psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t+=psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL && + s->session->psk_identity_hint == NULL) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(identity); + if (s->session->psk_identity == NULL) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, + psk_or_pre_ms, pre_ms_len); + n = strlen(identity); + s2n(n, p); + memcpy(p, identity, n); + n+=2; + psk_err = 0; + psk_err: + OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN); + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) + { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + } +#endif else { ssl3_send_alert(s, SSL3_AL_FATAL, @@ -2371,28 +2665,37 @@ int ssl3_send_client_verify(SSL *s) unsigned char *p,*d; unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx=NULL; #ifndef OPENSSL_NO_RSA unsigned u=0; #endif unsigned long n; -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) int j; -#endif if (s->state == SSL3_ST_CW_CERT_VRFY_A) { d=(unsigned char *)s->init_buf->data; p= &(d[4]); pkey=s->cert->key->privatekey; - - s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2), - &(data[MD5_DIGEST_LENGTH])); - +/* Create context from key and test if sha1 is allowed as digest */ + pctx = EVP_PKEY_CTX_new(pkey,NULL); + EVP_PKEY_sign_init(pctx); + if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0) + { + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(data[MD5_DIGEST_LENGTH])); + } + else + { + ERR_clear_error(); + } #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst1),&(data[0])); + NID_md5, + &(data[0])); if (RSA_sign(NID_md5_sha1, data, MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, &(p[2]), &u, pkey->pkey.rsa) <= 0 ) @@ -2438,10 +2741,30 @@ int ssl3_send_client_verify(SSL *s) } else #endif - { + if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) + { + unsigned char signbuf[64]; + int i; + size_t sigsize=64; + s->method->ssl3_enc->cert_verify_mac(s, + NID_id_GostR3411_94, + data); + if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + for (i=63,j=0; i>=0; j++, i--) { + p[2+j]=signbuf[i]; + } + s2n(j,p); + n=j+2; + } + else + { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR); goto err; - } + } *(d++)=SSL3_MT_CERTIFICATE_VERIFY; l2n3(n,d); @@ -2449,8 +2772,10 @@ int ssl3_send_client_verify(SSL *s) s->init_num=(int)n+4; s->init_off=0; } + EVP_PKEY_CTX_free(pctx); return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); err: + EVP_PKEY_CTX_free(pctx); return(-1); } @@ -2535,7 +2860,7 @@ int ssl3_send_client_certificate(SSL *s) int ssl3_check_cert_and_algorithm(SSL *s) { int i,idx; - long algs; + long alg_k,alg_a; EVP_PKEY *pkey=NULL; SESS_CERT *sc; #ifndef OPENSSL_NO_RSA @@ -2545,14 +2870,14 @@ int ssl3_check_cert_and_algorithm(SSL *s) DH *dh; #endif - sc=s->session->sess_cert; - - algs=s->s3->tmp.new_cipher->algorithms; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; + alg_a=s->s3->tmp.new_cipher->algorithm_auth; /* we don't have a certificate */ - if (algs & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) + if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK)) return(1); + sc=s->session->sess_cert; if (sc == NULL) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR); @@ -2572,11 +2897,11 @@ int ssl3_check_cert_and_algorithm(SSL *s) #ifndef OPENSSL_NO_ECDH if (idx == SSL_PKEY_ECC) { - if (check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, + if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s->s3->tmp.new_cipher) == 0) { /* check failed */ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT); - goto f_err; + goto f_err; } else { @@ -2590,20 +2915,20 @@ int ssl3_check_cert_and_algorithm(SSL *s) /* Check that we have a certificate if we require one */ - if ((algs & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN)) + if ((alg_a & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT); goto f_err; } #ifndef OPENSSL_NO_DSA - else if ((algs & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN)) + else if ((alg_a & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT); goto f_err; } #endif #ifndef OPENSSL_NO_RSA - if ((algs & SSL_kRSA) && + if ((alg_k & SSL_kRSA) && !(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL))) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT); @@ -2611,19 +2936,19 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_DH - if ((algs & SSL_kEDH) && + if ((alg_k & SSL_kEDH) && !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY); goto f_err; } - else if ((algs & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) + else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT); goto f_err; } #ifndef OPENSSL_NO_DSA - else if ((algs & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) + else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT); goto f_err; @@ -2634,7 +2959,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP)) { #ifndef OPENSSL_NO_RSA - if (algs & SSL_kRSA) + if (alg_k & SSL_kRSA) { if (rsa == NULL || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) @@ -2646,7 +2971,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) else #endif #ifndef OPENSSL_NO_DH - if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { if (dh == NULL || DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) @@ -2669,49 +2994,6 @@ err: return(0); } - -#ifndef OPENSSL_NO_ECDH -/* This is the complement of nid2curve_id in s3_srvr.c. */ -static int curve_id2nid(int curve_id) -{ - /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) - * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */ - static int nid_list[26] = - { - 0, - NID_sect163k1, /* sect163k1 (1) */ - NID_sect163r1, /* sect163r1 (2) */ - NID_sect163r2, /* sect163r2 (3) */ - NID_sect193r1, /* sect193r1 (4) */ - NID_sect193r2, /* sect193r2 (5) */ - NID_sect233k1, /* sect233k1 (6) */ - NID_sect233r1, /* sect233r1 (7) */ - NID_sect239k1, /* sect239k1 (8) */ - NID_sect283k1, /* sect283k1 (9) */ - NID_sect283r1, /* sect283r1 (10) */ - NID_sect409k1, /* sect409k1 (11) */ - NID_sect409r1, /* sect409r1 (12) */ - NID_sect571k1, /* sect571k1 (13) */ - NID_sect571r1, /* sect571r1 (14) */ - NID_secp160k1, /* secp160k1 (15) */ - NID_secp160r1, /* secp160r1 (16) */ - NID_secp160r2, /* secp160r2 (17) */ - NID_secp192k1, /* secp192k1 (18) */ - NID_X9_62_prime192v1, /* secp192r1 (19) */ - NID_secp224k1, /* secp224k1 (20) */ - NID_secp224r1, /* secp224r1 (21) */ - NID_secp256k1, /* secp256k1 (22) */ - NID_X9_62_prime256v1, /* secp256r1 (23) */ - NID_secp384r1, /* secp384r1 (24) */ - NID_secp521r1 /* secp521r1 (25) */ - }; - - if ((curve_id < 1) || (curve_id > 25)) return 0; - - return nid_list[curve_id]; -} -#endif - /* Check to see if handshake is full or resumed. Usually this is just a * case of checking to see if a cache hit has occurred. In the case of * session tickets we have to check the next message to be sure. @@ -2722,11 +3004,8 @@ int ssl3_check_finished(SSL *s) { int ok; long n; - /* If we have no ticket or session ID is non-zero length (a match of - * a non-zero session length would never reach here) it cannot be a - * resumed session. - */ - if (!s->session->tlsext_tick || s->session->session_id_length) + /* If we have no ticket it cannot be a resumed session. */ + if (!s->session->tlsext_tick) return 1; /* this function is called when we really expect a Certificate * message, so permit appropriate message length */ diff --git a/crypto/openssl/ssl/s3_enc.c b/crypto/openssl/ssl/s3_enc.c index 06e54666b2..3d7aec97a2 100644 --- a/crypto/openssl/ssl/s3_enc.c +++ b/crypto/openssl/ssl/s3_enc.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * 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 @@ -108,6 +108,32 @@ * Hudson (tjh@cryptsoft.com). * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include "ssl_locl.h" @@ -129,10 +155,8 @@ static unsigned char ssl3_pad_2[48]={ 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c }; - -static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, +static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, unsigned char *p); - static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) { EVP_MD_CTX m5; @@ -146,7 +170,6 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) #endif k=0; EVP_MD_CTX_init(&m5); - EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_init(&s1); for (i=0; (int)is3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; + /* m == NULL will lead to a crash later */ + OPENSSL_assert(m); #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp=NULL; @@ -226,7 +251,8 @@ int ssl3_change_cipher_state(SSL *s, int which) /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; - s->read_hash=m; + + ssl_replace_hash(&s->read_hash,m); #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->expand != NULL) @@ -262,7 +288,7 @@ int ssl3_change_cipher_state(SSL *s, int which) /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; - s->write_hash=m; + ssl_replace_hash(&s->write_hash,m); #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->compress != NULL) @@ -289,6 +315,8 @@ int ssl3_change_cipher_state(SSL *s, int which) p=s->s3->tmp.key_block; i=EVP_MD_size(m); + if (i < 0) + goto err2; cl=EVP_CIPHER_key_length(c); j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; @@ -369,7 +397,7 @@ int ssl3_setup_key_block(SSL *s) if (s->s3->tmp.key_block_length != 0) return(1); - if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) + if (!ssl_cipher_get_evp(s->session,&c,&hash,NULL,NULL,&comp)) { SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); @@ -383,7 +411,11 @@ int ssl3_setup_key_block(SSL *s) s->s3->tmp.new_compression=comp; #endif - num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); + num=EVP_MD_size(hash); + if (num < 0) + return 0; + + num=EVP_CIPHER_key_length(c)+num+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); @@ -405,11 +437,11 @@ int ssl3_setup_key_block(SSL *s) if (s->session->cipher != NULL) { - if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) + if (s->session->cipher->algorithm_enc == SSL_eNULL) s->s3->need_empty_fragments = 0; #ifndef OPENSSL_NO_RC4 - if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) + if (s->session->cipher->algorithm_enc == SSL_RC4) s->s3->need_empty_fragments = 0; #endif } @@ -519,50 +551,131 @@ int ssl3_enc(SSL *s, int send) void ssl3_init_finished_mac(SSL *s) { - EVP_MD_CTX_set_flags(&(s->s3->finish_dgst1), - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_DigestInit_ex(&(s->s3->finish_dgst1),s->ctx->md5, NULL); - EVP_DigestInit_ex(&(s->s3->finish_dgst2),s->ctx->sha1, NULL); + if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer); + if (s->s3->handshake_dgst) ssl3_free_digest_list(s); + s->s3->handshake_buffer=BIO_new(BIO_s_mem()); + (void)BIO_set_close(s->s3->handshake_buffer,BIO_CLOSE); } +void ssl3_free_digest_list(SSL *s) + { + int i; + if (!s->s3->handshake_dgst) return; + for (i=0;is3->handshake_dgst[i]) + EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); + } + OPENSSL_free(s->s3->handshake_dgst); + s->s3->handshake_dgst=NULL; + } + + + void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) { - EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len); - EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len); + if (s->s3->handshake_buffer) + { + BIO_write (s->s3->handshake_buffer,(void *)buf,len); + } + else + { + int i; + for (i=0;i< SSL_MAX_DIGEST;i++) + { + if (s->s3->handshake_dgst[i]!= NULL) + EVP_DigestUpdate(s->s3->handshake_dgst[i],buf,len); + } + } } -int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p) +int ssl3_digest_cached_records(SSL *s) { - return(ssl3_handshake_mac(s,ctx,NULL,0,p)); + int i; + long mask; + const EVP_MD *md; + long hdatalen; + void *hdata; + + /* Allocate handshake_dgst array */ + ssl3_free_digest_list(s); + s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + memset(s->s3->handshake_dgst,0,SSL_MAX_DIGEST *sizeof(EVP_MD_CTX *)); + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,&hdata); + if (hdatalen <= 0) + { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH); + return 0; + } + + /* Loop through bitso of algorithm2 field and create MD_CTX-es */ + for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++) + { + if ((mask & s->s3->tmp.new_cipher->algorithm2) && md) + { + s->s3->handshake_dgst[i]=EVP_MD_CTX_create(); + EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL); + EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen); + } + else + { + s->s3->handshake_dgst[i]=NULL; + } + } + /* Free handshake_buffer BIO */ + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + + return 1; } -int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2, +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p) + { + return(ssl3_handshake_mac(s,md_nid,NULL,0,p)); + } +int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p) { int ret; - - ret=ssl3_handshake_mac(s,ctx1,sender,len,p); + ret=ssl3_handshake_mac(s,NID_md5,sender,len,p); p+=ret; - ret+=ssl3_handshake_mac(s,ctx2,sender,len,p); + ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p); return(ret); } - -static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, +static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, unsigned char *p) { unsigned int ret; int npad,n; unsigned int i; unsigned char md_buf[EVP_MAX_MD_SIZE]; - EVP_MD_CTX ctx; + EVP_MD_CTX ctx,*d=NULL; - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_MD_CTX_copy_ex(&ctx,in_ctx); + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + /* Search for digest of specified type in the handshake_dgst + * array*/ + for (i=0;is3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) + { + d=s->s3->handshake_dgst[i]; + break; + } + } + if (!d) { + SSLerr(SSL_F_SSL3_HANDSHAKE_MAC,SSL_R_NO_REQUIRED_DIGEST); + return 0; + } + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_copy_ex(&ctx,d); n=EVP_MD_CTX_size(&ctx); - npad=(48/n)*n; + if (n < 0) + return 0; + npad=(48/n)*n; if (sender != NULL) EVP_DigestUpdate(&ctx,sender,len); EVP_DigestUpdate(&ctx,s->session->master_key, @@ -582,15 +695,16 @@ static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, return((int)ret); } -int ssl3_mac(SSL *ssl, unsigned char *md, int send) +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *mac_sec,*seq; EVP_MD_CTX md_ctx; - const EVP_MD *hash; + const EVP_MD_CTX *hash; unsigned char *p,rec_char; unsigned int md_size; int npad; + int t; if (send) { @@ -607,13 +721,16 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send) hash=ssl->read_hash; } - md_size=EVP_MD_size(hash); + t=EVP_MD_CTX_size(hash); + if (t < 0) + return -1; + md_size=t; npad=(48/md_size)*md_size; /* Chop the digest off the end :-) */ EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit_ex( &md_ctx,hash, NULL); + EVP_MD_CTX_copy_ex( &md_ctx,hash); EVP_DigestUpdate(&md_ctx,mac_sec,md_size); EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); EVP_DigestUpdate(&md_ctx,seq,8); @@ -625,7 +742,7 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send) EVP_DigestUpdate(&md_ctx,rec->input,rec->length); EVP_DigestFinal_ex( &md_ctx,md,NULL); - EVP_DigestInit_ex( &md_ctx,hash, NULL); + EVP_MD_CTX_copy_ex( &md_ctx,hash); EVP_DigestUpdate(&md_ctx,mac_sec,md_size); EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); EVP_DigestUpdate(&md_ctx,md,md_size); @@ -718,6 +835,12 @@ int ssl3_alert_code(int code) case SSL_AD_INTERNAL_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_USER_CANCELLED: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_NO_RENEGOTIATION: return(-1); /* Don't send it :-) */ + case SSL_AD_UNSUPPORTED_EXTENSION: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNRECOGNIZED_NAME: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); default: return(-1); } } diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c index 8fa4ab02c3..d6b047c995 100644 --- a/crypto/openssl/ssl/s3_lib.c +++ b/crypto/openssl/ssl/s3_lib.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * 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 @@ -121,16 +121,46 @@ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include #include "ssl_locl.h" #include "kssl_lcl.h" +#ifndef OPENSSL_NO_TLSEXT +#ifndef OPENSSL_NO_EC +#include "../crypto/ec/ec_lcl.h" +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_TLSEXT */ #include #ifndef OPENSSL_NO_DH #include #endif -#include const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT; @@ -138,217 +168,265 @@ const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT; /* list of available SSLv3 ciphers (sorted by id) */ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ + /* The RSA ciphers */ /* Cipher 01 */ { 1, SSL3_TXT_RSA_NULL_MD5, SSL3_CK_RSA_NULL_MD5, - SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_MD5|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 0, 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 02 */ { 1, SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, - SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_SHA1|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 0, 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 03 */ { 1, SSL3_TXT_RSA_RC4_40_MD5, SSL3_CK_RSA_RC4_40_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC4 |SSL_MD5 |SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 04 */ { 1, SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC4 |SSL_MD5|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 05 */ { 1, SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, - SSL_kRSA|SSL_aRSA|SSL_RC4 |SSL_SHA1|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 06 */ { 1, SSL3_TXT_RSA_RC2_40_MD5, SSL3_CK_RSA_RC2_40_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC2 |SSL_MD5 |SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 07 */ #ifndef OPENSSL_NO_IDEA { 1, SSL3_TXT_RSA_IDEA_128_SHA, SSL3_CK_RSA_IDEA_128_SHA, - SSL_kRSA|SSL_aRSA|SSL_IDEA |SSL_SHA1|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_IDEA, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif + /* Cipher 08 */ { 1, SSL3_TXT_RSA_DES_40_CBC_SHA, SSL3_CK_RSA_DES_40_CBC_SHA, - SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 09 */ { 1, SSL3_TXT_RSA_DES_64_CBC_SHA, SSL3_CK_RSA_DES_64_CBC_SHA, - SSL_kRSA|SSL_aRSA|SSL_DES |SSL_SHA1|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 0A */ { 1, SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, - SSL_kRSA|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* The DH ciphers */ /* Cipher 0B */ { 0, SSL3_TXT_DH_DSS_DES_40_CBC_SHA, SSL3_CK_DH_DSS_DES_40_CBC_SHA, - SSL_kDHd |SSL_aDH|SSL_DES|SSL_SHA1|SSL_SSLV3, + SSL_kDHd, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 0C */ { - 0, + 0, /* not implemented (non-ephemeral DH) */ SSL3_TXT_DH_DSS_DES_64_CBC_SHA, SSL3_CK_DH_DSS_DES_64_CBC_SHA, - SSL_kDHd |SSL_aDH|SSL_DES |SSL_SHA1|SSL_SSLV3, + SSL_kDHd, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 0D */ { - 0, + 0, /* not implemented (non-ephemeral DH) */ SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, SSL3_CK_DH_DSS_DES_192_CBC3_SHA, - SSL_kDHd |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3, + SSL_kDHd, + SSL_aDH, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 0E */ { - 0, + 0, /* not implemented (non-ephemeral DH) */ SSL3_TXT_DH_RSA_DES_40_CBC_SHA, SSL3_CK_DH_RSA_DES_40_CBC_SHA, - SSL_kDHr |SSL_aDH|SSL_DES|SSL_SHA1|SSL_SSLV3, + SSL_kDHr, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 0F */ { - 0, + 0, /* not implemented (non-ephemeral DH) */ SSL3_TXT_DH_RSA_DES_64_CBC_SHA, SSL3_CK_DH_RSA_DES_64_CBC_SHA, - SSL_kDHr |SSL_aDH|SSL_DES |SSL_SHA1|SSL_SSLV3, + SSL_kDHr, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 10 */ { - 0, + 0, /* not implemented (non-ephemeral DH) */ SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, SSL3_CK_DH_RSA_DES_192_CBC3_SHA, - SSL_kDHr |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3, + SSL_kDHr, + SSL_aDH, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* The Ephemeral DH ciphers */ @@ -357,158 +435,193 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_EDH_DSS_DES_40_CBC_SHA, SSL3_CK_EDH_DSS_DES_40_CBC_SHA, - SSL_kEDH|SSL_aDSS|SSL_DES|SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 12 */ { 1, SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, SSL3_CK_EDH_DSS_DES_64_CBC_SHA, - SSL_kEDH|SSL_aDSS|SSL_DES |SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 13 */ { 1, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, - SSL_kEDH|SSL_aDSS|SSL_3DES |SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aDSS, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 14 */ { 1, SSL3_TXT_EDH_RSA_DES_40_CBC_SHA, SSL3_CK_EDH_RSA_DES_40_CBC_SHA, - SSL_kEDH|SSL_aRSA|SSL_DES|SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 15 */ { 1, SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, SSL3_CK_EDH_RSA_DES_64_CBC_SHA, - SSL_kEDH|SSL_aRSA|SSL_DES |SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 16 */ { 1, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, - SSL_kEDH|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 17 */ { 1, SSL3_TXT_ADH_RC4_40_MD5, SSL3_CK_ADH_RC4_40_MD5, - SSL_kEDH |SSL_aNULL|SSL_RC4 |SSL_MD5 |SSL_SSLV3, + SSL_kEDH, + SSL_aNULL, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 18 */ { 1, SSL3_TXT_ADH_RC4_128_MD5, SSL3_CK_ADH_RC4_128_MD5, - SSL_kEDH |SSL_aNULL|SSL_RC4 |SSL_MD5 |SSL_SSLV3, + SSL_kEDH, + SSL_aNULL, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 19 */ { 1, SSL3_TXT_ADH_DES_40_CBC_SHA, SSL3_CK_ADH_DES_40_CBC_SHA, - SSL_kEDH |SSL_aNULL|SSL_DES|SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aNULL, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 1A */ { 1, SSL3_TXT_ADH_DES_64_CBC_SHA, SSL3_CK_ADH_DES_64_CBC_SHA, - SSL_kEDH |SSL_aNULL|SSL_DES |SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aNULL, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 1B */ { 1, SSL3_TXT_ADH_DES_192_CBC_SHA, SSL3_CK_ADH_DES_192_CBC_SHA, - SSL_kEDH |SSL_aNULL|SSL_3DES |SSL_SHA1|SSL_SSLV3, + SSL_kEDH, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, -/* Fortezza */ +/* Fortezza ciphersuite from SSL 3.0 spec */ +#if 0 /* Cipher 1C */ { 0, SSL3_TXT_FZA_DMS_NULL_SHA, SSL3_CK_FZA_DMS_NULL_SHA, - SSL_kFZA|SSL_aFZA |SSL_eNULL |SSL_SHA1|SSL_SSLV3, + SSL_kFZA, + SSL_aFZA, + SSL_eNULL, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 0, 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 1D */ @@ -516,45 +629,50 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, SSL3_TXT_FZA_DMS_FZA_SHA, SSL3_CK_FZA_DMS_FZA_SHA, - SSL_kFZA|SSL_aFZA |SSL_eFZA |SSL_SHA1|SSL_SSLV3, + SSL_kFZA, + SSL_aFZA, + SSL_eFZA, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 0, 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, -#if 0 /* Cipher 1E */ { 0, SSL3_TXT_FZA_DMS_RC4_SHA, SSL3_CK_FZA_DMS_RC4_SHA, - SSL_kFZA|SSL_aFZA |SSL_RC4 |SSL_SHA1|SSL_SSLV3, + SSL_kFZA, + SSL_aFZA, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif #ifndef OPENSSL_NO_KRB5 -/* The Kerberos ciphers */ +/* The Kerberos ciphers*/ /* Cipher 1E */ { 1, SSL3_TXT_KRB5_DES_64_CBC_SHA, SSL3_CK_KRB5_DES_64_CBC_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 1F */ @@ -562,13 +680,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_DES_192_CBC3_SHA, SSL3_CK_KRB5_DES_192_CBC3_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 20 */ @@ -576,13 +696,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_RC4_128_SHA, SSL3_CK_KRB5_RC4_128_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 21 */ @@ -590,13 +712,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_IDEA_128_CBC_SHA, SSL3_CK_KRB5_IDEA_128_CBC_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_IDEA|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_IDEA, + SSL_SHA1, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 22 */ @@ -604,13 +728,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_DES_64_CBC_MD5, SSL3_CK_KRB5_DES_64_CBC_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 56, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 23 */ @@ -618,13 +744,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_DES_192_CBC3_MD5, SSL3_CK_KRB5_DES_192_CBC3_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_3DES, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 168, 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 24 */ @@ -632,13 +760,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_RC4_128_MD5, SSL3_CK_KRB5_RC4_128_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 25 */ @@ -646,13 +776,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_IDEA_128_CBC_MD5, SSL3_CK_KRB5_IDEA_128_CBC_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_IDEA|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_IDEA, + SSL_MD5, + SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 26 */ @@ -660,13 +792,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_DES_40_CBC_SHA, SSL3_CK_KRB5_DES_40_CBC_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 27 */ @@ -674,13 +808,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_RC2_40_CBC_SHA, SSL3_CK_KRB5_RC2_40_CBC_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_RC2|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC2, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 28 */ @@ -688,13 +824,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_RC4_40_SHA, SSL3_CK_KRB5_RC4_40_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_SHA1 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 29 */ @@ -702,13 +840,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_DES_40_CBC_MD5, SSL3_CK_KRB5_DES_40_CBC_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_MD5, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 2A */ @@ -716,13 +856,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_RC2_40_CBC_MD5, SSL3_CK_KRB5_RC2_40_CBC_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_RC2|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC2, + SSL_MD5, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 2B */ @@ -730,13 +872,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, SSL3_TXT_KRB5_RC4_40_MD5, SSL3_CK_KRB5_RC4_40_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_MD5 |SSL_SSLV3, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, SSL_EXPORT|SSL_EXP40, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 40, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif /* OPENSSL_NO_KRB5 */ @@ -746,78 +890,90 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, - SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 30 */ { 0, TLS1_TXT_DH_DSS_WITH_AES_128_SHA, TLS1_CK_DH_DSS_WITH_AES_128_SHA, - SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kDHd, + SSL_aDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 31 */ { 0, TLS1_TXT_DH_RSA_WITH_AES_128_SHA, TLS1_CK_DH_RSA_WITH_AES_128_SHA, - SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 32 */ { 1, TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, TLS1_CK_DHE_DSS_WITH_AES_128_SHA, - SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aDSS, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 33 */ { 1, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA, - SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 34 */ { 1, TLS1_TXT_ADH_WITH_AES_128_SHA, TLS1_CK_ADH_WITH_AES_128_SHA, - SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 35 */ @@ -825,78 +981,94 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, - SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 36 */ { 0, TLS1_TXT_DH_DSS_WITH_AES_256_SHA, TLS1_CK_DH_DSS_WITH_AES_256_SHA, - SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kDHd, + SSL_aDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 37 */ { - 0, + 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_RSA_WITH_AES_256_SHA, TLS1_CK_DH_RSA_WITH_AES_256_SHA, - SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 38 */ { 1, TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, TLS1_CK_DHE_DSS_WITH_AES_256_SHA, - SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aDSS, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 39 */ { 1, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA, - SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, + /* Cipher 3A */ { 1, TLS1_TXT_ADH_WITH_AES_256_SHA, TLS1_CK_ADH_WITH_AES_256_SHA, - SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #ifndef OPENSSL_NO_CAMELLIA @@ -907,78 +1079,95 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kRSA|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kRSA, + SSL_aRSA, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 42 */ { 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, - SSL_kDHd|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kDHd, + SSL_aDH, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 43 */ { 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kDHr|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kDHr, + SSL_aDH, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 44 */ { 1, TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH|SSL_aDSS|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aDSS, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 45 */ { 1, TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aRSA, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 46 */ { 1, TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH|SSL_aNULL|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aNULL, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, #endif /* OPENSSL_NO_CAMELLIA */ @@ -986,98 +1175,174 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ /* New TLS Export CipherSuites from expired ID */ #if 0 /* Cipher 60 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, - TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_TLSV1, - SSL_EXPORT|SSL_EXP56, - 0, - 56, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, + TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_TLSV1, + SSL_EXPORT|SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 56, + 128, + }, + /* Cipher 61 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_TLSV1, - SSL_EXPORT|SSL_EXP56, - 0, - 56, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, + TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_TLSV1, + SSL_EXPORT|SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 56, + 128, + }, #endif + /* Cipher 62 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, - TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, - SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA|SSL_TLSV1, - SSL_EXPORT|SSL_EXP56, - 0, - 56, - 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, + TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_TLSV1, + SSL_EXPORT|SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 56, + 56, + }, + /* Cipher 63 */ - { - 1, - TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - SSL_kEDH|SSL_aDSS|SSL_DES|SSL_SHA|SSL_TLSV1, - SSL_EXPORT|SSL_EXP56, - 0, - 56, - 56, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_TLSV1, + SSL_EXPORT|SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 56, + 56, + }, + /* Cipher 64 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, - TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, - SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_EXPORT|SSL_EXP56, - 0, - 56, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, + TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_EXPORT|SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 56, + 128, + }, + /* Cipher 65 */ - { - 1, - TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - SSL_kEDH|SSL_aDSS|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_EXPORT|SSL_EXP56, - 0, - 56, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_EXPORT|SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 56, + 128, + }, + /* Cipher 66 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, - TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, - SSL_kEDH|SSL_aDSS|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_MEDIUM, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS - }, + { + 1, + TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, + TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, #endif + { + 1, + "GOST94-GOST89-GOST89", + 0x3000080, + SSL_kGOST, + SSL_aGOST94, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC, + 256, + 256 + }, + { + 1, + "GOST2001-GOST89-GOST89", + 0x3000081, + SSL_kGOST, + SSL_aGOST01, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC, + 256, + 256 + }, + { + 1, + "GOST94-NULL-GOST94", + 0x3000082, + SSL_kGOST, + SSL_aGOST94, + SSL_eNULL, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94, + 0, + 0 + }, + { + 1, + "GOST2001-NULL-GOST94", + 0x3000083, + SSL_kGOST, + SSL_aGOST01, + SSL_eNULL, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94, + 0, + 0 + }, #ifndef OPENSSL_NO_CAMELLIA /* Camellia ciphersuites from RFC4132 (256-bit portion) */ @@ -1087,81 +1352,163 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kRSA|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kRSA, + SSL_aRSA, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, /* Cipher 85 */ { 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, - SSL_kDHd|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kDHd, + SSL_aDH, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 86 */ { 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kDHr|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kDHr, + SSL_aDH, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 87 */ { 1, TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH|SSL_aDSS|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aDSS, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 88 */ { 1, TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aRSA, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, + /* Cipher 89 */ { 1, TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH|SSL_aNULL|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1, + SSL_kEDH, + SSL_aNULL, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 256, 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS }, #endif /* OPENSSL_NO_CAMELLIA */ +#ifndef OPENSSL_NO_PSK + /* Cipher 8A */ + { + 1, + TLS1_TXT_PSK_WITH_RC4_128_SHA, + TLS1_CK_PSK_WITH_RC4_128_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 8B */ + { + 1, + TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, + + /* Cipher 8C */ + { + 1, + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 8D */ + { + 1, + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_PSK */ + #ifndef OPENSSL_NO_SEED /* SEED ciphersuites from RFC4162 */ @@ -1170,13 +1517,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_RSA_WITH_SEED_SHA, TLS1_CK_RSA_WITH_SEED_SHA, - SSL_kRSA|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_kRSA, + SSL_aRSA, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 97 */ @@ -1184,13 +1533,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_DSS_WITH_SEED_SHA, TLS1_CK_DH_DSS_WITH_SEED_SHA, - SSL_kDHd|SSL_aDH|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_kDHd, + SSL_aDH, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 98 */ @@ -1198,13 +1549,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_RSA_WITH_SEED_SHA, TLS1_CK_DH_RSA_WITH_SEED_SHA, - SSL_kDHr|SSL_aDH|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_kDHr, + SSL_aDH, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 99 */ @@ -1212,13 +1565,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_DHE_DSS_WITH_SEED_SHA, TLS1_CK_DHE_DSS_WITH_SEED_SHA, - SSL_kEDH|SSL_aDSS|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_kEDH, + SSL_aDSS, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 9A */ @@ -1226,13 +1581,15 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_DHE_RSA_WITH_SEED_SHA, TLS1_CK_DHE_RSA_WITH_SEED_SHA, - SSL_kEDH|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_kEDH, + SSL_aRSA, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, /* Cipher 9B */ @@ -1240,376 +1597,487 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_ADH_WITH_SEED_SHA, TLS1_CK_ADH_WITH_SEED_SHA, - SSL_kEDH|SSL_aNULL|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_kEDH, + SSL_aNULL, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, - 0, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, 128, 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, }, #endif /* OPENSSL_NO_SEED */ #ifndef OPENSSL_NO_ECDH /* Cipher C001 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, - TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, - SSL_kECDH|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, + TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 0, + 0, + }, /* Cipher C002 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, - SSL_kECDH|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C003 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, - SSL_kECDH|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 168, - 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, /* Cipher C004 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C005 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 256, - 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, /* Cipher C006 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, - SSL_kECDHE|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 0, + 0, + }, /* Cipher C007 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, - SSL_kECDHE|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C008 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, - SSL_kECDHE|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 168, - 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, /* Cipher C009 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C00A */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 256, - 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, /* Cipher C00B */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, - TLS1_CK_ECDH_RSA_WITH_NULL_SHA, - SSL_kECDH|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, + TLS1_CK_ECDH_RSA_WITH_NULL_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 0, + 0, + }, /* Cipher C00C */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, - TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, - SSL_kECDH|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C00D */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, - SSL_kECDH|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 168, - 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, /* Cipher C00E */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, - SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C00F */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, - SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 256, - 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, /* Cipher C010 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, - TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, - SSL_kECDHE|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, + TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 0, + 0, + }, /* Cipher C011 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_kECDHE|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C012 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, - SSL_kECDHE|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 168, - 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, /* Cipher C013 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, - SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C014 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, - SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 256, - 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, /* Cipher C015 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_NULL_SHA, - TLS1_CK_ECDH_anon_WITH_NULL_SHA, - SSL_kECDHE|SSL_aNULL|SSL_eNULL|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 0, - 0, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_anon_WITH_NULL_SHA, + TLS1_CK_ECDH_anon_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 0, + 0, + }, /* Cipher C016 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, - TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, - SSL_kECDHE|SSL_aNULL|SSL_RC4|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, + TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C017 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, - SSL_kECDHE|SSL_aNULL|SSL_3DES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 168, - 168, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, /* Cipher C018 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, - SSL_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 128, - 128, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, /* Cipher C019 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, - SSL_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, - 0, - 256, - 256, - SSL_ALL_CIPHERS, - SSL_ALL_STRENGTHS, - }, + { + 1, + TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, #endif /* OPENSSL_NO_ECDH */ +#ifdef TEMP_GOST_TLS +/* Cipher FF00 */ + { + 1, + "GOST-MD5", + 0x0300ff00, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + { + 1, + "GOST-GOST94", + 0x0300ff01, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256 + }, + { + 1, + "GOST-GOST89MAC", + 0x0300ff02, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256 + }, + { + 1, + "GOST-GOST89STREAM", + 0x0300ff03, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF|TLS1_STREAM_MAC, + 256, + 256 + }, +#endif /* end of list */ }; SSL3_ENC_METHOD SSLv3_enc_data={ ssl3_enc, - ssl3_mac, + n_ssl3_mac, ssl3_setup_key_block, ssl3_generate_master_secret, ssl3_change_cipher_state, @@ -1628,17 +2096,12 @@ long ssl3_default_timeout(void) return(60*60*2); } -IMPLEMENT_ssl3_meth_func(sslv3_base_method, - ssl_undefined_function, - ssl_undefined_function, - ssl_bad_method) - int ssl3_num_ciphers(void) { return(SSL3_NUM_CIPHERS); } -SSL_CIPHER *ssl3_get_cipher(unsigned int u) +const SSL_CIPHER *ssl3_get_cipher(unsigned int u) { if (u < SSL3_NUM_CIPHERS) return(&(ssl3_ciphers[SSL3_NUM_CIPHERS-1-u])); @@ -1660,10 +2123,8 @@ int ssl3_new(SSL *s) if ((s3=OPENSSL_malloc(sizeof *s3)) == NULL) goto err; memset(s3,0,sizeof *s3); - EVP_MD_CTX_init(&s3->finish_dgst1); - EVP_MD_CTX_init(&s3->finish_dgst2); - pq_64bit_init(&(s3->rrec.seq_num)); - pq_64bit_init(&(s3->wrec.seq_num)); + memset(s3->rrec.seq_num,0,sizeof(s3->rrec.seq_num)); + memset(s3->wrec.seq_num,0,sizeof(s3->wrec.seq_num)); s->s3=s3; @@ -1678,11 +2139,18 @@ void ssl3_free(SSL *s) if(s == NULL) return; +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) + OPENSSL_free(s->s3->client_opaque_prf_input); + if (s->s3->server_opaque_prf_input != NULL) + OPENSSL_free(s->s3->server_opaque_prf_input); +#endif + ssl3_cleanup_key_block(s); if (s->s3->rbuf.buf != NULL) - OPENSSL_free(s->s3->rbuf.buf); + ssl3_release_read_buffer(s); if (s->s3->wbuf.buf != NULL) - OPENSSL_free(s->s3->wbuf.buf); + ssl3_release_write_buffer(s); if (s->s3->rrec.comp != NULL) OPENSSL_free(s->s3->rrec.comp); #ifndef OPENSSL_NO_DH @@ -1696,11 +2164,10 @@ void ssl3_free(SSL *s) if (s->s3->tmp.ca_names != NULL) sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free); - EVP_MD_CTX_cleanup(&s->s3->finish_dgst1); - EVP_MD_CTX_cleanup(&s->s3->finish_dgst2); - pq_64bit_free(&(s->s3->rrec.seq_num)); - pq_64bit_free(&(s->s3->wrec.seq_num)); - + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + } + if (s->s3->handshake_dgst) ssl3_free_digest_list(s); OPENSSL_cleanse(s->s3,sizeof *s->s3); OPENSSL_free(s->s3); s->s3=NULL; @@ -1711,6 +2178,15 @@ void ssl3_clear(SSL *s) unsigned char *rp,*wp; size_t rlen, wlen; +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) + OPENSSL_free(s->s3->client_opaque_prf_input); + s->s3->client_opaque_prf_input = NULL; + if (s->s3->server_opaque_prf_input != NULL) + OPENSSL_free(s->s3->server_opaque_prf_input); + s->s3->server_opaque_prf_input = NULL; +#endif + ssl3_cleanup_key_block(s); if (s->s3->tmp.ca_names != NULL) sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free); @@ -1733,10 +2209,13 @@ void ssl3_clear(SSL *s) wp = s->s3->wbuf.buf; rlen = s->s3->rbuf.len; wlen = s->s3->wbuf.len; - - EVP_MD_CTX_cleanup(&s->s3->finish_dgst1); - EVP_MD_CTX_cleanup(&s->s3->finish_dgst2); - + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + } + if (s->s3->handshake_dgst) { + ssl3_free_digest_list(s); + } memset(s->s3,0,sizeof *s->s3); s->s3->rbuf.buf = rp; s->s3->wbuf.buf = wp; @@ -1936,7 +2415,31 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) s->tlsext_debug_arg=parg; ret = 1; break; - + +#ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT: + if (larg > 12288) /* actual internal limit is 2^16 for the complete hello message + * (including the cert chain and everything) */ + { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG); + break; + } + if (s->tlsext_opaque_prf_input != NULL) + OPENSSL_free(s->tlsext_opaque_prf_input); + if ((size_t)larg == 0) + s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */ + else + s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg); + if (s->tlsext_opaque_prf_input != NULL) + { + s->tlsext_opaque_prf_input_len = (size_t)larg; + ret = 1; + } + else + s->tlsext_opaque_prf_input_len = 0; + break; +#endif + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: s->tlsext_status_type=larg; ret = 1; @@ -2194,13 +2697,20 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) } return 1; } - + +#ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG: + ctx->tlsext_opaque_prf_input_callback_arg = parg; + return 1; +#endif + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: ctx->tlsext_status_arg=parg; return 1; break; #endif /* !OPENSSL_NO_TLSEXT */ + /* A Thawte special :-) */ case SSL_CTRL_EXTRA_CHAIN_CERT: if (ctx->extra_certs == NULL) @@ -2250,7 +2760,13 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: ctx->tlsext_servername_callback=(int (*)(SSL *,int *,void *))fp; break; - + +#ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB: + ctx->tlsext_opaque_prf_input_callback = (int (*)(SSL *,void *, size_t, void *))fp; + break; +#endif + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: ctx->tlsext_status_cb=(int (*)(SSL *,void *))fp; break; @@ -2271,17 +2787,15 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) /* This function needs to check if the ciphers required are actually * available */ -SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) { - SSL_CIPHER c,*cp; + SSL_CIPHER c; + const SSL_CIPHER *cp; unsigned long id; id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1]; c.id=id; - cp = (SSL_CIPHER *)OBJ_bsearch((char *)&c, - (char *)ssl3_ciphers, - SSL3_NUM_CIPHERS,sizeof(SSL_CIPHER), - FP_ICC ssl_cipher_id_cmp); + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); if (cp == NULL || cp->valid == 0) return NULL; else @@ -2307,10 +2821,14 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, { SSL_CIPHER *c,*ret=NULL; STACK_OF(SSL_CIPHER) *prio, *allow; - int i,j,ok; - + int i,ii,ok; +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC) + unsigned int j; + int ec_ok, ec_nid; + unsigned char ec_search1 = 0, ec_search2 = 0; +#endif CERT *cert; - unsigned long alg,mask,emask; + unsigned long alg_k,alg_a,mask_k,mask_a,emask_k,emask_a; /* Let's see which ciphers we can support */ cert=s->cert; @@ -2326,73 +2844,237 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #endif #ifdef CIPHER_DEBUG - printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), srvr); - for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i) - { - c=sk_SSL_CIPHER_value(srvr,i); - printf("%p:%s\n",c,c->name); - } - printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), clnt); - for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i) + printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr); + for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i) + { + c=sk_SSL_CIPHER_value(srvr,i); + printf("%p:%s\n",(void *)c,c->name); + } + printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt); + for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i) { c=sk_SSL_CIPHER_value(clnt,i); - printf("%p:%s\n",c,c->name); + printf("%p:%s\n",(void *)c,c->name); } #endif if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) - { - prio = srvr; - allow = clnt; - } + { + prio = srvr; + allow = clnt; + } else - { - prio = clnt; - allow = srvr; - } + { + prio = clnt; + allow = srvr; + } for (i=0; imask; - emask=cert->export_mask; + mask_k = cert->mask_k; + mask_a = cert->mask_a; + emask_k = cert->export_mask_k; + emask_a = cert->export_mask_a; #ifdef KSSL_DEBUG - printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms); +/* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/ #endif /* KSSL_DEBUG */ - alg=c->algorithms&(SSL_MKEY_MASK|SSL_AUTH_MASK); + alg_k=c->algorithm_mkey; + alg_a=c->algorithm_auth; + #ifndef OPENSSL_NO_KRB5 - if (alg & SSL_KRB5) - { - if ( !kssl_keytab_is_available(s->kssl_ctx) ) - continue; - } + if (alg_k & SSL_kKRB5) + { + if ( !kssl_keytab_is_available(s->kssl_ctx) ) + continue; + } #endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + /* with PSK there must be server callback set */ + if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) + continue; +#endif /* OPENSSL_NO_PSK */ + if (SSL_C_IS_EXPORT(c)) { - ok=((alg & emask) == alg)?1:0; + ok = (alg_k & emask_k) && (alg_a & emask_a); #ifdef CIPHER_DEBUG - printf("%d:[%08lX:%08lX]%p:%s (export)\n",ok,alg,emask, - c,c->name); + printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a, + (void *)c,c->name); #endif } else { - ok=((alg & mask) == alg)?1:0; + ok = (alg_k & mask_k) && (alg_a & mask_a); #ifdef CIPHER_DEBUG - printf("%d:[%08lX:%08lX]%p:%s\n",ok,alg,mask,c, + printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c, c->name); #endif } +#ifndef OPENSSL_NO_TLSEXT +#ifndef OPENSSL_NO_EC + if ( + /* if we are considering an ECC cipher suite that uses our certificate */ + (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) + /* and we have an ECC certificate */ + && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) + /* and the client specified a Supported Point Formats extension */ + && ((s->session->tlsext_ecpointformatlist_length > 0) && (s->session->tlsext_ecpointformatlist != NULL)) + /* and our certificate's point is compressed */ + && ( + (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL) + && ( + (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED) + || (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1) + ) + ) + ) + { + ec_ok = 0; + /* if our certificate's curve is over a field type that the client does not support + * then do not allow this cipher suite to be negotiated */ + if ( + (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL) + && (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field) + ) + { + for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) + { + if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime) + { + ec_ok = 1; + break; + } + } + } + else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field) + { + for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) + { + if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2) + { + ec_ok = 1; + break; + } + } + } + ok = ok && ec_ok; + } + if ( + /* if we are considering an ECC cipher suite that uses our certificate */ + (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) + /* and we have an ECC certificate */ + && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) + /* and the client specified an EllipticCurves extension */ + && ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL)) + ) + { + ec_ok = 0; + if ( + (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL) + ) + { + ec_nid = EC_GROUP_get_curve_name(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group); + if ((ec_nid == 0) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL) + ) + { + if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field) + { + ec_search1 = 0xFF; + ec_search2 = 0x01; + } + else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field) + { + ec_search1 = 0xFF; + ec_search2 = 0x02; + } + } + else + { + ec_search1 = 0x00; + ec_search2 = tls1_ec_nid2curve_id(ec_nid); + } + if ((ec_search1 != 0) || (ec_search2 != 0)) + { + for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++) + { + if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2)) + { + ec_ok = 1; + break; + } + } + } + } + ok = ok && ec_ok; + } + if ( + /* if we are considering an ECC cipher suite that uses an ephemeral EC key */ + (alg_k & SSL_kEECDH) + /* and we have an ephemeral EC key */ + && (s->cert->ecdh_tmp != NULL) + /* and the client specified an EllipticCurves extension */ + && ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL)) + ) + { + ec_ok = 0; + if (s->cert->ecdh_tmp->group != NULL) + { + ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group); + if ((ec_nid == 0) + && (s->cert->ecdh_tmp->group->meth != NULL) + ) + { + if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_prime_field) + { + ec_search1 = 0xFF; + ec_search2 = 0x01; + } + else if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_characteristic_two_field) + { + ec_search1 = 0xFF; + ec_search2 = 0x02; + } + } + else + { + ec_search1 = 0x00; + ec_search2 = tls1_ec_nid2curve_id(ec_nid); + } + if ((ec_search1 != 0) || (ec_search2 != 0)) + { + for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++) + { + if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2)) + { + ec_ok = 1; + break; + } + } + } + } + ok = ok && ec_ok; + } +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_TLSEXT */ + if (!ok) continue; - j=sk_SSL_CIPHER_find(allow,c); - if (j >= 0) + ii=sk_SSL_CIPHER_find(allow,c); + if (ii >= 0) { - ret=sk_SSL_CIPHER_value(allow,j); + ret=sk_SSL_CIPHER_value(allow,ii); break; } } @@ -2402,12 +3084,24 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, int ssl3_get_req_cert_type(SSL *s, unsigned char *p) { int ret=0; - unsigned long alg; + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg=s->s3->tmp.new_cipher->algorithms; +#ifndef OPENSSL_NO_GOST + if (s->version >= TLS1_VERSION) + { + if (alg_k & SSL_kGOST) + { + p[ret++]=TLS_CT_GOST94_SIGN; + p[ret++]=TLS_CT_GOST01_SIGN; + return(ret); + } + } +#endif #ifndef OPENSSL_NO_DH - if (alg & (SSL_kDHr|SSL_kEDH)) + if (alg_k & (SSL_kDHr|SSL_kEDH)) { # ifndef OPENSSL_NO_RSA p[ret++]=SSL3_CT_RSA_FIXED_DH; @@ -2417,7 +3111,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) # endif } if ((s->version == SSL3_VERSION) && - (alg & (SSL_kEDH|SSL_kDHd|SSL_kDHr))) + (alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr))) { # ifndef OPENSSL_NO_RSA p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH; @@ -2434,10 +3128,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) p[ret++]=SSL3_CT_DSS_SIGN; #endif #ifndef OPENSSL_NO_ECDH - /* We should ask for fixed ECDH certificates only - * for SSL_kECDH (and not SSL_kECDHE) - */ - if ((alg & SSL_kECDH) && (s->version >= TLS1_VERSION)) + if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION)) { p[ret++]=TLS_CT_RSA_FIXED_ECDH; p[ret++]=TLS_CT_ECDSA_FIXED_ECDH; @@ -2446,7 +3137,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) #ifndef OPENSSL_NO_ECDSA /* ECDSA certs can be used with RSA cipher suites as well - * so we don't need to check for SSL_kECDH or SSL_kECDHE + * so we don't need to check for SSL_kECDH or SSL_kEECDH */ if (s->version >= TLS1_VERSION) { diff --git a/crypto/openssl/ssl/s3_meth.c b/crypto/openssl/ssl/s3_meth.c index 6a6eb1c58f..cdddb17b62 100644 --- a/crypto/openssl/ssl/s3_meth.c +++ b/crypto/openssl/ssl/s3_meth.c @@ -60,8 +60,8 @@ #include #include "ssl_locl.h" -static SSL_METHOD *ssl3_get_method(int ver); -static SSL_METHOD *ssl3_get_method(int ver) +static const SSL_METHOD *ssl3_get_method(int ver); +static const SSL_METHOD *ssl3_get_method(int ver) { if (ver == SSL3_VERSION) return(SSLv3_method()); @@ -70,8 +70,8 @@ static SSL_METHOD *ssl3_get_method(int ver) } IMPLEMENT_ssl3_meth_func(SSLv3_method, - ssl3_accept, - ssl3_connect, - ssl3_get_method) + ssl3_accept, + ssl3_connect, + ssl3_get_method) diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c index a2ba5748d5..e3f6050a26 100644 --- a/crypto/openssl/ssl/s3_pkt.c +++ b/crypto/openssl/ssl/s3_pkt.c @@ -129,14 +129,49 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) * (If s->read_ahead is set, 'max' bytes may be stored in rbuf * [plus s->packet_length bytes if extend == 1].) */ - int i,off,newb; + int i,len,left; + long align=0; + unsigned char *pkt; + SSL3_BUFFER *rb; + + if (n <= 0) return n; + + rb = &(s->s3->rbuf); + if (rb->buf == NULL) + if (!ssl3_setup_read_buffer(s)) + return -1; + + left = rb->left; +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (long)rb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align)&(SSL3_ALIGN_PAYLOAD-1); +#endif if (!extend) { /* start with empty packet ... */ - if (s->s3->rbuf.left == 0) - s->s3->rbuf.offset = 0; - s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset; + 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; + } + } + s->packet = rb->buf + rb->offset; s->packet_length = 0; /* ... now we can act as if 'extend' was set */ } @@ -144,59 +179,63 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) /* For DTLS/UDP reads should not span multiple packets * because the read operation returns the whole packet * at once (as long as it fits into the buffer). */ - if (SSL_version(s) == DTLS1_VERSION) + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { - if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left) - n = s->s3->rbuf.left; + if (left > 0 && n > left) + n = left; } /* if there is enough in the buffer from a previous read, take some */ - if (s->s3->rbuf.left >= (int)n) + if (left >= n) { s->packet_length+=n; - s->s3->rbuf.left-=n; - s->s3->rbuf.offset+=n; + rb->left=left-n; + rb->offset+=n; return(n); } /* else we need to read more data */ - if (!s->read_ahead) - max=n; - { - /* avoid buffer overflow */ - int max_max = s->s3->rbuf.len - s->packet_length; - if (max > max_max) - max = max_max; - } - if (n > max) /* does not happen */ + 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)) /* does not happen */ { SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR); return -1; } - off = s->packet_length; - newb = s->s3->rbuf.left; - /* Move any available bytes to front of buffer: - * 'off' bytes already pointed to by 'packet', - * 'newb' extra ones at the end */ - if (s->packet != s->s3->rbuf.buf) + if (!s->read_ahead) + /* ignore max parameter */ + max = n; + else { - /* off > 0 */ - memmove(s->s3->rbuf.buf, s->packet, off+newb); - s->packet = s->s3->rbuf.buf; + if (max < n) + max = n; + if (max > (int)(rb->len - rb->offset)) + max = rb->len - rb->offset; } - while (newb < n) + while (left < n) { - /* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need - * to read in more until we have off+n (up to off+max if possible) */ + /* 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) */ clear_sys_error(); if (s->rbio != NULL) { s->rwstate=SSL_READING; - i=BIO_read(s->rbio, &(s->s3->rbuf.buf[off+newb]), max-newb); + i=BIO_read(s->rbio,pkt+len+left, max-left); } else { @@ -206,23 +245,26 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) if (i <= 0) { - s->s3->rbuf.left = newb; + rb->left = left; + if (s->mode & SSL_MODE_RELEASE_BUFFERS) + if (len+left == 0) + ssl3_release_read_buffer(s); return(i); } - newb+=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_version(s) == DTLS1_VERSION) + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { - if (n > newb) - n = newb; /* makes the while condition false */ + if (n > left) + n = left; /* makes the while condition false */ } } /* done reading, now the book-keeping */ - s->s3->rbuf.offset = off + n; - s->s3->rbuf.left = newb - n; + rb->offset += n; + rb->left = left - n; s->packet_length += n; s->rwstate=SSL_NOTHING; return(n); @@ -246,7 +288,7 @@ static int ssl3_get_record(SSL *s) unsigned char *p; unsigned char md[EVP_MAX_MD_SIZE]; short version; - unsigned int mac_size; + int mac_size; int clear=0; size_t extra; int decryption_failed_or_bad_record_mac = 0; @@ -259,9 +301,9 @@ static int ssl3_get_record(SSL *s) extra=SSL3_RT_MAX_EXTRA; else extra=0; - if (extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE) + if (extra && !s->s3->init_extra) { - /* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER + /* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER * set after ssl3_setup_buffers() was done */ SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); return -1; @@ -284,6 +326,9 @@ again: ssl_minor= *(p++); version=(ssl_major<<8)|ssl_minor; n2s(p,rr->length); +#if 0 +fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); +#endif /* Lets check version */ if (!s->first_packet) @@ -291,9 +336,9 @@ again: if (version != s->version) { SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); - /* Send back error using their - * version number :-) */ - s->version=version; + if ((s->version & 0xFF00) == (version & 0xFF00)) + /* Send back error using their minor version number :-) */ + s->version = (unsigned short)version; al=SSL_AD_PROTOCOL_VERSION; goto f_err; } @@ -305,7 +350,7 @@ again: goto err; } - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra) + if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG); @@ -378,12 +423,14 @@ printf("\n"); /* r->length is now the compressed data plus mac */ if ( (sess == NULL) || (s->enc_read_ctx == NULL) || - (s->read_hash == NULL)) + (EVP_MD_CTX_md(s->read_hash) == NULL)) clear=1; if (!clear) { - mac_size=EVP_MD_size(s->read_hash); + /* !clear => s->read_hash != NULL => mac_size != -1 */ + mac_size=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size >= 0); if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) { @@ -396,7 +443,7 @@ printf("\n"); #endif } /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length >= mac_size) + if (rr->length >= (unsigned int)mac_size) { rr->length -= mac_size; mac = &rr->data[rr->length]; @@ -414,7 +461,7 @@ printf("\n"); #endif } i=s->method->ssl3_enc->mac(s,md,0); - if (mac == NULL || memcmp(md, mac, mac_size) != 0) + if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0) { decryption_failed_or_bad_record_mac = 1; } @@ -471,6 +518,10 @@ printf("\n"); /* just read a 0 length packet */ if (rr->length == 0) goto again; +#if 0 +fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length); +#endif + return(1); f_err: @@ -544,8 +595,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) n=(len-tot); for (;;) { - if (n > SSL3_RT_MAX_PLAIN_LENGTH) - nw=SSL3_RT_MAX_PLAIN_LENGTH; + if (n > s->max_send_fragment) + nw=s->max_send_fragment; else nw=n; @@ -577,14 +628,19 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, { unsigned char *p,*plen; int i,mac_size,clear=0; - int prefix_len = 0; + int prefix_len=0; + long align=0; SSL3_RECORD *wr; - SSL3_BUFFER *wb; + SSL3_BUFFER *wb=&(s->s3->wbuf); SSL_SESSION *sess; + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ - if (s->s3->wbuf.left != 0) + if (wb->left != 0) return(ssl3_write_pending(s,type,buf,len)); /* If we have an alert to send, lets send it */ @@ -600,18 +656,21 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, return 0; wr= &(s->s3->wrec); - wb= &(s->s3->wbuf); sess=s->session; if ( (sess == NULL) || (s->enc_write_ctx == NULL) || - (s->write_hash == NULL)) + (EVP_MD_CTX_md(s->write_hash) == NULL)) clear=1; if (clear) mac_size=0; else - mac_size=EVP_MD_size(s->write_hash); + { + mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } /* 'create_empty_fragment' is true only when this function calls itself */ if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) @@ -629,7 +688,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (prefix_len <= 0) goto err; - if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) + if (prefix_len > + (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { /* insufficient space */ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); @@ -640,7 +700,32 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, s->s3->empty_fragment_done = 1; } - p = wb->buf + prefix_len; + if (create_empty_fragment) + { +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + /* extra fragment would be couple of cipher blocks, + * which would be multiple of SSL3_ALIGN_PAYLOAD, so + * if we want to align the real payload, then we can + * just pretent we simply have two headers. */ + align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH; + align = (-align)&(SSL3_ALIGN_PAYLOAD-1); +#endif + p = wb->buf + align; + wb->offset = align; + } + else if (prefix_len) + { + p = wb->buf + wb->offset + prefix_len; + } + else + { +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (long)wb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align)&(SSL3_ALIGN_PAYLOAD-1); +#endif + p = wb->buf + align; + wb->offset = align; + } /* write the header */ @@ -683,7 +768,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (mac_size != 0) { - s->method->ssl3_enc->mac(s,&(p[wr->length]),1); + if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0) + goto err; wr->length+=mac_size; wr->input=p; wr->data=p; @@ -711,7 +797,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* now let's set up wb */ wb->left = prefix_len + wr->length; - wb->offset = 0; /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ s->s3->wpend_tot=len; @@ -730,6 +815,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) { int i; + SSL3_BUFFER *wb=&(s->s3->wbuf); /* XXXX */ if ((s->s3->wpend_tot > (int)len) @@ -748,17 +834,20 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, { s->rwstate=SSL_WRITING; i=BIO_write(s->wbio, - (char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]), - (unsigned int)s->s3->wbuf.left); + (char *)&(wb->buf[wb->offset]), + (unsigned int)wb->left); } else { SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET); i= -1; } - if (i == s->s3->wbuf.left) + if (i == wb->left) { - s->s3->wbuf.left=0; + wb->left=0; + wb->offset+=i; + if (s->mode & SSL_MODE_RELEASE_BUFFERS) + ssl3_release_write_buffer(s); s->rwstate=SSL_NOTHING; return(s->s3->wpend_ret); } @@ -767,12 +856,12 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, s->version == DTLS1_BAD_VER) { /* For DTLS, just drop it. That's kind of the whole point in using a datagram service */ - s->s3->wbuf.left = 0; + wb->left = 0; } return(i); } - s->s3->wbuf.offset+=i; - s->s3->wbuf.left-=i; + wb->offset+=i; + wb->left-=i; } } @@ -811,7 +900,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) void (*cb)(const SSL *ssl,int type2,int val)=NULL; if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ - if (!ssl3_setup_buffers(s)) + if (!ssl3_setup_read_buffer(s)) return(-1); if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) || @@ -920,6 +1009,8 @@ start: { s->rstate=SSL_ST_READ_HEADER; rr->off=0; + if (s->mode & SSL_MODE_RELEASE_BUFFERS) + ssl3_release_read_buffer(s); } } return(n); @@ -1303,8 +1394,6 @@ int ssl3_do_change_cipher_spec(SSL *s) } s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, - &(s->s3->finish_dgst1), - &(s->s3->finish_dgst2), sender,slen,s->s3->tmp.peer_finish_md); return(1); diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c index e696450d65..92f73b6681 100644 --- a/crypto/openssl/ssl/s3_srvr.c +++ b/crypto/openssl/ssl/s3_srvr.c @@ -1,4 +1,4 @@ -/* ssl/s3_srvr.c */ +/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * 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 @@ -121,6 +121,32 @@ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #define REUSE_CIPHER_BUG #define NETSCAPE_HANG_BUG @@ -143,12 +169,9 @@ #endif #include -static SSL_METHOD *ssl3_get_server_method(int ver); -#ifndef OPENSSL_NO_ECDH -static int nid2curve_id(int nid); -#endif +static const SSL_METHOD *ssl3_get_server_method(int ver); -static SSL_METHOD *ssl3_get_server_method(int ver) +static const SSL_METHOD *ssl3_get_server_method(int ver) { if (ver == SSL3_VERSION) return(SSLv3_server_method()); @@ -164,7 +187,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_server_method, int ssl3_accept(SSL *s) { BUF_MEM *buf; - unsigned long l,Time=(unsigned long)time(NULL); + unsigned long alg_k,Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; @@ -292,6 +315,7 @@ int ssl3_accept(SSL *s) s->shutdown=0; ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; + s->new_session = 2; s->state=SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; @@ -320,9 +344,11 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or anon ECDH or KRB5 */ - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) + /* Check if it is anon DH or anon ECDH, */ + /* normal PSK or KRB5 */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) + && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) { ret=ssl3_send_server_certificate(s); if (ret <= 0) goto end; @@ -349,13 +375,13 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: - l=s->s3->tmp.new_cipher->algorithms; + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; /* clear this, it may get reset by * send_server_key_exchange */ if ((s->options & SSL_OP_EPHEMERAL_RSA) #ifndef OPENSSL_NO_KRB5 - && !(l & SSL_KRB5) + && !(alg_k & SSL_kKRB5) #endif /* OPENSSL_NO_KRB5 */ ) /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key @@ -370,16 +396,23 @@ int ssl3_accept(SSL *s) /* only send if a DH key exchange, fortezza or * RSA but we have a sign only certificate * + * PSK: may send PSK identity hints + * * For ECC ciphersuites, we send a serverKeyExchange * message only if the cipher suite is either * ECDH-anon or ECDHE. In other cases, the - * server certificate contains the server's + * server certificate contains the server's * public key for key exchange. */ if (s->s3->tmp.use_rsa_tmp - || (l & SSL_kECDHE) - || (l & (SSL_DH|SSL_kFZA)) - || ((l & SSL_kRSA) + /* PSK: send ServerKeyExchange if PSK identity + * hint if provided */ +#ifndef OPENSSL_NO_PSK + || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) +#endif + || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH)) + || (alg_k & SSL_kEECDH) + || ((alg_k & SSL_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) @@ -409,12 +442,15 @@ int ssl3_accept(SSL *s) /* never request cert in anonymous ciphersuites * (see section "Certificate request" in SSL 3 drafts * and in RFC 2246): */ - ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) && + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && /* ... except when the application insists on verification * (against the specs, but s3_clnt.c accepts this for SSL 3) */ !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* never request cert in Kerberos ciphersuites */ - (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) + /* never request cert in Kerberos ciphersuites */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) + /* With normal PSK Certificates and + * Certificate Requests are omitted */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { /* no cert request */ skip=1; @@ -490,7 +526,7 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_KEY_EXCH_A: case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); - if (ret <= 0) + if (ret <= 0) goto end; if (ret == 2) { @@ -498,24 +534,43 @@ int ssl3_accept(SSL *s) * the client sends its ECDH pub key in * a certificate, the CertificateVerify * message is not sent. + * Also for GOST ciphersuites when + * the client uses its key from the certificate + * for key exchange. */ s->state=SSL3_ST_SR_FINISHED_A; s->init_num = 0; } - else + else { + int offset=0; + int dgst_num; + s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; /* We need to get hashes here so if there is * a client cert, it can be verified - */ - s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst1), - &(s->s3->tmp.cert_verify_md[0])); - s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst2), - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); + * FIXME - digest processing for CertificateVerify + * should be generalized. But it is next step + */ + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return -1; + for (dgst_num=0; dgst_nums3->handshake_dgst[dgst_num]) + { + int dgst_size; + + s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset])); + dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); + if (dgst_size < 0) + { + ret = -1; + goto end; + } + offset+=dgst_size; + } } break; @@ -535,11 +590,14 @@ int ssl3_accept(SSL *s) ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; - if (s->hit) - s->state=SSL_ST_OK; #ifndef OPENSSL_NO_TLSEXT - else if (s->tlsext_ticket_expected) + if (s->tlsext_ticket_expected) s->state=SSL3_ST_SW_SESSION_TICKET_A; + else if (s->hit) + s->state=SSL_ST_OK; +#else + if (s->hit) + s->state=SSL_ST_OK; #endif else s->state=SSL3_ST_SW_CHANGE_A; @@ -769,7 +827,7 @@ int ssl3_get_client_hello(SSL *s) (s->version != DTLS1_VERSION && s->client_version < s->version)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); - if ((s->client_version>>8) == SSL3_VERSION_MAJOR) + if ((s->client_version>>8) == SSL3_VERSION_MAJOR) { /* similar to ssl3_get_record, send alert using remote version number */ s->version = s->client_version; @@ -990,13 +1048,110 @@ int ssl3_get_client_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; } + + /* Check if we want to use external pre-shared secret for this + * handshake for not reused session only. We need to generate + * server_random before calling tls_session_secret_cb in order to allow + * SessionTicket processing to use it in key derivation. */ + { + unsigned long Time; + unsigned char *pos; + Time=(unsigned long)time(NULL); /* Time */ + pos=s->s3->server_random; + l2n(Time,pos); + if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0) + { + al=SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + + if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) + { + SSL_CIPHER *pref_cipher=NULL; + + s->session->master_key_length=sizeof(s->session->master_key); + if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, + ciphers, &pref_cipher, s->tls_session_secret_cb_arg)) + { + s->hit=1; + s->session->ciphers=ciphers; + s->session->verify_result=X509_V_OK; + + ciphers=NULL; + + /* check if some cipher was preferred by call back */ + pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); + if (pref_cipher == NULL) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + + s->session->cipher=pref_cipher; + + if (s->cipher_list) + sk_SSL_CIPHER_free(s->cipher_list); + + if (s->cipher_list_by_id) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); + s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); + } + } #endif + /* Worst case, we will use the NULL compression, but if we have other * options, we will now look for them. We have i-1 compression * algorithms from the client, starting at q. */ s->s3->tmp.new_compression=NULL; #ifndef OPENSSL_NO_COMP - if (s->ctx->comp_methods != NULL) + /* This only happens if we have a cache hit */ + if (s->session->compress_meth != 0) + { + int m, comp_id = s->session->compress_meth; + /* Perform sanity checks on resumed compression algorithm */ + /* Can't disable compression */ + if (s->options & SSL_OP_NO_COMPRESSION) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } + /* Look for resumed compression method */ + for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) + { + comp=sk_SSL_COMP_value(s->ctx->comp_methods,m); + if (comp_id == comp->id) + { + s->s3->tmp.new_compression=comp; + break; + } + } + if (s->s3->tmp.new_compression == NULL) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM); + goto f_err; + } + /* Look for resumed method in compression list */ + for (m = 0; m < i; m++) + { + if (q[m] == comp_id) + break; + } + if (m >= i) + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); + goto f_err; + } + } + else if (s->hit) + comp = NULL; + else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) { /* See if we have a match */ int m,nn,o,v,done=0; @@ -1020,22 +1175,15 @@ int ssl3_get_client_hello(SSL *s) else comp=NULL; } -#endif - - /* TLS does not mind if there is extra stuff */ -#if 0 /* SSL 3.0 does not mind either, so we should disable this test - * (was enabled in 0.9.6d through 0.9.6j and 0.9.7 through 0.9.7b, - * in earlier SSLeay/OpenSSL releases this test existed but was buggy) */ - if (s->version == SSL3_VERSION) +#else + /* If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) { - if (p < (d+n)) - { - /* wrong number of bytes, - * there could be more to follow */ - al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); - goto f_err; - } + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; } #endif @@ -1084,7 +1232,7 @@ int ssl3_get_client_hello(SSL *s) for (i=0; ialgorithms & SSL_eNULL) + if (c->algorithm_enc & SSL_eNULL) nc=c; if (SSL_C_IS_EXPORT(c)) ec=c; @@ -1100,6 +1248,9 @@ int ssl3_get_client_hello(SSL *s) #endif s->s3->tmp.new_cipher=s->session->cipher; } + + if (!ssl3_digest_cached_records(s)) + goto f_err; /* we now have the following setup. * client_random @@ -1128,16 +1279,22 @@ int ssl3_send_server_hello(SSL *s) unsigned char *buf; unsigned char *p,*d; int i,sl; - unsigned long l,Time; + unsigned long l; +#ifdef OPENSSL_NO_TLSEXT + unsigned long Time; +#endif if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { buf=(unsigned char *)s->init_buf->data; +#ifdef OPENSSL_NO_TLSEXT p=s->s3->server_random; + /* Generate server_random if it was not needed previously */ Time=(unsigned long)time(NULL); /* Time */ l2n(Time,p); if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) return -1; +#endif /* Do the message type and length last */ d=p= &(buf[4]); @@ -1191,6 +1348,11 @@ int ssl3_send_server_hello(SSL *s) *(p++)=s->s3->tmp.new_compression->id; #endif #ifndef OPENSSL_NO_TLSEXT + if (ssl_prepare_serverhello_tlsext(s) <= 0) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT); + return -1; + } if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); @@ -1270,7 +1432,7 @@ int ssl3_send_server_key_exchange(SSL *s) EVP_MD_CTX_init(&md_ctx); if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; + type=s->s3->tmp.new_cipher->algorithm_mkey; cert=s->cert; buf=s->init_buf; @@ -1365,7 +1527,7 @@ int ssl3_send_server_key_exchange(SSL *s) else #endif #ifndef OPENSSL_NO_ECDH - if (type & SSL_kECDHE) + if (type & SSL_kEECDH) { const EC_GROUP *group; @@ -1435,7 +1597,7 @@ int ssl3_send_server_key_exchange(SSL *s) * supported named curves, curve_id is non-zero. */ if ((curve_id = - nid2curve_id(EC_GROUP_get_curve_name(group))) + tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) == 0) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); @@ -1492,6 +1654,14 @@ int ssl3_send_server_key_exchange(SSL *s) } else #endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) + { + /* reserve size for record length and PSK identity hint*/ + n+=2+strlen(s->ctx->psk_identity_hint); + } + else +#endif /* !OPENSSL_NO_PSK */ { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); @@ -1503,7 +1673,8 @@ int ssl3_send_server_key_exchange(SSL *s) n+=2+nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) == NULL) @@ -1535,7 +1706,7 @@ int ssl3_send_server_key_exchange(SSL *s) } #ifndef OPENSSL_NO_ECDH - if (type & SSL_kECDHE) + if (type & SSL_kEECDH) { /* XXX: For now, we only support named (not generic) curves. * In this situation, the serverKeyExchange message has: @@ -1559,6 +1730,16 @@ int ssl3_send_server_key_exchange(SSL *s) } #endif +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) + { + /* copy PSK identity hint */ + s2n(strlen(s->ctx->psk_identity_hint), p); + strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); + p+=strlen(s->ctx->psk_identity_hint); + } +#endif + /* not anonymous */ if (pkey != NULL) { @@ -1571,8 +1752,6 @@ int ssl3_send_server_key_exchange(SSL *s) j=0; for (num=2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); @@ -1756,7 +1935,7 @@ int ssl3_get_client_key_exchange(SSL *s) { int i,al,ok; long n; - unsigned long l; + unsigned long alg_k; unsigned char *p; #ifndef OPENSSL_NO_RSA RSA *rsa=NULL; @@ -1767,7 +1946,7 @@ int ssl3_get_client_key_exchange(SSL *s) DH *dh_srvr; #endif #ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; + KSSL_ERR kssl_err; #endif /* OPENSSL_NO_KRB5 */ #ifndef OPENSSL_NO_ECDH @@ -1787,10 +1966,10 @@ int ssl3_get_client_key_exchange(SSL *s) if (!ok) return((int)n); p=(unsigned char *)s->init_msg; - l=s->s3->tmp.new_cipher->algorithms; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; #ifndef OPENSSL_NO_RSA - if (l & SSL_kRSA) + if (alg_k & SSL_kRSA) { /* FIX THIS UP EAY EAY EAY EAY */ if (s->s3->tmp.use_rsa_tmp) @@ -1821,9 +2000,8 @@ int ssl3_get_client_key_exchange(SSL *s) rsa=pkey->pkey.rsa; } - /* TLS and [incidentally] DTLS, including pre-0.9.8f */ - if (s->version > SSL3_VERSION && - s->client_version != DTLS1_BAD_VER) + /* TLS and [incidentally] DTLS{0xFEFF} */ + if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { n2s(p,i); if (n != i+2) @@ -1897,7 +2075,7 @@ int ssl3_get_client_key_exchange(SSL *s) else #endif #ifndef OPENSSL_NO_DH - if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { n2s(p,i); if (n != i+2) @@ -1960,30 +2138,30 @@ int ssl3_get_client_key_exchange(SSL *s) else #endif #ifndef OPENSSL_NO_KRB5 - if (l & SSL_kKRB5) - { - krb5_error_code krb5rc; + if (alg_k & SSL_kKRB5) + { + krb5_error_code krb5rc; krb5_data enc_ticket; krb5_data authenticator; krb5_data enc_pms; - KSSL_CTX *kssl_ctx = s->kssl_ctx; + KSSL_CTX *kssl_ctx = s->kssl_ctx; EVP_CIPHER_CTX ciph_ctx; - EVP_CIPHER *enc = NULL; + const EVP_CIPHER *enc = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH - + EVP_MAX_BLOCK_LENGTH]; - int padl, outl; + + EVP_MAX_BLOCK_LENGTH]; + int padl, outl; krb5_timestamp authtime = 0; krb5_ticket_times ttimes; EVP_CIPHER_CTX_init(&ciph_ctx); - if (!kssl_ctx) kssl_ctx = kssl_ctx_new(); + if (!kssl_ctx) kssl_ctx = kssl_ctx_new(); n2s(p,i); enc_ticket.length = i; - if (n < (int)enc_ticket.length + 6) + if (n < (long)(enc_ticket.length + 6)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); @@ -1996,7 +2174,7 @@ int ssl3_get_client_key_exchange(SSL *s) n2s(p,i); authenticator.length = i; - if (n < (int)(enc_ticket.length + authenticator.length) + 6) + if (n < (long)(enc_ticket.length + authenticator.length + 6)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); @@ -2029,19 +2207,19 @@ int ssl3_get_client_key_exchange(SSL *s) goto err; } - if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, + if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, &kssl_err)) != 0) - { + { #ifdef KSSL_DEBUG - printf("kssl_sget_tkt rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - printf("kssl_err text= %s\n", kssl_err.text); + printf("kssl_sget_tkt rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + printf("kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - kssl_err.reason); - goto err; - } + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + kssl_err.reason); + goto err; + } /* Note: no authenticator is not considered an error, ** but will return authtime == 0. @@ -2050,29 +2228,29 @@ int ssl3_get_client_key_exchange(SSL *s) &authtime, &kssl_err)) != 0) { #ifdef KSSL_DEBUG - printf("kssl_check_authent rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - printf("kssl_err text= %s\n", kssl_err.text); + printf("kssl_check_authent rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + printf("kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - kssl_err.reason); - goto err; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + kssl_err.reason); + goto err; } if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); - goto err; + goto err; } #ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); + kssl_ctx_show(kssl_ctx); #endif /* KSSL_DEBUG */ enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; + if (enc == NULL) + goto err; memset(iv, 0, sizeof iv); /* per RFC 1510 */ @@ -2119,7 +2297,7 @@ int ssl3_get_client_key_exchange(SSL *s) * (Perhaps we should have a separate BUG value for the Kerberos cipher) */ if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) - { + { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_AD_DECODE_ERROR); goto err; @@ -2128,32 +2306,32 @@ int ssl3_get_client_key_exchange(SSL *s) EVP_CIPHER_CTX_cleanup(&ciph_ctx); - s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, - s->session->master_key, pms, outl); + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, pms, outl); - if (kssl_ctx->client_princ) - { - size_t len = strlen(kssl_ctx->client_princ); - if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) - { - s->session->krb5_client_princ_len = len; - memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len); - } - } + if (kssl_ctx->client_princ) + { + size_t len = strlen(kssl_ctx->client_princ); + if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) + { + s->session->krb5_client_princ_len = len; + memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len); + } + } - /* Was doing kssl_ctx_free() here, + /* Was doing kssl_ctx_free() here, ** but it caused problems for apache. - ** kssl_ctx = kssl_ctx_free(kssl_ctx); - ** if (s->kssl_ctx) s->kssl_ctx = NULL; - */ - } + ** kssl_ctx = kssl_ctx_free(kssl_ctx); + ** if (s->kssl_ctx) s->kssl_ctx = NULL; + */ + } else #endif /* OPENSSL_NO_KRB5 */ #ifndef OPENSSL_NO_ECDH - if ((l & SSL_kECDH) || (l & SSL_kECDHE)) + if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) { int ret = 1; int field_size = 0; @@ -2161,18 +2339,18 @@ int ssl3_get_client_key_exchange(SSL *s) const EC_GROUP *group; const BIGNUM *priv_key; - /* initialize structures for server's ECDH key pair */ + /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; + goto err; } /* Let's get server private key and group information */ - if (l & SSL_kECDH) + if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { - /* use the certificate */ + /* use the certificate */ tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec; } else @@ -2202,20 +2380,20 @@ int ssl3_get_client_key_exchange(SSL *s) goto err; } - if (n == 0L) - { + if (n == 0L) + { /* Client Publickey was in Client Certificate */ - if (l & SSL_kECDHE) + if (alg_k & SSL_kEECDH) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY); goto f_err; } - if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer)) + if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer)) == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) - { + { /* XXX: For now, we do not support client * authentication using ECDH certificates * so this branch (n == 0L) of the code is @@ -2227,11 +2405,11 @@ int ssl3_get_client_key_exchange(SSL *s) * the two ECDH shares are for the same * group. */ - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); - goto f_err; - } + goto f_err; + } if (EC_POINT_copy(clnt_ecpoint, EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0) @@ -2240,10 +2418,10 @@ int ssl3_get_client_key_exchange(SSL *s) ERR_R_EC_LIB); goto err; } - ret = 2; /* Skip certificate verify processing */ - } - else - { + ret = 2; /* Skip certificate verify processing */ + } + else + { /* Get client's public key from encoded point * in the ClientKeyExchange message. */ @@ -2254,21 +2432,21 @@ int ssl3_get_client_key_exchange(SSL *s) goto err; } - /* Get encoded point length */ - i = *p; + /* Get encoded point length */ + i = *p; p += 1; - if (EC_POINT_oct2point(group, + if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - /* p is pointing to somewhere in the buffer - * currently, so set it to the start - */ - p=(unsigned char *)s->init_buf->data; - } + /* p is pointing to somewhere in the buffer + * currently, so set it to the start + */ + p=(unsigned char *)s->init_buf->data; + } /* Compute the shared pre-master secret */ field_size = EC_GROUP_get_degree(group); @@ -2279,28 +2457,190 @@ int ssl3_get_client_key_exchange(SSL *s) goto err; } i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL); - if (i <= 0) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + if (i <= 0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } + goto err; + } EVP_PKEY_free(clnt_pub_pkey); EC_POINT_free(clnt_ecpoint); - if (srvr_ecdh != NULL) - EC_KEY_free(srvr_ecdh); + EC_KEY_free(srvr_ecdh); BN_CTX_free(bn_ctx); + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; /* Compute the master secret */ - s->session->master_key_length = s->method->ssl3_enc-> \ + s->session->master_key_length = s->method->ssl3_enc-> \ generate_master_secret(s, s->session->master_key, p, i); - OPENSSL_cleanse(p, i); - return (ret); + OPENSSL_cleanse(p, i); + return (ret); } else #endif +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) + { + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + char tmp_id[PSK_MAX_IDENTITY_LEN+1]; + + al=SSL_AD_HANDSHAKE_FAILURE; + + n2s(p,i); + if (n != i+2) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto psk_err; + } + if (i > PSK_MAX_IDENTITY_LEN) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto psk_err; + } + if (s->psk_server_callback == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_SERVER_CB); + goto psk_err; + } + + /* Create guaranteed NULL-terminated identity + * string for the callback */ + memcpy(tmp_id, p, i); + memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); + psk_len = s->psk_server_callback(s, tmp_id, + psk_or_pre_ms, sizeof(psk_or_pre_ms)); + OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); + + if (psk_len > PSK_MAX_PSK_LEN) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + else if (psk_len == 0) + { + /* PSK related to the given identity not found */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al=SSL_AD_UNKNOWN_PSK_IDENTITY; + goto psk_err; + } + + /* create PSK pre_master_secret */ + pre_ms_len=2+psk_len+2+psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t+=psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup((char *)p); + if (s->session->psk_identity == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL && + s->session->psk_identity_hint == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, psk_or_pre_ms, pre_ms_len); + psk_err = 0; + psk_err: + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) + goto f_err; + } + else +#endif + if (alg_k & SSL_kGOST) + { + int ret = 0; + EVP_PKEY_CTX *pkey_ctx; + EVP_PKEY *client_pub_pkey = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen=32, inlen; + + /* Get our certificate private key*/ + pkey_ctx = EVP_PKEY_CTX_new(s->cert->key->privatekey,NULL); + EVP_PKEY_decrypt_init(pkey_ctx); + /* If client certificate is present and is of the same type, maybe + * use it for key exchange. Don't mind errors from + * EVP_PKEY_derive_set_peer, because it is completely valid to use + * a client certificate for authorization only. */ + client_pub_pkey = X509_get_pubkey(s->session->peer); + if (client_pub_pkey) + { + if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) + ERR_clear_error(); + } + /* Decrypt session key */ + if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + if (p[1] == 0x81) + { + start = p+3; + inlen = p[2]; + } + else if (p[1] < 0x80) + { + start = p+2; + inlen = p[1]; + } + else + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) + + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + /* Generate master secret */ + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key,premaster_secret,32); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + ret = 2; + else + ret = 1; + gerr: + EVP_PKEY_free(client_pub_pkey); + EVP_PKEY_CTX_free(pkey_ctx); + if (ret) + return ret; + else + goto err; + } + else { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, @@ -2390,15 +2730,25 @@ int ssl3_get_cert_verify(SSL *s) /* we now have a signature that we need to verify */ p=(unsigned char *)s->init_msg; - n2s(p,i); - n-=2; - if (i > n) + /* Check for broken implementations of GOST ciphersuites */ + /* If key is GOST and n is exactly 64, it is bare + * signature without length field */ + if (n==64 && (pkey->type==NID_id_GostR3410_94 || + pkey->type == NID_id_GostR3410_2001) ) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH); - al=SSL_AD_DECODE_ERROR; - goto f_err; - } - + i=64; + } + else + { + n2s(p,i); + n-=2; + if (i > n) + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH); + al=SSL_AD_DECODE_ERROR; + goto f_err; + } + } j=EVP_PKEY_size(pkey); if ((i > j) || (n > j) || (n <= 0)) { @@ -2461,6 +2811,28 @@ int ssl3_get_cert_verify(SSL *s) } else #endif + if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) + { unsigned char signature[64]; + int idx; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey,NULL); + EVP_PKEY_verify_init(pctx); + if (i!=64) { + fprintf(stderr,"GOST signature length is %d",i); + } + for (idx=0;idx<64;idx++) { + signature[63-idx]=p[idx]; + } + j=EVP_PKEY_verify(pctx,signature,64,s->s3->tmp.cert_verify_md,32); + EVP_PKEY_CTX_free(pctx); + if (j<=0) + { + al=SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_ECDSA_SIGNATURE); + goto f_err; + } + } + else { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR); al=SSL_AD_UNSUPPORTED_CERTIFICATE; @@ -2643,14 +3015,15 @@ int ssl3_send_server_certificate(SSL *s) if (s->state == SSL3_ST_SW_CERT_A) { x=ssl_get_server_send_cert(s); - if (x == NULL && - /* VRS: allow null cert if auth == KRB5 */ - (s->s3->tmp.new_cipher->algorithms - & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - != (SSL_aKRB5|SSL_kKRB5)) + if (x == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); - return(0); + /* VRS: allow null cert if auth == KRB5 */ + if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || + (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); + return(0); + } } l=ssl3_output_cert_chain(s,x); @@ -2662,70 +3035,6 @@ int ssl3_send_server_certificate(SSL *s) /* SSL3_ST_SW_CERT_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } - - -#ifndef OPENSSL_NO_ECDH -/* This is the complement of curve_id2nid in s3_clnt.c. */ -static int nid2curve_id(int nid) -{ - /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) - * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */ - switch (nid) { - case NID_sect163k1: /* sect163k1 (1) */ - return 1; - case NID_sect163r1: /* sect163r1 (2) */ - return 2; - case NID_sect163r2: /* sect163r2 (3) */ - return 3; - case NID_sect193r1: /* sect193r1 (4) */ - return 4; - case NID_sect193r2: /* sect193r2 (5) */ - return 5; - case NID_sect233k1: /* sect233k1 (6) */ - return 6; - case NID_sect233r1: /* sect233r1 (7) */ - return 7; - case NID_sect239k1: /* sect239k1 (8) */ - return 8; - case NID_sect283k1: /* sect283k1 (9) */ - return 9; - case NID_sect283r1: /* sect283r1 (10) */ - return 10; - case NID_sect409k1: /* sect409k1 (11) */ - return 11; - case NID_sect409r1: /* sect409r1 (12) */ - return 12; - case NID_sect571k1: /* sect571k1 (13) */ - return 13; - case NID_sect571r1: /* sect571r1 (14) */ - return 14; - case NID_secp160k1: /* secp160k1 (15) */ - return 15; - case NID_secp160r1: /* secp160r1 (16) */ - return 16; - case NID_secp160r2: /* secp160r2 (17) */ - return 17; - case NID_secp192k1: /* secp192k1 (18) */ - return 18; - case NID_X9_62_prime192v1: /* secp192r1 (19) */ - return 19; - case NID_secp224k1: /* secp224k1 (20) */ - return 20; - case NID_secp224r1: /* secp224r1 (21) */ - return 21; - case NID_secp256k1: /* secp256k1 (22) */ - return 22; - case NID_X9_62_prime256v1: /* secp256r1 (23) */ - return 23; - case NID_secp384r1: /* secp384r1 (24) */ - return 24; - case NID_secp521r1: /* secp521r1 (25) */ - return 25; - default: - return 0; - } -} -#endif #ifndef OPENSSL_NO_TLSEXT int ssl3_send_newsession_ticket(SSL *s) { diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h index 7d4e46e916..e4c3f65010 100644 --- a/crypto/openssl/ssl/ssl.h +++ b/crypto/openssl/ssl/ssl.h @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * 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 @@ -109,62 +109,35 @@ * */ /* ==================================================================== - * Copyright (c) 1998-2006 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. + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. * - * 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. + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. * - * 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/)" + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. * - * 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. + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. * - * 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. + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. * - * 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ #ifndef HEADER_SSL_H @@ -248,56 +221,88 @@ extern "C" { #define SSL_MAX_KEY_ARG_LENGTH 8 #define SSL_MAX_MASTER_KEY_LENGTH 48 + /* These are used to specify which ciphers to use and not to use */ + +#define SSL_TXT_EXP40 "EXPORT40" +#define SSL_TXT_EXP56 "EXPORT56" #define SSL_TXT_LOW "LOW" #define SSL_TXT_MEDIUM "MEDIUM" #define SSL_TXT_HIGH "HIGH" #define SSL_TXT_FIPS "FIPS" -#define SSL_TXT_kFZA "kFZA" -#define SSL_TXT_aFZA "aFZA" -#define SSL_TXT_eFZA "eFZA" -#define SSL_TXT_FZA "FZA" + +#define SSL_TXT_kFZA "kFZA" /* unused! */ +#define SSL_TXT_aFZA "aFZA" /* unused! */ +#define SSL_TXT_eFZA "eFZA" /* unused! */ +#define SSL_TXT_FZA "FZA" /* unused! */ #define SSL_TXT_aNULL "aNULL" #define SSL_TXT_eNULL "eNULL" #define SSL_TXT_NULL "NULL" -#define SSL_TXT_kKRB5 "kKRB5" -#define SSL_TXT_aKRB5 "aKRB5" -#define SSL_TXT_KRB5 "KRB5" - #define SSL_TXT_kRSA "kRSA" -#define SSL_TXT_kDHr "kDHr" -#define SSL_TXT_kDHd "kDHd" +#define SSL_TXT_kDHr "kDHr" /* no such ciphersuites supported! */ +#define SSL_TXT_kDHd "kDHd" /* no such ciphersuites supported! */ +#define SSL_TXT_kDH "kDH" /* no such ciphersuites supported! */ #define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kKRB5 "kKRB5" +#define SSL_TXT_kECDHr "kECDHr" +#define SSL_TXT_kECDHe "kECDHe" +#define SSL_TXT_kECDH "kECDH" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_kGOST "kGOST" + #define SSL_TXT_aRSA "aRSA" #define SSL_TXT_aDSS "aDSS" -#define SSL_TXT_aDH "aDH" +#define SSL_TXT_aDH "aDH" /* no such ciphersuites supported! */ +#define SSL_TXT_aECDH "aECDH" +#define SSL_TXT_aKRB5 "aKRB5" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_aGOST94 "aGOST94" +#define SSL_TXT_aGOST01 "aGOST01" +#define SSL_TXT_aGOST "aGOST" + #define SSL_TXT_DSS "DSS" #define SSL_TXT_DH "DH" -#define SSL_TXT_EDH "EDH" +#define SSL_TXT_EDH "EDH" /* same as "kEDH:-ADH" */ #define SSL_TXT_ADH "ADH" #define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_EECDH "EECDH" /* same as "kEECDH:-AECDH" */ +#define SSL_TXT_AECDH "AECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_KRB5 "KRB5" +#define SSL_TXT_PSK "PSK" + #define SSL_TXT_DES "DES" #define SSL_TXT_3DES "3DES" #define SSL_TXT_RC4 "RC4" #define SSL_TXT_RC2 "RC2" #define SSL_TXT_IDEA "IDEA" #define SSL_TXT_SEED "SEED" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" #define SSL_TXT_AES "AES" +#define SSL_TXT_CAMELLIA128 "CAMELLIA128" +#define SSL_TXT_CAMELLIA256 "CAMELLIA256" #define SSL_TXT_CAMELLIA "CAMELLIA" + #define SSL_TXT_MD5 "MD5" #define SSL_TXT_SHA1 "SHA1" -#define SSL_TXT_SHA "SHA" -#define SSL_TXT_EXP "EXP" -#define SSL_TXT_EXPORT "EXPORT" -#define SSL_TXT_EXP40 "EXPORT40" -#define SSL_TXT_EXP56 "EXPORT56" +#define SSL_TXT_SHA "SHA" /* same as "SHA1" */ +#define SSL_TXT_GOST94 "GOST94" +#define SSL_TXT_GOST89MAC "GOST89MAC" + #define SSL_TXT_SSLV2 "SSLv2" #define SSL_TXT_SSLV3 "SSLv3" #define SSL_TXT_TLSV1 "TLSv1" + +#define SSL_TXT_EXP "EXP" +#define SSL_TXT_EXPORT "EXPORT" + #define SSL_TXT_ALL "ALL" -#define SSL_TXT_ECC "ECCdraft" /* ECC ciphersuites are not yet official */ /* * COMPLEMENTOF* definitions. These identifiers are used to (de-select) @@ -319,7 +324,13 @@ extern "C" { /* The following cipher list is used by default. * It also is substituted when an application-defined cipher list string * starts with 'DEFAULT'. */ -#define SSL_DEFAULT_CIPHER_LIST "AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" /* low priority for RC4 */ +#define SSL_DEFAULT_CIPHER_LIST "ALL:!aNULL:!eNULL:!SSLv2" +/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! + * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable + * some of them.) + */ /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ #define SSL_SENT_SHUTDOWN 1 @@ -344,6 +355,7 @@ extern "C" { * 'struct ssl_st *' function parameters used to prototype callbacks * in SSL_CTX. */ typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; /* used to hold info on the particular ciphers used */ typedef struct ssl_cipher_st @@ -351,17 +363,25 @@ typedef struct ssl_cipher_st int valid; const char *name; /* text name */ unsigned long id; /* id, 4 bytes, first is version */ - unsigned long algorithms; /* what ciphers are used */ + + /* changed in 0.9.9: these four used to be portions of a single value 'algorithms' */ + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + unsigned long algo_strength; /* strength and export flags */ unsigned long algorithm2; /* Extra flags */ int strength_bits; /* Number of bits really used */ int alg_bits; /* Number of bits for algorithm */ - unsigned long mask; /* used for matching */ - unsigned long mask_strength; /* also used for matching */ } SSL_CIPHER; DECLARE_STACK_OF(SSL_CIPHER) +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); + /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ typedef struct ssl_method_st { @@ -385,12 +405,12 @@ typedef struct ssl_method_st 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); - SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr); + const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr); int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr); int (*ssl_pending)(const SSL *s); int (*num_ciphers)(void); - SSL_CIPHER *(*get_cipher)(unsigned ncipher); - struct ssl_method_st *(*get_ssl_method)(int version); + const SSL_CIPHER *(*get_cipher)(unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method)(int version); long (*get_timeout)(void); struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ int (*ssl_version)(void); @@ -402,17 +422,20 @@ typedef struct ssl_method_st * SSL_SESSION_ID ::= SEQUENCE { * version INTEGER, -- structure version number * SSLversion INTEGER, -- SSL version number - * Cipher OCTET_STRING, -- the 3 byte cipher ID - * Session_ID OCTET_STRING, -- the Session ID - * Master_key OCTET_STRING, -- the master key - * KRB5_principal OCTET_STRING -- optional Kerberos principal - * Key_Arg [ 0 ] IMPLICIT OCTET_STRING, -- the optional Key argument + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate - * Session_ID_context [ 4 ] EXPLICIT OCTET_STRING, -- the Session ID context - * Verify_result [ 5 ] EXPLICIT INTEGER -- X509_V_... code for `Peer' - * Compression [6] IMPLICIT ASN1_OBJECT -- compression OID XXXXX + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * ECPointFormatList [ 7 ] OCTET STRING, -- optional EC point format list from TLS extension + * PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity * } * Look in ssl/ssl_asn1.c for more details * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). @@ -440,7 +463,10 @@ typedef struct ssl_session_st unsigned int krb5_client_princ_len; unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; #endif /* OPENSSL_NO_KRB5 */ - +#ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + char *psk_identity; +#endif int not_resumable; /* The cert is the certificate used to establish this connection */ @@ -459,9 +485,9 @@ typedef struct ssl_session_st long timeout; long time; - int compress_meth; /* Need to lookup the method */ + unsigned int compress_meth; /* Need to lookup the method */ - SSL_CIPHER *cipher; + const SSL_CIPHER *cipher; unsigned long cipher_id; /* when ASN.1 loaded, this * needs to be used to load * the 'cipher' structure */ @@ -475,6 +501,12 @@ typedef struct ssl_session_st struct ssl_session_st *prev,*next; #ifndef OPENSSL_NO_TLSEXT char *tlsext_hostname; +#ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* peer's list */ +#endif /* OPENSSL_NO_EC */ /* RFC4507 info */ unsigned char *tlsext_tick; /* Session ticket */ size_t tlsext_ticklen; /* Session ticket length */ @@ -504,7 +536,7 @@ typedef struct ssl_session_st /* SSL_OP_ALL: various bug workarounds that should be rather harmless. * This used to be 0x000FFFFFL before 0.9.7. */ -#define SSL_OP_ALL 0x00000FFFL +#define SSL_OP_ALL 0x80000FFFL /* DTLS options */ #define SSL_OP_NO_QUERY_MTU 0x00001000L @@ -517,6 +549,8 @@ typedef struct ssl_session_st /* As server, disallow session resumption on renegotiation */ #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* Don't use compression even if supported */ +#define SSL_OP_NO_COMPRESSION 0x00020000L /* Permit unsafe legacy renegotiation */ #define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L /* If set, always create a new key when using tmp_ecdh parameters */ @@ -545,7 +579,11 @@ typedef struct ssl_session_st #define SSL_OP_PKCS1_CHECK_2 0x10000000L #define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L - +/* Make server add server-hello extension from early version of + * cryptopro draft, when GOST ciphersuite is negotiated. + * Required for interoperability with CryptoPro CSP 3.x + */ +#define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L /* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success * when just a single record has been written): */ @@ -560,7 +598,10 @@ typedef struct ssl_session_st #define SSL_MODE_AUTO_RETRY 0x00000004L /* Don't attempt to automatically build certificate chain */ #define SSL_MODE_NO_AUTO_CHAIN 0x00000008L - +/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context + * or just freed (depending on the context's setting for freelist_max_len). */ +#define SSL_MODE_RELEASE_BUFFERS 0x00000010L /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, * they cannot be used to clear bits. */ @@ -639,17 +680,18 @@ typedef struct ssl_comp_st } SSL_COMP; DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); struct ssl_ctx_st { - SSL_METHOD *method; + const SSL_METHOD *method; STACK_OF(SSL_CIPHER) *cipher_list; /* same as above but sorted for lookup */ STACK_OF(SSL_CIPHER) *cipher_list_by_id; struct x509_store_st /* X509_STORE */ *cert_store; - struct lhash_st /* LHASH */ *sessions; /* a set of SSL_SESSIONs */ + LHASH_OF(SSL_SESSION) *sessions; /* Most session-ids that will be cached, default is * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */ unsigned long session_cache_size; @@ -774,6 +816,12 @@ struct ssl_ctx_st int quiet_shutdown; + /* Maximum amount of data to send in one fragment. + * actual record size can be more than this due to + * padding and MAC overheads. + */ + unsigned int max_send_fragment; + #ifndef OPENSSL_ENGINE /* Engine to pass requests for client certs to */ @@ -792,14 +840,33 @@ struct ssl_ctx_st int (*tlsext_ticket_key_cb)(SSL *ssl, unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, - HMAC_CTX *hctx, int enc); + HMAC_CTX *hctx, int enc); /* certificate status request info */ /* Callback for status request */ int (*tlsext_status_cb)(SSL *ssl, void *arg); void *tlsext_status_arg; + + /* draft-rescorla-tls-opaque-prf-input-00.txt information */ + int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg); + void *tlsext_opaque_prf_input_callback_arg; +#endif + +#ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len); #endif +#ifndef OPENSSL_NO_BUF_FREELISTS +#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 + unsigned int freelist_max_len; + struct ssl3_buf_freelist_st *wbuf_freelist; + struct ssl3_buf_freelist_st *rbuf_freelist; +#endif }; #define SSL_SESS_CACHE_OFF 0x0000 @@ -813,7 +880,7 @@ struct ssl_ctx_st #define SSL_SESS_CACHE_NO_INTERNAL \ (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) - struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx); +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); #define SSL_CTX_sess_number(ctx) \ SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) #define SSL_CTX_sess_connect(ctx) \ @@ -855,6 +922,31 @@ int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)); void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)); +#ifndef OPENSSL_NO_PSK +/* 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 +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, unsigned char *psk, + unsigned int max_psk_len)); +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, unsigned char *psk, + unsigned int max_psk_len)); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len)); +void SSL_set_psk_server_callback(SSL *ssl, + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len)); +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +#endif + #define SSL_NOTHING 1 #define SSL_WRITING 2 #define SSL_READING 3 @@ -866,6 +958,9 @@ void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL #define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) #define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) +#define SSL_MAC_FLAG_READ_MAC_STREAM 1 +#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + struct ssl_st { /* protocol version @@ -874,7 +969,7 @@ struct ssl_st int version; int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ - SSL_METHOD *method; /* SSLv3 */ + const SSL_METHOD *method; /* SSLv3 */ /* There are 2 BIO's even though they are normally both the * same. This is so data can be read and written to different @@ -957,9 +1052,9 @@ struct ssl_st /* These are the ones being used, the ones in SSL_SESSION are * the ones to be 'copied' into these ones */ - + int mac_flags; EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ - const EVP_MD *read_hash; /* used for mac generation */ + EVP_MD_CTX *read_hash; /* used for mac generation */ #ifndef OPENSSL_NO_COMP COMP_CTX *expand; /* uncompress */ #else @@ -967,7 +1062,7 @@ struct ssl_st #endif EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - const EVP_MD *write_hash; /* used for mac generation */ + EVP_MD_CTX *write_hash; /* used for mac generation */ #ifndef OPENSSL_NO_COMP COMP_CTX *compress; /* compression */ #else @@ -1005,6 +1100,14 @@ struct ssl_st KSSL_CTX *kssl_ctx; /* Kerberos 5 context */ #endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len); +#endif + SSL_CTX *ctx; /* set this flag to 1 and a sleep(1) is put into all SSL_read() * and SSL_write() calls, good for nbio debuging :-) */ @@ -1024,6 +1127,7 @@ struct ssl_st int first_packet; int client_version; /* what was passed, used for * SSLv3/TLS rollback check */ + unsigned int max_send_fragment; #ifndef OPENSSL_NO_TLSEXT /* TLS extension debug callback */ void (*tlsext_debug_cb)(SSL *s, int client_server, int type, @@ -1050,11 +1154,33 @@ struct ssl_st /* RFC4507 session ticket expected to be received or sent */ int tlsext_ticket_expected; +#ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* our list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* our list */ +#endif /* OPENSSL_NO_EC */ + + /* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */ + void *tlsext_opaque_prf_input; + size_t tlsext_opaque_prf_input_len; + + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ #define session_ctx initial_ctx #else #define session_ctx ctx -#endif +#endif /* OPENSSL_NO_TLSEXT */ }; #ifdef __cplusplus @@ -1161,20 +1287,13 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); #define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) #define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) -#if 1 /*SSLEAY_MACROS*/ #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) -#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \ - (char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u) -#define PEM_read_bio_SSL_SESSION(bp,x,cb,u) PEM_ASN1_read_bio_of(SSL_SESSION,d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,cb,u) -#define PEM_write_SSL_SESSION(fp,x) \ - PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \ - PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL) -#define PEM_write_bio_SSL_SESSION(bp,x) \ - PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL) -#endif -#define SSL_AD_REASON_OFFSET 1000 +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +#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 */ @@ -1204,6 +1323,8 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); #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_ERROR_NONE 0 #define SSL_ERROR_SSL 1 @@ -1262,6 +1383,8 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); #define SSL_CTRL_GET_MAX_CERT_LIST 50 #define SSL_CTRL_SET_MAX_CERT_LIST 51 +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 + /* see tls1.h for macros based on these */ #ifndef OPENSSL_NO_TLSEXT #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 @@ -1271,7 +1394,9 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); #define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 #define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 #define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 - +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 @@ -1341,7 +1466,7 @@ void BIO_ssl_shutdown(BIO *ssl_bio); #endif int SSL_CTX_set_cipher_list(SSL_CTX *,const char *str); -SSL_CTX *SSL_CTX_new(SSL_METHOD *meth); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); void SSL_CTX_free(SSL_CTX *); long SSL_CTX_set_timeout(SSL_CTX *ctx,long t); long SSL_CTX_get_timeout(const SSL_CTX *ctx); @@ -1352,7 +1477,7 @@ int SSL_clear(SSL *s); void SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm); -SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits); char * SSL_CIPHER_get_version(const SSL_CIPHER *c); const char * SSL_CIPHER_get_name(const SSL_CIPHER *c); @@ -1423,9 +1548,8 @@ long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); void SSL_copy_session_id(SSL *to,const SSL *from); SSL_SESSION *SSL_SESSION_new(void); -unsigned long SSL_SESSION_hash(const SSL_SESSION *a); -int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b); -const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); #ifndef OPENSSL_NO_FP_API int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses); #endif @@ -1485,6 +1609,9 @@ int SSL_set_purpose(SSL *s, int purpose); int SSL_CTX_set_trust(SSL_CTX *s, int trust); int SSL_set_trust(SSL *s, int trust); +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + void SSL_free(SSL *ssl); int SSL_accept(SSL *ssl); int SSL_connect(SSL *ssl); @@ -1500,27 +1627,29 @@ int SSL_get_error(const SSL *s,int ret_code); const char *SSL_get_version(const SSL *s); /* This sets the 'default' SSL version that SSL_new() will create */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth); +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); -SSL_METHOD *SSLv2_method(void); /* SSLv2 */ -SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ -SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ +#ifndef OPENSSL_NO_SSL2 +const SSL_METHOD *SSLv2_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ +#endif -SSL_METHOD *SSLv3_method(void); /* SSLv3 */ -SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ -SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ -SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */ -SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */ -SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */ +const SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */ +const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */ +const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */ -SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ -SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ -SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ -SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ -SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ -SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); @@ -1529,8 +1658,8 @@ int SSL_renegotiate(SSL *s); int SSL_renegotiate_pending(SSL *s); int SSL_shutdown(SSL *s); -SSL_METHOD *SSL_get_ssl_method(SSL *s); -int SSL_set_ssl_method(SSL *s,SSL_METHOD *method); +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); const char *SSL_alert_type_string_long(int value); const char *SSL_alert_type_string(int value); const char *SSL_alert_desc_string_long(int value); @@ -1622,6 +1751,11 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void ); #define SSL_set_max_cert_list(ssl,m) \ SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +#define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +#define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + /* NB: the keylength is only applicable when is_export is true */ #ifndef OPENSSL_NO_RSA void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, @@ -1663,6 +1797,15 @@ void *SSL_COMP_get_compression_methods(void); int SSL_COMP_add_compression_method(int id,void *cm); #endif +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -1680,7 +1823,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_DO_DTLS1_WRITE 245 #define SSL_F_DO_SSL3_WRITE 104 #define SSL_F_DTLS1_ACCEPT 246 -#define SSL_F_DTLS1_ADD_CERT_TO_BUF 280 +#define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 #define SSL_F_DTLS1_BUFFER_RECORD 247 #define SSL_F_DTLS1_CLIENT_HELLO 248 #define SSL_F_DTLS1_CONNECT 249 @@ -1689,9 +1832,9 @@ void ERR_load_SSL_strings(void); #define SSL_F_DTLS1_GET_MESSAGE 252 #define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 #define SSL_F_DTLS1_GET_RECORD 254 -#define SSL_F_DTLS1_HANDLE_TIMEOUT 282 +#define SSL_F_DTLS1_HANDLE_TIMEOUT 297 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 -#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277 +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 #define SSL_F_DTLS1_PROCESS_RECORD 257 #define SSL_F_DTLS1_READ_BYTES 258 @@ -1735,7 +1878,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL2_SET_CERTIFICATE 126 #define SSL_F_SSL2_WRITE 127 #define SSL_F_SSL3_ACCEPT 128 -#define SSL_F_SSL3_ADD_CERT_TO_BUF 281 +#define SSL_F_SSL3_ADD_CERT_TO_BUF 296 #define SSL_F_SSL3_CALLBACK_CTRL 233 #define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 @@ -1743,11 +1886,12 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_CONNECT 132 #define SSL_F_SSL3_CTRL 213 #define SSL_F_SSL3_CTX_CTRL 133 -#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 279 +#define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 #define SSL_F_SSL3_ENC 134 #define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 -#define SSL_F_SSL3_GET_CERT_STATUS 288 +#define SSL_F_SSL3_GET_CERT_STATUS 289 #define SSL_F_SSL3_GET_CERT_VERIFY 136 #define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 #define SSL_F_SSL3_GET_CLIENT_HELLO 138 @@ -1760,7 +1904,8 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 #define SSL_F_SSL3_GET_SERVER_DONE 145 #define SSL_F_SSL3_GET_SERVER_HELLO 146 -#define SSL_F_SSL3_NEW_SESSION_TICKET 284 +#define SSL_F_SSL3_HANDSHAKE_MAC 285 +#define SSL_F_SSL3_NEW_SESSION_TICKET 287 #define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 #define SSL_F_SSL3_PEEK 235 #define SSL_F_SSL3_READ_BYTES 148 @@ -1772,16 +1917,17 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 #define SSL_F_SSL3_SEND_SERVER_HELLO 242 #define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 -#define SSL_F_SSL3_SETUP_BUFFERS 156 #define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +#define SSL_F_SSL3_SETUP_READ_BUFFER 156 +#define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 #define SSL_F_SSL3_WRITE_BYTES 158 #define SSL_F_SSL3_WRITE_PENDING 159 -#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 285 -#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 272 +#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 -#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 286 -#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 273 +#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 #define SSL_F_SSL_BAD_METHOD 160 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 #define SSL_F_SSL_CERT_DUP 221 @@ -1789,7 +1935,8 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_CERT_INSTANTIATE 214 #define SSL_F_SSL_CERT_NEW 162 #define SSL_F_SSL_CHECK_PRIVATE_KEY 163 -#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 274 +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 #define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 #define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 #define SSL_F_SSL_CLEAR 164 @@ -1799,7 +1946,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 #define SSL_F_SSL_CTX_NEW 169 #define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 -#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 278 +#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 #define SSL_F_SSL_CTX_SET_PURPOSE 226 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 #define SSL_F_SSL_CTX_SET_SSL_VERSION 170 @@ -1811,6 +1958,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 #define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 #define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 @@ -1822,13 +1970,13 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_INIT_WBIO_BUFFER 184 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 #define SSL_F_SSL_NEW 186 -#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 287 -#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 290 -#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 289 -#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 291 +#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 #define SSL_F_SSL_PEEK 270 -#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 275 -#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 276 +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 #define SSL_F_SSL_READ 223 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 @@ -1843,6 +1991,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_SET_RFD 194 #define SSL_F_SSL_SET_SESSION 195 #define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +#define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 #define SSL_F_SSL_SET_TRUST 228 #define SSL_F_SSL_SET_WFD 196 #define SSL_F_SSL_SHUTDOWN 224 @@ -1855,13 +2004,19 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_USE_PRIVATEKEY 201 #define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 #define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +#define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 #define SSL_F_SSL_USE_RSAPRIVATEKEY 204 #define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 #define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 #define SSL_F_SSL_VERIFY_CERT_CHAIN 207 #define SSL_F_SSL_WRITE 208 +#define SSL_F_TLS1_CERT_VERIFY_MAC 286 #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 #define SSL_F_TLS1_ENC 210 +#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +#define SSL_F_TLS1_PRF 284 #define SSL_F_TLS1_SETUP_KEY_BLOCK 211 #define SSL_F_WRITE_PENDING 212 @@ -1882,12 +2037,15 @@ void ERR_load_SSL_strings(void); #define SSL_R_BAD_ECC_CERT 304 #define SSL_R_BAD_ECDSA_SIGNATURE 305 #define SSL_R_BAD_ECPOINT 306 +#define SSL_R_BAD_HANDSHAKE_LENGTH 332 #define SSL_R_BAD_HELLO_REQUEST 105 #define SSL_R_BAD_LENGTH 271 #define SSL_R_BAD_MAC_DECODE 113 +#define SSL_R_BAD_MAC_LENGTH 333 #define SSL_R_BAD_MESSAGE_TYPE 114 #define SSL_R_BAD_PACKET_LENGTH 115 #define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 #define SSL_R_BAD_RESPONSE_ARGUMENT 117 #define SSL_R_BAD_RSA_DECRYPT 118 #define SSL_R_BAD_RSA_ENCRYPT 119 @@ -1911,8 +2069,9 @@ void ERR_load_SSL_strings(void); #define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 #define SSL_R_CIPHER_TABLE_SRC_ERROR 139 -#define SSL_R_CLIENTHELLO_TLSEXT 157 +#define SSL_R_CLIENTHELLO_TLSEXT 226 #define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +#define SSL_R_COMPRESSION_DISABLED 343 #define SSL_R_COMPRESSION_FAILURE 141 #define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 #define SSL_R_COMPRESSION_LIBRARY_ERROR 142 @@ -1925,8 +2084,12 @@ void ERR_load_SSL_strings(void); #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 #define SSL_R_DIGEST_CHECK_FAILED 149 -#define SSL_R_DTLS_MESSAGE_TOO_BIG 318 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 334 #define SSL_R_DUPLICATE_COMPRESSION_ID 309 +#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 #define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 #define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 @@ -1937,11 +2100,13 @@ void ERR_load_SSL_strings(void); #define SSL_R_HTTPS_PROXY_REQUEST 155 #define SSL_R_HTTP_REQUEST 156 #define SSL_R_ILLEGAL_PADDING 283 +#define SSL_R_INCONSISTENT_COMPRESSION 340 #define SSL_R_INVALID_CHALLENGE_LENGTH 158 #define SSL_R_INVALID_COMMAND 280 +#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 #define SSL_R_INVALID_PURPOSE 278 -#define SSL_R_INVALID_STATUS_RESPONSE 316 -#define SSL_R_INVALID_TICKET_KEYS_LENGTH 275 +#define SSL_R_INVALID_STATUS_RESPONSE 328 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 #define SSL_R_INVALID_TRUST 279 #define SSL_R_KEY_ARG_TOO_LONG 284 #define SSL_R_KRB5 285 @@ -1985,23 +2150,27 @@ void ERR_load_SSL_strings(void); #define SSL_R_NO_CIPHERS_SPECIFIED 183 #define SSL_R_NO_CIPHER_LIST 184 #define SSL_R_NO_CIPHER_MATCH 185 -#define SSL_R_NO_CLIENT_CERT_METHOD 317 +#define SSL_R_NO_CLIENT_CERT_METHOD 331 #define SSL_R_NO_CLIENT_CERT_RECEIVED 186 #define SSL_R_NO_COMPRESSION_SPECIFIED 187 +#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 #define SSL_R_NO_METHOD_SPECIFIED 188 #define SSL_R_NO_PRIVATEKEY 189 #define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 #define SSL_R_NO_PROTOCOLS_AVAILABLE 191 #define SSL_R_NO_PUBLICKEY 192 -#define SSL_R_NO_RENEGOTIATION 319 +#define SSL_R_NO_RENEGOTIATION 339 +#define SSL_R_NO_REQUIRED_DIGEST 324 #define SSL_R_NO_SHARED_CIPHER 193 #define SSL_R_NO_VERIFY_CALLBACK 194 #define SSL_R_NULL_SSL_CTX 195 #define SSL_R_NULL_SSL_METHOD_PASSED 196 #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +#define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 #define SSL_R_PACKET_LENGTH_TOO_LONG 198 -#define SSL_R_PARSE_TLSEXT 223 +#define SSL_R_PARSE_TLSEXT 227 #define SSL_R_PATH_TOO_LONG 270 #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 #define SSL_R_PEER_ERROR 200 @@ -2012,6 +2181,9 @@ void ERR_load_SSL_strings(void); #define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 #define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 #define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +#define SSL_R_PSK_NO_CLIENT_CB 224 +#define SSL_R_PSK_NO_SERVER_CB 225 #define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 #define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 #define SSL_R_PUBLIC_KEY_NOT_RSA 210 @@ -2021,22 +2193,24 @@ void ERR_load_SSL_strings(void); #define SSL_R_RECORD_LENGTH_MISMATCH 213 #define SSL_R_RECORD_TOO_LARGE 214 #define SSL_R_RECORD_TOO_SMALL 298 -#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 320 -#define SSL_R_RENEGOTIATION_ENCODING_ERR 321 -#define SSL_R_RENEGOTIATION_MISMATCH 322 +#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +#define SSL_R_RENEGOTIATION_MISMATCH 337 #define SSL_R_REQUIRED_CIPHER_MISSING 215 +#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 -#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 324 -#define SSL_R_SERVERHELLO_TLSEXT 224 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +#define SSL_R_SERVERHELLO_TLSEXT 275 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 #define SSL_R_SHORT_READ 219 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 -#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 225 -#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 226 +#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 #define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 #define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 @@ -2070,8 +2244,13 @@ void ERR_load_SSL_strings(void); #define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 #define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 #define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 -#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 227 +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 #define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 #define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 @@ -2098,9 +2277,10 @@ void ERR_load_SSL_strings(void); #define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 #define SSL_R_UNKNOWN_SSL_VERSION 254 #define SSL_R_UNKNOWN_STATE 255 -#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 323 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 #define SSL_R_UNSUPPORTED_CIPHER 256 #define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +#define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 #define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 #define SSL_R_UNSUPPORTED_PROTOCOL 258 #define SSL_R_UNSUPPORTED_SSL_VERSION 259 diff --git a/crypto/openssl/ssl/ssl3.h b/crypto/openssl/ssl/ssl3.h index 2f579c253b..baaa89e717 100644 --- a/crypto/openssl/ssl/ssl3.h +++ b/crypto/openssl/ssl/ssl3.h @@ -123,7 +123,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { @@ -163,12 +162,14 @@ extern "C" { #define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A #define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B -#define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C -#define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D -#if 0 /* Because it clashes with KRB5, is never used any more, and is safe - to remove according to David Hopwood - of the ietf-tls list */ -#define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E +#if 0 + #define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C + #define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D + #if 0 /* Because it clashes with KRB5, is never used any more, and is safe + to remove according to David Hopwood + of the ietf-tls list */ + #define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E + #endif #endif /* VRS Additional Kerberos5 entries @@ -220,9 +221,11 @@ extern "C" { #define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" #define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" -#define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" -#define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" -#define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +#if 0 + #define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" + #define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" + #define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +#endif #define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" #define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" @@ -248,23 +251,65 @@ extern "C" { #define SSL3_SESSION_ID_SIZE 32 #define SSL3_RT_HEADER_LENGTH 5 -/* Due to MS stuffing up, this can change.... */ -#if defined(OPENSSL_SYS_WIN16) || \ - (defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)) -#define SSL3_RT_MAX_EXTRA (14000) +#ifndef SSL3_ALIGN_PAYLOAD + /* Some will argue that this increases memory footprint, but it's + * not actually true. Point is that malloc has to return at least + * 64-bit aligned pointers, meaning that allocating 5 bytes wastes + * 3 bytes in either case. Suggested pre-gaping simply moves these + * wasted bytes from the end of allocated region to its front, + * but makes data payload aligned, which improves performance:-) */ +# define SSL3_ALIGN_PAYLOAD 8 #else -#define SSL3_RT_MAX_EXTRA (16384) +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif #endif +/* This is the maximum MAC (digest) size used by the SSL library. + * Currently maximum of 20 is used by SHA1, but we reserve for + * future extension for 512-bit hashes. + */ + +#define SSL3_RT_MAX_MD_SIZE 64 + +/* Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +#define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +#define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ #define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* The standards give a maximum encryption overhead of 1024 bytes. + * In practice the value is lower than this. The overhead is the maximum + * number of padding bytes (256) plus the mac size. + */ +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* OpenSSL currently only uses a padding length of at most one block so + * the send overhead is smaller. + */ + +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + #ifdef OPENSSL_NO_COMP -#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH #else -#define SSL3_RT_MAX_COMPRESSED_LENGTH (1024+SSL3_RT_MAX_PLAIN_LENGTH) +#define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) #endif -#define SSL3_RT_MAX_ENCRYPTED_LENGTH (1024+SSL3_RT_MAX_COMPRESSED_LENGTH) -#define SSL3_RT_MAX_PACKET_SIZE (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) -#define SSL3_RT_MAX_DATA_SIZE (1024*1024) +#define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +#define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) #define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" #define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" @@ -303,7 +348,7 @@ typedef struct ssl3_record_st /*rw*/ unsigned char *input; /* where the decode bytes are */ /*r */ unsigned char *comp; /* only used with decompression - malloc()ed */ /*r */ unsigned long epoch; /* epoch number, needed by DTLS1 */ -/*r */ PQ_64BIT seq_num; /* sequence number, needed by DTLS1 */ +/*r */ unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */ } SSL3_RECORD; typedef struct ssl3_buffer_st @@ -326,13 +371,14 @@ typedef struct ssl3_buffer_st * enough to contain all of the cert types defined either for * SSLv3 and TLSv1. */ -#define SSL3_CT_NUMBER 7 +#define SSL3_CT_NUMBER 9 #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 #define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 #define SSL3_FLAGS_POP_BUFFER 0x0004 #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 typedef struct ssl3_state_st { @@ -340,8 +386,10 @@ typedef struct ssl3_state_st int delay_buf_pop_ret; unsigned char read_sequence[8]; + int read_mac_secret_size; unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; unsigned char write_sequence[8]; + int write_mac_secret_size; unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; unsigned char server_random[SSL3_RANDOM_SIZE]; @@ -351,6 +399,9 @@ typedef struct ssl3_state_st int need_empty_fragments; int empty_fragment_done; + /* The value of 'extra' when the buffers were initialized */ + int init_extra; + SSL3_BUFFER rbuf; /* read IO goes into here */ SSL3_BUFFER wbuf; /* write IO goes into here */ @@ -372,9 +423,11 @@ typedef struct ssl3_state_st const unsigned char *wpend_buf; /* used during startup, digest all incoming/outgoing packets */ - EVP_MD_CTX finish_dgst1; - EVP_MD_CTX finish_dgst2; - + 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; /* this is set whenerver we see a change_cipher_spec message * come in when we are not looking for one */ int change_cipher_spec; @@ -394,6 +447,14 @@ typedef struct ssl3_state_st int in_read_app_data; + /* Opaque PRF input as used for the current handshake. + * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined + * (otherwise, they are merely present to improve binary compatibility) */ + void *client_opaque_prf_input; + size_t client_opaque_prf_input_len; + void *server_opaque_prf_input; + size_t server_opaque_prf_input_len; + struct { /* actually only needs to be 16+20 */ unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2]; @@ -408,7 +469,7 @@ typedef struct ssl3_state_st int message_type; /* used to hold the new cipher we are going to use */ - SSL_CIPHER *new_cipher; + const SSL_CIPHER *new_cipher; #ifndef OPENSSL_NO_DH DH *dh; #endif @@ -435,6 +496,8 @@ typedef struct ssl3_state_st const EVP_CIPHER *new_sym_enc; const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; #ifndef OPENSSL_NO_COMP const SSL_COMP *new_compression; #else diff --git a/crypto/openssl/ssl/ssl_algs.c b/crypto/openssl/ssl/ssl_algs.c index 2d9077e303..0967b2dfe4 100644 --- a/crypto/openssl/ssl/ssl_algs.c +++ b/crypto/openssl/ssl/ssl_algs.c @@ -76,13 +76,16 @@ int SSL_library_init(void) #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_cbc()); + /* Not actually used for SSL/TLS but this makes PKCS#12 work + * if an application only calls SSL_library_init(). + */ + EVP_add_cipher(EVP_rc2_40_cbc()); #endif #ifndef OPENSSL_NO_AES EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_256_cbc()); #endif - #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); @@ -91,7 +94,7 @@ int SSL_library_init(void) #ifndef OPENSSL_NO_SEED EVP_add_cipher(EVP_seed_cbc()); #endif - + #ifndef OPENSSL_NO_MD5 EVP_add_digest(EVP_md5()); EVP_add_digest_alias(SN_md5,"ssl2-md5"); @@ -102,6 +105,14 @@ int SSL_library_init(void) EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); #endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2); diff --git a/crypto/openssl/ssl/ssl_asn1.c b/crypto/openssl/ssl/ssl_asn1.c index d82e47a14e..28709978b5 100644 --- a/crypto/openssl/ssl/ssl_asn1.c +++ b/crypto/openssl/ssl/ssl_asn1.c @@ -55,6 +55,32 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include @@ -84,12 +110,16 @@ typedef struct ssl_session_asn1_st ASN1_INTEGER tlsext_tick_lifetime; ASN1_OCTET_STRING tlsext_tick; #endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + ASN1_OCTET_STRING psk_identity_hint; + ASN1_OCTET_STRING psk_identity; +#endif /* OPENSSL_NO_PSK */ } SSL_SESSION_ASN1; int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) { #define LSIZE2 (sizeof(long)*2) - int v1=0,v2=0,v3=0,v4=0,v5=0; + int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0; unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2]; unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2]; #ifndef OPENSSL_NO_TLSEXT @@ -97,8 +127,8 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) unsigned char ibuf6[LSIZE2]; #endif #ifndef OPENSSL_NO_COMP - int v11=0; unsigned char cbuf; + int v11=0; #endif long l; SSL_SESSION_ASN1 a; @@ -177,7 +207,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) a.krb5_princ.data=in->krb5_client_princ; } #endif /* OPENSSL_NO_KRB5 */ - + if (in->time != 0L) { a.time.length=LSIZE2; @@ -223,6 +253,21 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint); } #endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + { + a.psk_identity_hint.length=strlen(in->psk_identity_hint); + a.psk_identity_hint.type=V_ASN1_OCTET_STRING; + a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint); + } + if (in->psk_identity) + { + a.psk_identity.length=strlen(in->psk_identity); + a.psk_identity.type=V_ASN1_OCTET_STRING; + a.psk_identity.data=(unsigned char *)(in->psk_identity); + } +#endif /* OPENSSL_NO_PSK */ + M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); @@ -256,6 +301,13 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11); #endif #endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7); + if (in->psk_identity) + M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); +#endif /* OPENSSL_NO_PSK */ + M_ASN1_I2D_seq_total(); M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); @@ -282,6 +334,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) #ifndef OPENSSL_NO_TLSEXT if (in->tlsext_hostname) M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7); + if (in->psk_identity) + M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_TLSEXT if (in->tlsext_tick_lifetime_hint > 0) M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); if (in->tlsext_tick) @@ -295,7 +355,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) } SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - long length) + long length) { int version,ssl_version=0,i; long id; @@ -475,6 +535,24 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, } else ret->tlsext_hostname=NULL; +#endif /* OPENSSL_NO_TLSEXT */ + +#ifndef OPENSSL_NO_PSK + os.length=0; + os.data=NULL; + M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7); + if (os.data) + { + ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } + else + ret->psk_identity_hint=NULL; +#endif /* OPENSSL_NO_PSK */ + +#ifndef OPENSSL_NO_TLSEXT ai.length=0; M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9); if (ai.data != NULL) @@ -485,17 +563,17 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, else if (ret->tlsext_ticklen && ret->session_id_length) ret->tlsext_tick_lifetime_hint = -1; else - ret->tlsext_tick_lifetime_hint = 0; - os.length=0; - os.data=NULL; - M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10); - if (os.data) - { + ret->tlsext_tick_lifetime_hint=0; + os.length=0; + os.data=NULL; + M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10); + if (os.data) + { ret->tlsext_tick = os.data; ret->tlsext_ticklen = os.length; - os.data = NULL; - os.length = 0; - } + os.data = NULL; + os.length = 0; + } else ret->tlsext_tick=NULL; #endif /* OPENSSL_NO_TLSEXT */ diff --git a/crypto/openssl/ssl/ssl_cert.c b/crypto/openssl/ssl/ssl_cert.c index 16fda5d8bf..27256eea81 100644 --- a/crypto/openssl/ssl/ssl_cert.c +++ b/crypto/openssl/ssl/ssl_cert.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * 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 @@ -197,8 +197,10 @@ CERT *ssl_cert_dup(CERT *cert) * if you find that more readable */ ret->valid = cert->valid; - ret->mask = cert->mask; - ret->export_mask = cert->export_mask; + ret->mask_k = cert->mask_k; + ret->mask_a = cert->mask_a; + ret->export_mask_k = cert->export_mask_k; + ret->export_mask_a = cert->export_mask_a; #ifndef OPENSSL_NO_RSA if (cert->rsa_tmp != NULL) @@ -753,6 +755,8 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, sk_X509_NAME_push(stack,xn); } + ERR_clear_error(); + if (0) { err: diff --git a/crypto/openssl/ssl/ssl_ciph.c b/crypto/openssl/ssl/ssl_ciph.c index 5e2d436da3..bee3507ea1 100644 --- a/crypto/openssl/ssl/ssl_ciph.c +++ b/crypto/openssl/ssl/ssl_ciph.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * 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 @@ -113,12 +113,41 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + #include #include #ifndef OPENSSL_NO_COMP #include #endif - +#ifndef OPENSSL_NO_ENGINE +#include +#endif #include "ssl_locl.h" #define SSL_ENC_DES_IDX 0 @@ -126,18 +155,18 @@ #define SSL_ENC_RC4_IDX 2 #define SSL_ENC_RC2_IDX 3 #define SSL_ENC_IDEA_IDX 4 -#define SSL_ENC_eFZA_IDX 5 -#define SSL_ENC_NULL_IDX 6 -#define SSL_ENC_AES128_IDX 7 -#define SSL_ENC_AES256_IDX 8 -#define SSL_ENC_CAMELLIA128_IDX 9 -#define SSL_ENC_CAMELLIA256_IDX 10 +#define SSL_ENC_NULL_IDX 5 +#define SSL_ENC_AES128_IDX 6 +#define SSL_ENC_AES256_IDX 7 +#define SSL_ENC_CAMELLIA128_IDX 8 +#define SSL_ENC_CAMELLIA256_IDX 9 +#define SSL_ENC_GOST89_IDX 10 #define SSL_ENC_SEED_IDX 11 #define SSL_ENC_NUM_IDX 12 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ - NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, }; #define SSL_COMP_NULL_IDX 0 @@ -148,9 +177,30 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; #define SSL_MD_MD5_IDX 0 #define SSL_MD_SHA1_IDX 1 -#define SSL_MD_NUM_IDX 2 +#define SSL_MD_GOST94_IDX 2 +#define SSL_MD_GOST89MAC_IDX 3 +/*Constant SSL_MAX_DIGEST equal to size of digests array should be + * defined in the + * ssl_locl.h */ +#define SSL_MD_NUM_IDX SSL_MAX_DIGEST static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ - NULL,NULL, + NULL,NULL,NULL,NULL + }; +/* PKEY_TYPE for GOST89MAC is known in advance, but, because + * implementation is engine-provided, we'll fill it only if + * corresponding EVP_PKEY_METHOD is found + */ +static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={ + EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef + }; + +static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ + 0,0,0,0 + }; + +static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={ + SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA, + SSL_HANDSHAKE_MAC_GOST94,0 }; #define CIPHER_ADD 1 @@ -161,72 +211,144 @@ static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ typedef struct cipher_order_st { - SSL_CIPHER *cipher; + const SSL_CIPHER *cipher; int active; int dead; struct cipher_order_st *next,*prev; } CIPHER_ORDER; static const SSL_CIPHER cipher_aliases[]={ - /* Don't include eNULL unless specifically enabled. */ - /* Don't include ECC in ALL because these ciphers are not yet official. */ - {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL & ~SSL_kECDH & ~SSL_kECDHE, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */ - /* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */ - {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, /* COMPLEMENT OF ALL */ - {0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0}, - {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0}, /* VRS Kerberos5 */ - {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_ECC, 0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0}, - {0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0}, - {0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0}, /* VRS Kerberos5 */ - {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0}, - {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0}, - {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0}, - {0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0}, - {0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0}, - {0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0}, - - {0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0}, -#ifndef OPENSSL_NO_IDEA - {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0}, -#endif - {0,SSL_TXT_SEED,0,SSL_SEED, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_CAMELLIA,0,SSL_CAMELLIA, 0,0,0,0,SSL_ENC_MASK,0}, - - {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0}, - {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0}, - {0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0}, - - {0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_KRB5,0,SSL_KRB5, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, - {0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, - {0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, - {0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0}, - - {0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0}, - {0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0}, - {0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0}, - - {0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, - {0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, - {0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK}, - {0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK}, - {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK}, - {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK}, - {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK}, - {0,SSL_TXT_FIPS, 0, 0, SSL_FIPS, 0,0,0,0,SSL_FIPS|SSL_STRONG_NONE}, + /* "ALL" doesn't include eNULL (must be specifically enabled) */ + {0,SSL_TXT_ALL,0, 0,0,~SSL_eNULL,0,0,0,0,0,0}, + /* "COMPLEMENTOFALL" */ + {0,SSL_TXT_CMPALL,0, 0,0,SSL_eNULL,0,0,0,0,0,0}, + + /* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in ALL!) */ + {0,SSL_TXT_CMPDEF,0, SSL_kEDH|SSL_kEECDH,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0}, + + /* key exchange aliases + * (some of those using only a single bit here combine + * multiple key exchange algs according to the RFCs, + * e.g. kEDH combines DHE_DSS and DHE_RSA) */ + {0,SSL_TXT_kRSA,0, SSL_kRSA, 0,0,0,0,0,0,0,0}, + + {0,SSL_TXT_kDHr,0, SSL_kDHr, 0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ + {0,SSL_TXT_kDHd,0, SSL_kDHd, 0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ + {0,SSL_TXT_kDH,0, SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ + {0,SSL_TXT_kEDH,0, SSL_kEDH, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_DH,0, SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0}, + + {0,SSL_TXT_kKRB5,0, SSL_kKRB5, 0,0,0,0,0,0,0,0}, + + {0,SSL_TXT_kECDHr,0, SSL_kECDHr,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kECDHe,0, SSL_kECDHe,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kECDH,0, SSL_kECDHr|SSL_kECDHe,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kEECDH,0, SSL_kEECDH,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0}, + + {0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0}, + + /* server authentication aliases */ + {0,SSL_TXT_aRSA,0, 0,SSL_aRSA, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aDSS,0, 0,SSL_aDSS, 0,0,0,0,0,0,0}, + {0,SSL_TXT_DSS,0, 0,SSL_aDSS, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aKRB5,0, 0,SSL_aKRB5, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aNULL,0, 0,SSL_aNULL, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aDH,0, 0,SSL_aDH, 0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ + {0,SSL_TXT_aECDH,0, 0,SSL_aECDH, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aECDSA,0, 0,SSL_aECDSA,0,0,0,0,0,0,0}, + {0,SSL_TXT_ECDSA,0, 0,SSL_aECDSA, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aPSK,0, 0,SSL_aPSK, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0}, + {0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0}, + {0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0}, + + /* aliases combining key exchange and server authentication */ + {0,SSL_TXT_EDH,0, SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_EECDH,0, SSL_kEECDH,~SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_NULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0}, + {0,SSL_TXT_KRB5,0, SSL_kKRB5,SSL_aKRB5,0,0,0,0,0,0,0}, + {0,SSL_TXT_RSA,0, SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0}, + {0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0}, + + + /* symmetric encryption aliases */ + {0,SSL_TXT_DES,0, 0,0,SSL_DES, 0,0,0,0,0,0}, + {0,SSL_TXT_3DES,0, 0,0,SSL_3DES, 0,0,0,0,0,0}, + {0,SSL_TXT_RC4,0, 0,0,SSL_RC4, 0,0,0,0,0,0}, + {0,SSL_TXT_RC2,0, 0,0,SSL_RC2, 0,0,0,0,0,0}, + {0,SSL_TXT_IDEA,0, 0,0,SSL_IDEA, 0,0,0,0,0,0}, + {0,SSL_TXT_SEED,0, 0,0,SSL_SEED, 0,0,0,0,0,0}, + {0,SSL_TXT_eNULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0}, + {0,SSL_TXT_AES128,0, 0,0,SSL_AES128,0,0,0,0,0,0}, + {0,SSL_TXT_AES256,0, 0,0,SSL_AES256,0,0,0,0,0,0}, + {0,SSL_TXT_AES,0, 0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0}, + {0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0}, + {0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0}, + {0,SSL_TXT_CAMELLIA ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0}, + + /* MAC aliases */ + {0,SSL_TXT_MD5,0, 0,0,0,SSL_MD5, 0,0,0,0,0}, + {0,SSL_TXT_SHA1,0, 0,0,0,SSL_SHA1, 0,0,0,0,0}, + {0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0}, + {0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0}, + {0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0}, + + /* protocol version aliases */ + {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0}, + {0,SSL_TXT_SSLV3,0, 0,0,0,0,SSL_SSLV3, 0,0,0,0}, + {0,SSL_TXT_TLSV1,0, 0,0,0,0,SSL_TLSV1, 0,0,0,0}, + + /* export flag */ + {0,SSL_TXT_EXP,0, 0,0,0,0,0,SSL_EXPORT,0,0,0}, + {0,SSL_TXT_EXPORT,0, 0,0,0,0,0,SSL_EXPORT,0,0,0}, + + /* strength classes */ + {0,SSL_TXT_EXP40,0, 0,0,0,0,0,SSL_EXP40, 0,0,0}, + {0,SSL_TXT_EXP56,0, 0,0,0,0,0,SSL_EXP56, 0,0,0}, + {0,SSL_TXT_LOW,0, 0,0,0,0,0,SSL_LOW, 0,0,0}, + {0,SSL_TXT_MEDIUM,0, 0,0,0,0,0,SSL_MEDIUM,0,0,0}, + {0,SSL_TXT_HIGH,0, 0,0,0,0,0,SSL_HIGH, 0,0,0}, + /* FIPS 140-2 approved ciphersuite */ + {0,SSL_TXT_FIPS,0, 0,0,~SSL_eNULL,0,0,SSL_FIPS, 0,0,0}, }; +/* Search for public key algorithm with given name and + * return its pkey_id if it is available. Otherwise return 0 + */ +#ifdef OPENSSL_NO_ENGINE + +static int get_optional_pkey_id(const char *pkey_name) + { + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id=0; + ameth = EVP_PKEY_asn1_find_str(NULL,pkey_name,-1); + if (ameth) + { + EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth); + } + return pkey_id; + } + +#else + +static int get_optional_pkey_id(const char *pkey_name) + { + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng = NULL; + int pkey_id=0; + ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1); + if (ameth) + { + EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth); + } + if (tmpeng) ENGINE_finish(tmpeng); + return pkey_id; + } + +#endif void ssl_load_ciphers(void) { @@ -252,16 +374,37 @@ void ssl_load_ciphers(void) EVP_get_cipherbyname(SN_camellia_128_cbc); ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]= EVP_get_cipherbyname(SN_camellia_256_cbc); + ssl_cipher_methods[SSL_ENC_GOST89_IDX]= + EVP_get_cipherbyname(SN_gost89_cnt); ssl_cipher_methods[SSL_ENC_SEED_IDX]= EVP_get_cipherbyname(SN_seed_cbc); ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_get_digestbyname(SN_md5); + ssl_mac_secret_size[SSL_MD_MD5_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); ssl_digest_methods[SSL_MD_SHA1_IDX]= EVP_get_digestbyname(SN_sha1); - } - + ssl_mac_secret_size[SSL_MD_SHA1_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); + ssl_digest_methods[SSL_MD_GOST94_IDX]= + EVP_get_digestbyname(SN_id_GostR3411_94); + if (ssl_digest_methods[SSL_MD_GOST94_IDX]) + { + ssl_mac_secret_size[SSL_MD_GOST94_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); + } + ssl_digest_methods[SSL_MD_GOST89MAC_IDX]= + EVP_get_digestbyname(SN_id_Gost28147_89_MAC); + ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); + if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32; + } + } #ifndef OPENSSL_NO_COMP static int sk_comp_cmp(const SSL_COMP * const *a, @@ -316,10 +459,10 @@ static void load_builtin_compressions(void) #endif int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, SSL_COMP **comp) + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp) { int i; - SSL_CIPHER *c; + const SSL_CIPHER *c; c=s->cipher; if (c == NULL) return(0); @@ -344,7 +487,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, if ((enc == NULL) || (md == NULL)) return(0); - switch (c->algorithms & SSL_ENC_MASK) + switch (c->algorithm_enc) { case SSL_DES: i=SSL_ENC_DES_IDX; @@ -364,26 +507,24 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_eNULL: i=SSL_ENC_NULL_IDX; break; - case SSL_AES: - switch(c->alg_bits) - { - case 128: i=SSL_ENC_AES128_IDX; break; - case 256: i=SSL_ENC_AES256_IDX; break; - default: i=-1; break; - } + case SSL_AES128: + i=SSL_ENC_AES128_IDX; break; - case SSL_CAMELLIA: - switch(c->alg_bits) - { - case 128: i=SSL_ENC_CAMELLIA128_IDX; break; - case 256: i=SSL_ENC_CAMELLIA256_IDX; break; - default: i=-1; break; - } + case SSL_AES256: + i=SSL_ENC_AES256_IDX; + break; + case SSL_CAMELLIA128: + i=SSL_ENC_CAMELLIA128_IDX; + break; + case SSL_CAMELLIA256: + i=SSL_ENC_CAMELLIA256_IDX; + break; + case SSL_eGOST2814789CNT: + i=SSL_ENC_GOST89_IDX; break; case SSL_SEED: i=SSL_ENC_SEED_IDX; break; - default: i= -1; break; @@ -399,7 +540,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, *enc=ssl_cipher_methods[i]; } - switch (c->algorithms & SSL_MAC_MASK) + switch (c->algorithm_mac) { case SSL_MD5: i=SSL_MD_MD5_IDX; @@ -407,21 +548,48 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SHA1: i=SSL_MD_SHA1_IDX; break; + case SSL_GOST94: + i = SSL_MD_GOST94_IDX; + break; + case SSL_GOST89MAC: + i = SSL_MD_GOST89MAC_IDX; + break; default: i= -1; break; } if ((i < 0) || (i > SSL_MD_NUM_IDX)) - *md=NULL; + { + *md=NULL; + if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef; + if (mac_secret_size!=NULL) *mac_secret_size = 0; + + } else + { *md=ssl_digest_methods[i]; + if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i]; + if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i]; + } - if ((*enc != NULL) && (*md != NULL)) + if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef)) return(1); else return(0); } +int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) +{ + if (idx <0||idx>=SSL_MD_NUM_IDX) + { + return 0; + } + if (ssl_handshake_digest_flag[idx]==0) return 0; + *mask = ssl_handshake_digest_flag[idx]; + *md = ssl_digest_methods[idx]; + return 1; +} + #define ITEM_SEP(a) \ (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) @@ -433,7 +601,7 @@ static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, *head=curr->next; if (curr->prev != NULL) curr->prev->next=curr->next; - if (curr->next != NULL) /* should always be true */ + if (curr->next != NULL) curr->next->prev=curr->prev; (*tail)->next=curr; curr->prev= *tail; @@ -441,69 +609,105 @@ static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, *tail=curr; } -struct disabled_masks { /* This is a kludge no longer needed with OpenSSL 0.9.9, - * where 128-bit and 256-bit algorithms simply will get - * separate bits. */ - unsigned long mask; /* everything except m256 */ - unsigned long m256; /* applies to 256-bit algorithms only */ -}; +static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) + { + if (curr == *head) return; + if (curr == *tail) + *tail=curr->prev; + if (curr->next != NULL) + curr->next->prev=curr->prev; + if (curr->prev != NULL) + curr->prev->next=curr->next; + (*head)->prev=curr; + curr->next= *head; + curr->prev=NULL; + *head=curr; + } -static struct disabled_masks ssl_cipher_get_disabled(void) +static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, unsigned long *enc, unsigned long *mac, unsigned long *ssl) { - unsigned long mask; - unsigned long m256; - struct disabled_masks ret; + *mkey = 0; + *auth = 0; + *enc = 0; + *mac = 0; + *ssl = 0; - mask = SSL_kFZA; #ifdef OPENSSL_NO_RSA - mask |= SSL_aRSA|SSL_kRSA; + *mkey |= SSL_kRSA; + *auth |= SSL_aRSA; #endif #ifdef OPENSSL_NO_DSA - mask |= SSL_aDSS; + *auth |= SSL_aDSS; #endif + *mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */ + *auth |= SSL_aDH; #ifdef OPENSSL_NO_DH - mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH; + *mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH; + *auth |= SSL_aDH; #endif #ifdef OPENSSL_NO_KRB5 - mask |= SSL_kKRB5|SSL_aKRB5; + *mkey |= SSL_kKRB5; + *auth |= SSL_aKRB5; +#endif +#ifdef OPENSSL_NO_ECDSA + *auth |= SSL_aECDSA; #endif #ifdef OPENSSL_NO_ECDH - mask |= SSL_kECDH|SSL_kECDHE; + *mkey |= SSL_kECDHe|SSL_kECDHr; + *auth |= SSL_aECDH; #endif +#ifdef OPENSSL_NO_PSK + *mkey |= SSL_kPSK; + *auth |= SSL_aPSK; +#endif + /* Check for presence of GOST 34.10 algorithms, and if they + * do not present, disable appropriate auth and key exchange */ + if (!get_optional_pkey_id("gost94")) { + *auth |= SSL_aGOST94; + } + if (!get_optional_pkey_id("gost2001")) { + *auth |= SSL_aGOST01; + } + /* Disable GOST key exchange if no GOST signature algs are available * */ + if ((*auth & (SSL_aGOST94|SSL_aGOST01)) == (SSL_aGOST94|SSL_aGOST01)) { + *mkey |= SSL_kGOST; + } #ifdef SSL_FORBID_ENULL - mask |= SSL_eNULL; + *enc |= SSL_eNULL; #endif + + + + *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; + *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; + *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0; + *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0; + *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0; + *enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0; + *enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0; + + *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; + *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; + *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0; + *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0; - mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; - mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; - mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0; - mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; - mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; - mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; - mask |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0; - - mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; - mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; - - /* finally consider algorithms where mask and m256 differ */ - m256 = mask; - mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0; - mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA:0; - m256 |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES:0; - m256 |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA:0; - - ret.mask = mask; - ret.m256 = m256; - return ret; } static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, - int num_of_ciphers, unsigned long mask, unsigned long m256, - CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) + int num_of_ciphers, + unsigned long disabled_mkey, unsigned long disabled_auth, + unsigned long disabled_enc, unsigned long disabled_mac, + unsigned long disabled_ssl, + CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { int i, co_list_num; - SSL_CIPHER *c; + const SSL_CIPHER *c; /* * We have num_of_ciphers descriptions compiled in, depending on the @@ -517,14 +721,13 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, for (i = 0; i < num_of_ciphers; i++) { c = ssl_method->get_cipher(i); -#define IS_MASKED(c) ((c)->algorithms & (((c)->alg_bits == 256) ? m256 : mask)) /* drop those that use any of that is not available */ -#ifdef OPENSSL_FIPS - if ((c != NULL) && c->valid && !IS_MASKED(c) - && (!FIPS_mode() || (c->algo_strength & SSL_FIPS))) -#else - if ((c != NULL) && c->valid && !IS_MASKED(c)) -#endif + if ((c != NULL) && c->valid && + !(c->algorithm_mkey & disabled_mkey) && + !(c->algorithm_auth & disabled_auth) && + !(c->algorithm_enc & disabled_enc) && + !(c->algorithm_mac & disabled_mac) && + !(c->algorithm_ssl & disabled_ssl)) { co_list[co_list_num].cipher = c; co_list[co_list_num].next = NULL; @@ -532,7 +735,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, co_list[co_list_num].active = 0; co_list_num++; #ifdef KSSL_DEBUG - printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms); + printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth); #endif /* KSSL_DEBUG */ /* if (!sk_push(ca_list,(char *)c)) goto err; @@ -543,29 +746,45 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, /* * Prepare linked list from list entries */ - for (i = 1; i < co_list_num - 1; i++) - { - co_list[i].prev = &(co_list[i-1]); - co_list[i].next = &(co_list[i+1]); - } if (co_list_num > 0) { - (*head_p) = &(co_list[0]); - (*head_p)->prev = NULL; - (*head_p)->next = &(co_list[1]); - (*tail_p) = &(co_list[co_list_num - 1]); - (*tail_p)->prev = &(co_list[co_list_num - 2]); - (*tail_p)->next = NULL; + co_list[0].prev = NULL; + + if (co_list_num > 1) + { + co_list[0].next = &co_list[1]; + + for (i = 1; i < co_list_num - 1; i++) + { + co_list[i].prev = &co_list[i - 1]; + co_list[i].next = &co_list[i + 1]; + } + + co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; + } + + co_list[co_list_num - 1].next = NULL; + + *head_p = &co_list[0]; + *tail_p = &co_list[co_list_num - 1]; } } -static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, - int num_of_group_aliases, unsigned long mask, +static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, + int num_of_group_aliases, + unsigned long disabled_mkey, unsigned long disabled_auth, + unsigned long disabled_enc, unsigned long disabled_mac, + unsigned long disabled_ssl, CIPHER_ORDER *head) { CIPHER_ORDER *ciph_curr; - SSL_CIPHER **ca_curr; + const SSL_CIPHER **ca_curr; int i; + unsigned long mask_mkey = ~disabled_mkey; + unsigned long mask_auth = ~disabled_auth; + unsigned long mask_enc = ~disabled_enc; + unsigned long mask_mac = ~disabled_mac; + unsigned long mask_ssl = ~disabled_ssl; /* * First, add the real ciphers as already collected @@ -581,84 +800,118 @@ static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, /* * Now we add the available ones from the cipher_aliases[] table. - * They represent either an algorithm, that must be fully - * supported (not match any bit in mask) or represent a cipher - * strength value (will be added in any case because algorithms=0). + * They represent either one or more algorithms, some of which + * in any affected category must be supported (set in enabled_mask), + * or represent a cipher strength value (will be added in any case because algorithms=0). */ for (i = 0; i < num_of_group_aliases; i++) { - if ((i == 0) || /* always fetch "ALL" */ - !(cipher_aliases[i].algorithms & mask)) - { - *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); - ca_curr++; - } + unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; + unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; + unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; + unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; + unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; + + if (algorithm_mkey) + if ((algorithm_mkey & mask_mkey) == 0) + continue; + + if (algorithm_auth) + if ((algorithm_auth & mask_auth) == 0) + continue; + + if (algorithm_enc) + if ((algorithm_enc & mask_enc) == 0) + continue; + + if (algorithm_mac) + if ((algorithm_mac & mask_mac) == 0) + continue; + + if (algorithm_ssl) + if ((algorithm_ssl & mask_ssl) == 0) + continue; + + *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); + ca_curr++; } *ca_curr = NULL; /* end of list */ } -static void ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long ssl_version, - unsigned long algorithms, unsigned long mask, - unsigned long algo_strength, unsigned long mask_strength, - int rule, int strength_bits, CIPHER_ORDER *co_list, +static void ssl_cipher_apply_rule(unsigned long cipher_id, + unsigned long alg_mkey, unsigned long alg_auth, + unsigned long alg_enc, unsigned long alg_mac, + unsigned long alg_ssl, + unsigned long algo_strength, + int rule, int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { - CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2; - SSL_CIPHER *cp; - unsigned long ma, ma_s; + CIPHER_ORDER *head, *tail, *curr, *curr2, *last; + const SSL_CIPHER *cp; + int reverse = 0; #ifdef CIPHER_DEBUG - printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n", - rule, algorithms, mask, algo_strength, mask_strength, - strength_bits); + printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", + rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits); #endif - curr = head = *head_p; - curr2 = head; - tail2 = tail = *tail_p; + if (rule == CIPHER_DEL) + reverse = 1; /* needed to maintain sorting between currently deleted ciphers */ + + head = *head_p; + tail = *tail_p; + + if (reverse) + { + curr = tail; + last = head; + } + else + { + curr = head; + last = tail; + } + + curr2 = curr; for (;;) { - if ((curr == NULL) || (curr == tail2)) break; + if ((curr == NULL) || (curr == last)) break; curr = curr2; - curr2 = curr->next; + curr2 = reverse ? curr->prev : curr->next; cp = curr->cipher; - /* If explicit cipher suite, match only that one for its own protocol version. - * Usual selection criteria will be used for similar ciphersuites from other version! */ - - if (cipher_id && (cp->algorithms & SSL_SSL_MASK) == ssl_version) + /* + * Selection criteria is either the value of strength_bits + * or the algorithms used. + */ + if (strength_bits >= 0) { - if (cp->id != cipher_id) + if (strength_bits != cp->strength_bits) continue; } - - /* - * Selection criteria is either the number of strength_bits - * or the algorithm used. - */ - else if (strength_bits == -1) + else { - ma = mask & cp->algorithms; - ma_s = mask_strength & cp->algo_strength; - #ifdef CIPHER_DEBUG - printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength); - printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength); + printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength); #endif - /* - * Select: if none of the mask bit was met from the - * cipher or not all of the bits were met, the - * selection does not apply. - */ - if (((ma == 0) && (ma_s == 0)) || - ((ma & algorithms) != ma) || - ((ma_s & algo_strength) != ma_s)) - continue; /* does not apply */ + + if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) + continue; + if (alg_auth && !(alg_auth & cp->algorithm_auth)) + continue; + if (alg_enc && !(alg_enc & cp->algorithm_enc)) + continue; + if (alg_mac && !(alg_mac & cp->algorithm_mac)) + continue; + if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) + continue; + if ((algo_strength & SSL_EXP_MASK) && !(algo_strength & SSL_EXP_MASK & cp->algo_strength)) + continue; + if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) + continue; } - else if (strength_bits != cp->strength_bits) - continue; /* does not apply */ #ifdef CIPHER_DEBUG printf("Action = %d\n", rule); @@ -667,38 +920,37 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long ssl_ver /* add the cipher if it has not been added yet. */ if (rule == CIPHER_ADD) { + /* reverse == 0 */ if (!curr->active) { - int add_this_cipher = 1; - - if (((cp->algorithms & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0)) - { - /* Make sure "ECCdraft" ciphersuites are activated only if - * *explicitly* requested, but not implicitly (such as - * as part of the "AES" alias). */ - - add_this_cipher = (mask & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0 || cipher_id != 0; - } - - if (add_this_cipher) - { - ll_append_tail(&head, curr, &tail); - curr->active = 1; - } + ll_append_tail(&head, curr, &tail); + curr->active = 1; } } /* Move the added cipher to this location */ else if (rule == CIPHER_ORD) { + /* reverse == 0 */ if (curr->active) { ll_append_tail(&head, curr, &tail); } } else if (rule == CIPHER_DEL) - curr->active = 0; + { + /* reverse == 1 */ + if (curr->active) + { + /* most recently deleted ciphersuites get best positions + * for any future CIPHER_ADD (note that the CIPHER_DEL loop + * works in reverse to maintain the order) */ + ll_append_head(&head, curr, &tail); + curr->active = 0; + } + } else if (rule == CIPHER_KILL) { + /* reverse == 0 */ if (head == curr) head = curr->next; else @@ -719,8 +971,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long ssl_ver *tail_p = tail; } -static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list, - CIPHER_ORDER **head_p, +static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { int max_strength_bits, i, *number_uses; @@ -743,10 +994,10 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list, number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); if (!number_uses) - { + { SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE); return(0); - } + } memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); /* @@ -765,21 +1016,20 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list, */ for (i = max_strength_bits; i >= 0; i--) if (number_uses[i] > 0) - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, - co_list, head_p, tail_p); + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p); OPENSSL_free(number_uses); return(1); } static int ssl_cipher_process_rulestr(const char *rule_str, - CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list) + CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p, + const SSL_CIPHER **ca_list) { - unsigned long algorithms, mask, algo_strength, mask_strength; + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength; const char *l, *start, *buf; int j, multi, found, rule, retval, ok, buflen; - unsigned long cipher_id = 0, ssl_version = 0; + unsigned long cipher_id = 0; char ch; retval = 1; @@ -807,7 +1057,12 @@ static int ssl_cipher_process_rulestr(const char *rule_str, continue; } - algorithms = mask = algo_strength = mask_strength = 0; + alg_mkey = 0; + alg_auth = 0; + alg_enc = 0; + alg_mac = 0; + alg_ssl = 0; + algo_strength = 0; start=l; for (;;) @@ -868,10 +1123,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str, * sufficient, we have to strncmp() anyway. (We cannot * use strcmp(), because buf is not '\0' terminated.) */ - j = found = 0; - cipher_id = 0; - ssl_version = 0; - while (ca_list[j]) + j = found = 0; + cipher_id = 0; + while (ca_list[j]) { if (!strncmp(buf, ca_list[j]->name, buflen) && (ca_list[j]->name[buflen] == '\0')) @@ -882,31 +1136,100 @@ static int ssl_cipher_process_rulestr(const char *rule_str, else j++; } + if (!found) break; /* ignore this entry */ - /* New algorithms: - * 1 - any old restrictions apply outside new mask - * 2 - any new restrictions apply outside old mask - * 3 - enforce old & new where masks intersect - */ - algorithms = (algorithms & ~ca_list[j]->mask) | /* 1 */ - (ca_list[j]->algorithms & ~mask) | /* 2 */ - (algorithms & ca_list[j]->algorithms); /* 3 */ - mask |= ca_list[j]->mask; - algo_strength = (algo_strength & ~ca_list[j]->mask_strength) | - (ca_list[j]->algo_strength & ~mask_strength) | - (algo_strength & ca_list[j]->algo_strength); - mask_strength |= ca_list[j]->mask_strength; - - /* explicit ciphersuite found */ + if (ca_list[j]->algorithm_mkey) + { + if (alg_mkey) + { + alg_mkey &= ca_list[j]->algorithm_mkey; + if (!alg_mkey) { found = 0; break; } + } + else + alg_mkey = ca_list[j]->algorithm_mkey; + } + + if (ca_list[j]->algorithm_auth) + { + if (alg_auth) + { + alg_auth &= ca_list[j]->algorithm_auth; + if (!alg_auth) { found = 0; break; } + } + else + alg_auth = ca_list[j]->algorithm_auth; + } + + if (ca_list[j]->algorithm_enc) + { + if (alg_enc) + { + alg_enc &= ca_list[j]->algorithm_enc; + if (!alg_enc) { found = 0; break; } + } + else + alg_enc = ca_list[j]->algorithm_enc; + } + + if (ca_list[j]->algorithm_mac) + { + if (alg_mac) + { + alg_mac &= ca_list[j]->algorithm_mac; + if (!alg_mac) { found = 0; break; } + } + else + alg_mac = ca_list[j]->algorithm_mac; + } + + if (ca_list[j]->algo_strength & SSL_EXP_MASK) + { + if (algo_strength & SSL_EXP_MASK) + { + algo_strength &= (ca_list[j]->algo_strength & SSL_EXP_MASK) | ~SSL_EXP_MASK; + if (!(algo_strength & SSL_EXP_MASK)) { found = 0; break; } + } + else + algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK; + } + + if (ca_list[j]->algo_strength & SSL_STRONG_MASK) + { + if (algo_strength & SSL_STRONG_MASK) + { + algo_strength &= (ca_list[j]->algo_strength & SSL_STRONG_MASK) | ~SSL_STRONG_MASK; + if (!(algo_strength & SSL_STRONG_MASK)) { found = 0; break; } + } + else + algo_strength |= ca_list[j]->algo_strength & SSL_STRONG_MASK; + } + if (ca_list[j]->valid) { + /* explicit ciphersuite found; its protocol version + * does not become part of the search pattern!*/ + cipher_id = ca_list[j]->id; - ssl_version = ca_list[j]->algorithms & SSL_SSL_MASK; - break; } + else + { + /* not an explicit ciphersuite; only in this case, the + * protocol version is considered part of the search pattern */ + if (ca_list[j]->algorithm_ssl) + { + if (alg_ssl) + { + alg_ssl &= ca_list[j]->algorithm_ssl; + if (!alg_ssl) { found = 0; break; } + } + else + alg_ssl = ca_list[j]->algorithm_ssl; + } + } + if (!multi) break; } @@ -918,8 +1241,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, ok = 0; if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) - ok = ssl_cipher_strength_sort(co_list, - head_p, tail_p); + ok = ssl_cipher_strength_sort(head_p, tail_p); else SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); @@ -936,9 +1258,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str, } else if (found) { - ssl_cipher_apply_rule(cipher_id, ssl_version, algorithms, mask, - algo_strength, mask_strength, rule, -1, - co_list, head_p, tail_p); + ssl_cipher_apply_rule(cipher_id, + alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, + rule, -1, head_p, tail_p); } else { @@ -957,12 +1279,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, const char *rule_str) { int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; - unsigned long disabled_mask; - unsigned long disabled_m256; + unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl; STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; const char *rule_p; CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; - SSL_CIPHER **ca_list = NULL; + const SSL_CIPHER **ca_list = NULL; /* * Return with error if nothing to do. @@ -974,12 +1295,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * To reduce the work to do we only want to process the compiled * in algorithms, so we first get the mask of disabled ciphers. */ - { - struct disabled_masks d; - d = ssl_cipher_get_disabled(); - disabled_mask = d.mask; - disabled_m256 = d.m256; - } + ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl); /* * Now we have to collect the available ciphers from the compiled @@ -997,8 +1313,52 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, return(NULL); /* Failure */ } - ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask, - disabled_m256, co_list, &head, &tail); + ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, + disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl, + co_list, &head, &tail); + + + /* Now arrange all ciphers by preference: */ + + /* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */ + ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + /* AES is our preferred symmetric cipher */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + + /* Temporarily enable everything else for sorting */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + + /* Low priority for MD5 */ + ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Move anonymous ciphers to the end. Usually, these will remain disabled. + * (For applications that allow them, they aren't too bad, but we prefer + * authenticated ciphers.) */ + ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Move ciphers without forward secrecy to the end */ + ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + /* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); */ + ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kKRB5, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* RC4 is sort-of broken -- move the the end */ + ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Now sort by symmetric encryption strength. The above ordering remains + * in force within each class */ + if (!ssl_cipher_strength_sort(&head, &tail)) + { + OPENSSL_free(co_list); + return NULL; + } + + /* Now disable everything (maintaining the ordering!) */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + /* * We also need cipher aliases for selecting based on the rule_str. @@ -1010,8 +1370,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; - ca_list = - (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); + ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); if (ca_list == NULL) { OPENSSL_free(co_list); @@ -1019,7 +1378,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, return(NULL); /* Failure */ } ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, - (disabled_mask & disabled_m256), head); + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, head); /* * If the rule_string begins with DEFAULT, apply the default rule @@ -1030,23 +1390,23 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, if (strncmp(rule_str,"DEFAULT",7) == 0) { ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, - co_list, &head, &tail, ca_list); + &head, &tail, ca_list); rule_p += 7; if (*rule_p == ':') rule_p++; } if (ok && (strlen(rule_p) > 0)) - ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail, - ca_list); + ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); - OPENSSL_free(ca_list); /* Not needed anymore */ + OPENSSL_free((void *)ca_list); /* Not needed anymore */ if (!ok) { /* Rule processing failure */ OPENSSL_free(co_list); return(NULL); } + /* * Allocate new "cipherstack" for the result, return with error * if we cannot get one. @@ -1063,11 +1423,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ for (curr = head; curr != NULL; curr = curr->next) { -#ifdef OPENSSL_FIPS - if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) -#else if (curr->active) -#endif { sk_SSL_CIPHER_push(cipherstack, curr->cipher); #ifdef CIPHER_DEBUG @@ -1100,14 +1456,19 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) int is_export,pkl,kl; const char *ver,*exp_str; const char *kx,*au,*enc,*mac; - unsigned long alg,alg2,alg_s; + unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2,alg_s; #ifdef KSSL_DEBUG - static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n"; + static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; #else static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; #endif /* KSSL_DEBUG */ - alg=cipher->algorithms; + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + alg_ssl = cipher->algorithm_ssl; + alg_s=cipher->algo_strength; alg2=cipher->algorithm2; @@ -1116,14 +1477,14 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) kl=SSL_C_EXPORT_KEYLENGTH(cipher); exp_str=is_export?" export":""; - if (alg & SSL_SSLV2) + if (alg_ssl & SSL_SSLV2) ver="SSLv2"; - else if (alg & SSL_SSLV3) + else if (alg_ssl & SSL_SSLV3) ver="SSLv3"; else ver="unknown"; - switch (alg&SSL_MKEY_MASK) + switch (alg_mkey) { case SSL_kRSA: kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA"; @@ -1134,25 +1495,29 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kDHd: kx="DH/DSS"; break; - case SSL_kKRB5: /* VRS */ - case SSL_KRB5: /* VRS */ - kx="KRB5"; - break; - case SSL_kFZA: - kx="Fortezza"; + case SSL_kKRB5: + kx="KRB5"; break; case SSL_kEDH: kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH"; break; - case SSL_kECDH: - case SSL_kECDHE: - kx=is_export?"ECDH(<=163)":"ECDH"; + case SSL_kECDHr: + kx="ECDH/RSA"; + break; + case SSL_kECDHe: + kx="ECDH/ECDSA"; + break; + case SSL_kEECDH: + kx="ECDH"; + break; + case SSL_kPSK: + kx="PSK"; break; default: kx="unknown"; } - switch (alg&SSL_AUTH_MASK) + switch (alg_auth) { case SSL_aRSA: au="RSA"; @@ -1163,23 +1528,27 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_aDH: au="DH"; break; - case SSL_aKRB5: /* VRS */ - case SSL_KRB5: /* VRS */ - au="KRB5"; - break; - case SSL_aFZA: + case SSL_aKRB5: + au="KRB5"; + break; + case SSL_aECDH: + au="ECDH"; + break; case SSL_aNULL: au="None"; break; case SSL_aECDSA: au="ECDSA"; break; + case SSL_aPSK: + au="PSK"; + break; default: au="unknown"; break; } - switch (alg&SSL_ENC_MASK) + switch (alg_enc) { case SSL_DES: enc=(is_export && kl == 5)?"DES(40)":"DES(56)"; @@ -1197,39 +1566,30 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_IDEA: enc="IDEA(128)"; break; - case SSL_eFZA: - enc="Fortezza"; - break; case SSL_eNULL: enc="None"; break; - case SSL_AES: - switch(cipher->strength_bits) - { - case 128: enc="AES(128)"; break; - case 192: enc="AES(192)"; break; - case 256: enc="AES(256)"; break; - default: enc="AES(?""?""?)"; break; - } + case SSL_AES128: + enc="AES(128)"; break; - case SSL_CAMELLIA: - switch(cipher->strength_bits) - { - case 128: enc="Camellia(128)"; break; - case 256: enc="Camellia(256)"; break; - default: enc="Camellia(?""?""?)"; break; - } + case SSL_AES256: + enc="AES(256)"; + break; + case SSL_CAMELLIA128: + enc="Camellia(128)"; + break; + case SSL_CAMELLIA256: + enc="Camellia(256)"; break; case SSL_SEED: enc="SEED(128)"; break; - default: enc="unknown"; break; } - switch (alg&SSL_MAC_MASK) + switch (alg_mac) { case SSL_MD5: mac="MD5"; @@ -1252,7 +1612,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) return("Buffer too small"); #ifdef KSSL_DEBUG - BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg); + BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl); #else BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str); #endif /* KSSL_DEBUG */ diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c index 7eb52026e7..0eed464749 100644 --- a/crypto/openssl/ssl/ssl_err.c +++ b/crypto/openssl/ssl/ssl_err.c @@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -141,6 +141,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"}, +{ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS), "SSL3_DIGEST_CACHED_RECORDS"}, {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), "SSL3_DO_CHANGE_CIPHER_SPEC"}, {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"}, {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, @@ -158,6 +159,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), "SSL3_GET_SERVER_CERTIFICATE"}, {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "SSL3_GET_SERVER_DONE"}, {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "SSL3_GET_SERVER_HELLO"}, +{ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"}, {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "SSL3_OUTPUT_CERT_CHAIN"}, {ERR_FUNC(SSL_F_SSL3_PEEK), "SSL3_PEEK"}, @@ -170,8 +172,9 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE), "SSL3_SEND_SERVER_CERTIFICATE"}, {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "SSL3_SEND_SERVER_HELLO"}, {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE), "SSL3_SEND_SERVER_KEY_EXCHANGE"}, -{ERR_FUNC(SSL_F_SSL3_SETUP_BUFFERS), "SSL3_SETUP_BUFFERS"}, {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"}, +{ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "SSL3_SETUP_READ_BUFFER"}, +{ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "SSL3_SETUP_WRITE_BUFFER"}, {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"}, {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"}, {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"}, @@ -188,6 +191,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_CERT_NEW), "SSL_CERT_NEW"}, {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), "SSL_CHECK_SERVERHELLO_TLSEXT"}, +{ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), "SSL_CHECK_SRVR_ECC_CERT_AND_ALG"}, {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), "SSL_CIPHER_PROCESS_RULESTR"}, {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, @@ -209,6 +213,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"}, {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1), "SSL_CTX_use_PrivateKey_ASN1"}, {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE), "SSL_CTX_use_PrivateKey_file"}, +{ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT), "SSL_CTX_use_psk_identity_hint"}, {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"}, {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1), "SSL_CTX_use_RSAPrivateKey_ASN1"}, {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE), "SSL_CTX_use_RSAPrivateKey_file"}, @@ -241,6 +246,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"}, {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"}, {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), "SSL_set_session_id_context"}, +{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"}, {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, @@ -253,13 +259,19 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"}, {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"}, {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"}, +{ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"}, {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"}, {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1), "SSL_use_RSAPrivateKey_ASN1"}, {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE), "SSL_use_RSAPrivateKey_file"}, {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "SSL_VERIFY_CERT_CHAIN"}, {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, +{ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"}, +{ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, +{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, +{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, +{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, {0,NULL} @@ -283,12 +295,15 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_BAD_ECC_CERT) ,"bad ecc cert"}, {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE) ,"bad ecdsa signature"}, {ERR_REASON(SSL_R_BAD_ECPOINT) ,"bad ecpoint"}, +{ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH) ,"bad handshake length"}, {ERR_REASON(SSL_R_BAD_HELLO_REQUEST) ,"bad hello request"}, {ERR_REASON(SSL_R_BAD_LENGTH) ,"bad length"}, {ERR_REASON(SSL_R_BAD_MAC_DECODE) ,"bad mac decode"}, +{ERR_REASON(SSL_R_BAD_MAC_LENGTH) ,"bad mac length"}, {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE) ,"bad message type"}, {ERR_REASON(SSL_R_BAD_PACKET_LENGTH) ,"bad packet length"}, {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),"bad protocol version number"}, +{ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH),"bad psk identity hint length"}, {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) ,"bad response argument"}, {ERR_REASON(SSL_R_BAD_RSA_DECRYPT) ,"bad rsa decrypt"}, {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT) ,"bad rsa encrypt"}, @@ -314,6 +329,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"}, {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) ,"clienthello tlsext"}, {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"}, +{ERR_REASON(SSL_R_COMPRESSION_DISABLED) ,"compression disabled"}, {ERR_REASON(SSL_R_COMPRESSION_FAILURE) ,"compression failure"}, {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),"compression id not within private range"}, {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),"compression library error"}, @@ -328,6 +344,10 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"}, {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"}, {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID),"duplicate compression id"}, +{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT),"ecc cert not for key agreement"}, +{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING),"ecc cert not for signing"}, +{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"}, +{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"}, {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"}, {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"}, {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"}, @@ -338,8 +358,10 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"}, {ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"}, {ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"}, +{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"}, {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"}, {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, +{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"}, {ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"}, {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"}, {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"}, @@ -389,18 +411,22 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) ,"no client cert method"}, {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED),"no client cert received"}, {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"}, +{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"}, {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) ,"no method specified"}, {ERR_REASON(SSL_R_NO_PRIVATEKEY) ,"no privatekey"}, {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"}, {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"}, {ERR_REASON(SSL_R_NO_PUBLICKEY) ,"no publickey"}, {ERR_REASON(SSL_R_NO_RENEGOTIATION) ,"no renegotiation"}, +{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST) ,"digest requred for handshake isn't computed"}, {ERR_REASON(SSL_R_NO_SHARED_CIPHER) ,"no shared cipher"}, {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) ,"no verify callback"}, {ERR_REASON(SSL_R_NULL_SSL_CTX) ,"null ssl ctx"}, {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED),"null ssl method passed"}, {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"}, +{ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),"old session compression algorithm not returned"}, {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"}, +{ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG),"opaque PRF input too long"}, {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"}, {ERR_REASON(SSL_R_PARSE_TLSEXT) ,"parse tlsext"}, {ERR_REASON(SSL_R_PATH_TOO_LONG) ,"path too long"}, @@ -413,6 +439,9 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG),"pre mac length too long"}, {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS),"problems mapping cipher functions"}, {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN) ,"protocol is shutdown"}, +{ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND),"psk identity not found"}, +{ERR_REASON(SSL_R_PSK_NO_CLIENT_CB) ,"psk no client cb"}, +{ERR_REASON(SSL_R_PSK_NO_SERVER_CB) ,"psk no server cb"}, {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR),"public key encrypt error"}, {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) ,"public key is not rsa"}, {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"}, @@ -426,6 +455,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"}, {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"}, {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"}, +{ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING),"required compresssion algorithm missing"}, {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"}, {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"}, {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"}, @@ -436,6 +466,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"}, +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"}, {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),"ssl3 ext invalid servername"}, {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),"ssl3 ext invalid servername type"}, {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG),"ssl3 session id too long"}, @@ -471,6 +502,11 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),"tlsv1 alert record overflow"}, {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1 alert unknown ca"}, {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1 alert user cancelled"}, +{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),"tlsv1 bad certificate hash value"}, +{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),"tlsv1 bad certificate status response"}, +{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),"tlsv1 certificate unobtainable"}, +{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"}, +{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"}, {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"}, {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"}, {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"}, @@ -502,6 +538,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"}, {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, +{ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE),"unsupported digest type"}, {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"}, {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL) ,"unsupported protocol"}, {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"}, diff --git a/crypto/openssl/ssl/ssl_lib.c b/crypto/openssl/ssl/ssl_lib.c index 15650da5e7..3157f20eac 100644 --- a/crypto/openssl/ssl/ssl_lib.c +++ b/crypto/openssl/ssl/ssl_lib.c @@ -58,7 +58,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * 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 @@ -115,6 +115,32 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #ifdef REF_CHECK # include @@ -143,9 +169,9 @@ SSL3_ENC_METHOD ssl3_undef_enc_method={ ssl_undefined_function, (int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function, (int (*)(SSL*, int))ssl_undefined_function, - (int (*)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char*, int, unsigned char *))ssl_undefined_function, + (int (*)(SSL *, const char*, int, unsigned char *))ssl_undefined_function, 0, /* finish_mac_length */ - (int (*)(SSL *, EVP_MD_CTX *, unsigned char *))ssl_undefined_function, + (int (*)(SSL *, int, unsigned char *))ssl_undefined_function, NULL, /* client_finished_label */ 0, /* client_finished_label_len */ NULL, /* server_finished_label */ @@ -204,6 +230,8 @@ int SSL_clear(SSL *s) } ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); s->first_packet=0; @@ -224,14 +252,15 @@ int SSL_clear(SSL *s) } /** Used to change an SSL_CTXs default SSL method type */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth) +int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth) { STACK_OF(SSL_CIPHER) *sk; ctx->method=meth; sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list), - &(ctx->cipher_list_by_id),SSL_DEFAULT_CIPHER_LIST); + &(ctx->cipher_list_by_id), + meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); @@ -308,6 +337,7 @@ SSL *SSL_new(SSL_CTX *ctx) s->trust = ctx->trust; #endif s->quiet_shutdown=ctx->quiet_shutdown; + s->max_send_fragment = ctx->max_send_fragment; CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); s->ctx=ctx; @@ -324,6 +354,7 @@ SSL *SSL_new(SSL_CTX *ctx) CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); s->initial_ctx=ctx; #endif + s->verify_result=X509_V_OK; s->method=ctx->method; @@ -338,6 +369,11 @@ SSL *SSL_new(SSL_CTX *ctx) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); +#ifndef OPENSSL_NO_PSK + s->psk_client_callback=ctx->psk_client_callback; + s->psk_server_callback=ctx->psk_server_callback; +#endif + return(s); err: if (s != NULL) @@ -425,7 +461,7 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, } CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r); + p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); return (p != NULL); } @@ -450,6 +486,16 @@ int SSL_set_trust(SSL *s, int trust) return X509_VERIFY_PARAM_set_trust(s->param, trust); } +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) + { + return X509_VERIFY_PARAM_set1(ctx->param, vpm); + } + +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) + { + return X509_VERIFY_PARAM_set1(ssl->param, vpm); + } + void SSL_free(SSL *s) { int i; @@ -504,6 +550,8 @@ void SSL_free(SSL *s) } ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); if (s->cert != NULL) ssl_cert_free(s->cert); /* Free up if allocated */ @@ -512,6 +560,11 @@ void SSL_free(SSL *s) if (s->tlsext_hostname) OPENSSL_free(s->tlsext_hostname); if (s->initial_ctx) SSL_CTX_free(s->initial_ctx); +#ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist) OPENSSL_free(s->tlsext_ecpointformatlist); + if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist); +#endif /* OPENSSL_NO_EC */ + if (s->tlsext_opaque_prf_input) OPENSSL_free(s->tlsext_opaque_prf_input); if (s->tlsext_ocsp_exts) sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); @@ -520,6 +573,7 @@ void SSL_free(SSL *s) if (s->tlsext_ocsp_resp) OPENSSL_free(s->tlsext_ocsp_resp); #endif + if (s->client_CA != NULL) sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free); @@ -844,7 +898,7 @@ int SSL_check_private_key(const SSL *ssl) } if (ssl->cert == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED); + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED); return 0; } if (ssl->cert->key->x509 == NULL) @@ -1007,6 +1061,11 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) return larg; } return 0; + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + s->max_send_fragment = larg; + return 1; case SSL_CTRL_GET_RI_SUPPORT: if (s->s3) return s->s3->send_connection_binding; @@ -1029,7 +1088,7 @@ long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) } } -struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx) +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; } @@ -1072,7 +1131,7 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) return(ctx->session_cache_mode); case SSL_CTRL_SESS_NUMBER: - return(ctx->sessions->num_items); + return(lh_SSL_SESSION_num_items(ctx->sessions)); case SSL_CTRL_SESS_CONNECT: return(ctx->stats.sess_connect); case SSL_CTRL_SESS_CONNECT_GOOD: @@ -1103,6 +1162,11 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) return(ctx->mode|=larg); case SSL_CTRL_CLEAR_MODE: return(ctx->mode&=~larg); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + ctx->max_send_fragment = larg; + return 1; default: return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg)); } @@ -1207,8 +1271,8 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) /* ssl_create_cipher_list may return an empty stack if it * was unable to find a cipher matching the given rule string * (for example if the rule string specifies a cipher which - * has been disabled). This is not an error as far as - * ssl_create_cipher_list is concerned, and hence + * has been disabled). This is not an error as far as + * ssl_create_cipher_list is concerned, and hence * ctx->cipher_list and ctx->cipher_list_by_id has been * updated. */ if (sk == NULL) @@ -1276,13 +1340,13 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) } int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, - int (*put_cb)(const SSL_CIPHER *, unsigned char *)) + int (*put_cb)(const SSL_CIPHER *, unsigned char *)) { int i,j=0; SSL_CIPHER *c; unsigned char *q; #ifndef OPENSSL_NO_KRB5 - int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx); + int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx); #endif /* OPENSSL_NO_KRB5 */ if (sk == NULL) return(0); @@ -1292,10 +1356,16 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, { c=sk_SSL_CIPHER_value(sk,i); #ifndef OPENSSL_NO_KRB5 - if ((c->algorithms & SSL_KRB5) && nokrb5) - continue; -#endif /* OPENSSL_NO_KRB5 */ - + if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) && + nokrb5) + continue; +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + /* with PSK there must be client callback set */ + if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) && + s->psk_client_callback == NULL) + continue; +#endif /* OPENSSL_NO_PSK */ j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); p+=j; } @@ -1306,7 +1376,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, { static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, + 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p); p+=j; @@ -1321,7 +1391,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, STACK_OF(SSL_CIPHER) **skp) { - SSL_CIPHER *c; + const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *sk; int i,n; if (s->s3) @@ -1384,6 +1454,7 @@ err: return(NULL); } + #ifndef OPENSSL_NO_TLSEXT /** return a servername extension value if provided in Client Hello, or NULL. * So far, only host_name types are defined (RFC 3546). @@ -1407,7 +1478,7 @@ int SSL_get_servername_type(const SSL *s) } #endif -unsigned long SSL_SESSION_hash(const SSL_SESSION *a) +static unsigned long ssl_session_hash(const SSL_SESSION *a) { unsigned long l; @@ -1424,7 +1495,7 @@ unsigned long SSL_SESSION_hash(const SSL_SESSION *a) * 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. */ -int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) +static int ssl_session_cmp(const SSL_SESSION *a,const SSL_SESSION *b) { if (a->ssl_version != b->ssl_version) return(1); @@ -1437,27 +1508,19 @@ int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each * variable. The reason is that the functions aren't static, they're exposed via * ssl.h. */ -static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *) -static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *) +static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) +static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) -SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) { SSL_CTX *ret=NULL; - + if (meth == NULL) { SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED); return(NULL); } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && (meth->version < TLS1_VERSION)) - { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return NULL; - } -#endif - if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); @@ -1520,15 +1583,14 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) ret->app_gen_cookie_cb=0; ret->app_verify_cookie_cb=0; - ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash), - LHASH_COMP_FN(SSL_SESSION_cmp)); + ret->sessions=lh_SSL_SESSION_new(); 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); + meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { @@ -1564,6 +1626,8 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) ret->extra_certs=NULL; ret->comp_methods=SSL_COMP_get_compression_methods(); + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + #ifndef OPENSSL_NO_TLSEXT ret->tlsext_servername_callback = 0; ret->tlsext_servername_arg = NULL; @@ -1577,7 +1641,29 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) ret->tlsext_status_arg = NULL; #endif - +#ifndef OPENSSL_NO_PSK + ret->psk_identity_hint=NULL; + ret->psk_client_callback=NULL; + ret->psk_server_callback=NULL; +#endif +#ifndef OPENSSL_NO_BUF_FREELISTS + ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; + ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->rbuf_freelist) + goto err; + ret->rbuf_freelist->chunklen = 0; + ret->rbuf_freelist->len = 0; + ret->rbuf_freelist->head = NULL; + ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->wbuf_freelist) + { + OPENSSL_free(ret->rbuf_freelist); + goto err; + } + ret->wbuf_freelist->chunklen = 0; + ret->wbuf_freelist->len = 0; + ret->wbuf_freelist->head = NULL; +#endif #ifndef OPENSSL_NO_ENGINE ret->client_cert_engine = NULL; #ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO @@ -1616,6 +1702,20 @@ static void SSL_COMP_free(SSL_COMP *comp) { OPENSSL_free(comp); } #endif +#ifndef OPENSSL_NO_BUF_FREELISTS +static void +ssl_buf_freelist_free(SSL3_BUF_FREELIST *list) + { + SSL3_BUF_FREELIST_ENTRY *ent, *next; + for (ent = list->head; ent; ent = next) + { + next = ent->next; + OPENSSL_free(ent); + } + OPENSSL_free(list); + } +#endif + void SSL_CTX_free(SSL_CTX *a) { int i; @@ -1653,7 +1753,7 @@ void SSL_CTX_free(SSL_CTX *a) CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); if (a->sessions != NULL) - lh_free(a->sessions); + lh_SSL_SESSION_free(a->sessions); if (a->cert_store != NULL) X509_STORE_free(a->cert_store); @@ -1673,10 +1773,23 @@ void SSL_CTX_free(SSL_CTX *a) #else a->comp_methods = NULL; #endif + +#ifndef OPENSSL_NO_PSK + if (a->psk_identity_hint) + OPENSSL_free(a->psk_identity_hint); +#endif #ifndef OPENSSL_NO_ENGINE if (a->client_cert_engine) ENGINE_finish(a->client_cert_engine); #endif + +#ifndef OPENSSL_NO_BUF_FREELISTS + if (a->wbuf_freelist) + ssl_buf_freelist_free(a->wbuf_freelist); + if (a->rbuf_freelist) + ssl_buf_freelist_free(a->rbuf_freelist); +#endif + OPENSSL_free(a); } @@ -1707,13 +1820,13 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) X509_VERIFY_PARAM_set_depth(ctx->param, depth); } -void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) { CERT_PKEY *cpk; int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign; int rsa_enc_export,dh_rsa_export,dh_dsa_export; int rsa_tmp_export,dh_tmp_export,kl; - unsigned long mask,emask; + unsigned long mask_k,mask_a,emask_k,emask_a; int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size; #ifndef OPENSSL_NO_ECDH int have_ecdh_tmp; @@ -1760,60 +1873,77 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl); cpk= &(c->pkeys[SSL_PKEY_ECC]); have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL); - mask=0; - emask=0; + mask_k=0; + mask_a=0; + emask_k=0; + emask_a=0; + + #ifdef CIPHER_DEBUG - printf("rt=%d rte=%d dht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", - rsa_tmp,rsa_tmp_export,dh_tmp, + printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", + rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp, rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa); #endif + + cpk = &(c->pkeys[SSL_PKEY_GOST01]); + if (cpk->x509 != NULL && cpk->privatekey !=NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST01; + } + cpk = &(c->pkeys[SSL_PKEY_GOST94]); + if (cpk->x509 != NULL && cpk->privatekey !=NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST94; + } if (rsa_enc || (rsa_tmp && rsa_sign)) - mask|=SSL_kRSA; + mask_k|=SSL_kRSA; if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) - emask|=SSL_kRSA; + emask_k|=SSL_kRSA; #if 0 /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */ - if ( (dh_tmp || dh_rsa || dh_dsa) && + if ( (dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) - mask|=SSL_kEDH; + mask_k|=SSL_kEDH; if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && (rsa_enc || rsa_sign || dsa_sign)) - emask|=SSL_kEDH; + emask_k|=SSL_kEDH; #endif - if (dh_tmp_export) - emask|=SSL_kEDH; + if (dh_tmp_export) + emask_k|=SSL_kEDH; if (dh_tmp) - mask|=SSL_kEDH; + mask_k|=SSL_kEDH; - if (dh_rsa) mask|=SSL_kDHr; - if (dh_rsa_export) emask|=SSL_kDHr; + if (dh_rsa) mask_k|=SSL_kDHr; + if (dh_rsa_export) emask_k|=SSL_kDHr; - if (dh_dsa) mask|=SSL_kDHd; - if (dh_dsa_export) emask|=SSL_kDHd; + if (dh_dsa) mask_k|=SSL_kDHd; + if (dh_dsa_export) emask_k|=SSL_kDHd; if (rsa_enc || rsa_sign) { - mask|=SSL_aRSA; - emask|=SSL_aRSA; + mask_a|=SSL_aRSA; + emask_a|=SSL_aRSA; } if (dsa_sign) { - mask|=SSL_aDSS; - emask|=SSL_aDSS; + mask_a|=SSL_aDSS; + emask_a|=SSL_aDSS; } - mask|=SSL_aNULL; - emask|=SSL_aNULL; + mask_a|=SSL_aNULL; + emask_a|=SSL_aNULL; #ifndef OPENSSL_NO_KRB5 - mask|=SSL_kKRB5|SSL_aKRB5; - emask|=SSL_kKRB5|SSL_aKRB5; + mask_k|=SSL_kKRB5; + mask_a|=SSL_aKRB5; + emask_k|=SSL_kKRB5; + emask_a|=SSL_aKRB5; #endif /* An ECC certificate may be usable for ECDH and/or @@ -1821,7 +1951,7 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) */ if (have_ecc_cert) { - /* This call populates extension flags (ex_flags) */ + /* This call populates extension flags (ex_flags) */ x = (c->pkeys[SSL_PKEY_ECC]).x509; X509_check_purpose(x, -1, 0); ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? @@ -1829,7 +1959,7 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; ecc_pkey = X509_get_pubkey(x); - ecc_pkey_size = (ecc_pkey != NULL) ? + ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; EVP_PKEY_free(ecc_pkey); if ((x->sig_alg) && (x->sig_alg->algorithm)) @@ -1837,27 +1967,41 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) #ifndef OPENSSL_NO_ECDH if (ecdh_ok) { - if ((signature_nid == NID_md5WithRSAEncryption) || - (signature_nid == NID_md4WithRSAEncryption) || - (signature_nid == NID_md2WithRSAEncryption)) + const char *sig = OBJ_nid2ln(signature_nid); + if (sig == NULL) + { + ERR_clear_error(); + sig = "unknown"; + } + + if (strstr(sig, "WithRSA")) { - mask|=SSL_kECDH|SSL_aRSA; + mask_k|=SSL_kECDHr; + mask_a|=SSL_aECDH; if (ecc_pkey_size <= 163) - emask|=SSL_kECDH|SSL_aRSA; + { + emask_k|=SSL_kECDHr; + emask_a|=SSL_aECDH; + } } + if (signature_nid == NID_ecdsa_with_SHA1) { - mask|=SSL_kECDH|SSL_aECDSA; + mask_k|=SSL_kECDHe; + mask_a|=SSL_aECDH; if (ecc_pkey_size <= 163) - emask|=SSL_kECDH|SSL_aECDSA; + { + emask_k|=SSL_kECDHe; + emask_a|=SSL_aECDH; + } } } #endif #ifndef OPENSSL_NO_ECDSA if (ecdsa_ok) { - mask|=SSL_aECDSA; - emask|=SSL_aECDSA; + mask_a|=SSL_aECDSA; + emask_a|=SSL_aECDSA; } #endif } @@ -1865,12 +2009,22 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) #ifndef OPENSSL_NO_ECDH if (have_ecdh_tmp) { - mask|=SSL_kECDHE; - emask|=SSL_kECDHE; + mask_k|=SSL_kEECDH; + emask_k|=SSL_kEECDH; } #endif - c->mask=mask; - c->export_mask=emask; + +#ifndef OPENSSL_NO_PSK + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; + emask_k |= SSL_kPSK; + emask_a |= SSL_aPSK; +#endif + + c->mask_k=mask_k; + c->mask_a=mask_a; + c->export_mask_k=emask_k; + c->export_mask_a=emask_a; c->valid=1; } @@ -1878,13 +2032,18 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs) +#ifndef OPENSSL_NO_EC + +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) { - unsigned long alg = cs->algorithms; + unsigned long alg_k, alg_a; EVP_PKEY *pkey = NULL; int keysize = 0; int signature_nid = 0; + alg_k = cs->algorithm_mkey; + alg_a = cs->algorithm_auth; + if (SSL_C_IS_EXPORT(cs)) { /* ECDH key length in export ciphers must be <= 163 bits */ @@ -1899,37 +2058,46 @@ int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs) X509_check_purpose(x, -1, 0); if ((x->sig_alg) && (x->sig_alg->algorithm)) signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - if (alg & SSL_kECDH) + if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { /* key usage, if present, must allow key agreement */ if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); return 0; } - if (alg & SSL_aECDSA) + if (alg_k & SSL_kECDHe) { /* signature alg must be ECDSA */ if (signature_nid != NID_ecdsa_with_SHA1) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); return 0; } } - if (alg & SSL_aRSA) + if (alg_k & SSL_kECDHr) { /* signature alg must be RSA */ - if ((signature_nid != NID_md5WithRSAEncryption) && - (signature_nid != NID_md4WithRSAEncryption) && - (signature_nid != NID_md2WithRSAEncryption)) + + const char *sig = OBJ_nid2ln(signature_nid); + if (sig == NULL) + { + ERR_clear_error(); + sig = "unknown"; + } + if (strstr(sig, "WithRSA") == NULL) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); return 0; } } - } - else if (alg & SSL_aECDSA) + } + if (alg_a & SSL_aECDSA) { /* key usage, if present, must allow signing */ if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; } } @@ -1937,58 +2105,74 @@ int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs) return 1; /* all checks are ok */ } +#endif + /* THIS NEEDS CLEANING UP */ X509 *ssl_get_server_send_cert(SSL *s) { - unsigned long alg,mask,kalg; + unsigned long alg_k,alg_a,mask_k,mask_a; CERT *c; int i,is_export; c=s->cert; ssl_set_cert_masks(c, s->s3->tmp.new_cipher); - alg=s->s3->tmp.new_cipher->algorithms; is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); - mask=is_export?c->export_mask:c->mask; - kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK); + if (is_export) + { + mask_k = c->export_mask_k; + mask_a = c->export_mask_a; + } + else + { + mask_k = c->mask_k; + mask_a = c->mask_a; + } + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (kalg & SSL_kECDH) + if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { - /* we don't need to look at SSL_kECDHE + /* we don't need to look at SSL_kEECDH * since no certificate is needed for * anon ECDH and for authenticated - * ECDHE, the check for the auth + * EECDH, the check for the auth * algorithm will set i correctly * NOTE: For ECDH-RSA, we need an ECC - * not an RSA cert but for ECDHE-RSA + * not an RSA cert but for EECDH-RSA * we need an RSA cert. Placing the * checks for SSL_kECDH before RSA * checks ensures the correct cert is chosen. */ i=SSL_PKEY_ECC; } - else if (kalg & SSL_aECDSA) + else if (alg_a & SSL_aECDSA) { i=SSL_PKEY_ECC; } - else if (kalg & SSL_kDHr) + else if (alg_k & SSL_kDHr) i=SSL_PKEY_DH_RSA; - else if (kalg & SSL_kDHd) + else if (alg_k & SSL_kDHd) i=SSL_PKEY_DH_DSA; - else if (kalg & SSL_aDSS) + else if (alg_a & SSL_aDSS) i=SSL_PKEY_DSA_SIGN; - else if (kalg & SSL_aRSA) + else if (alg_a & SSL_aRSA) { if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL) i=SSL_PKEY_RSA_SIGN; else i=SSL_PKEY_RSA_ENC; } - else if (kalg & SSL_aKRB5) + else if (alg_a & SSL_aKRB5) { /* VRS something else here? */ return(NULL); } - else /* if (kalg & SSL_aNULL) */ + else if (alg_a & SSL_aGOST94) + i=SSL_PKEY_GOST94; + else if (alg_a & SSL_aGOST01) + i=SSL_PKEY_GOST01; + else /* if (alg_a & SSL_aNULL) */ { SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); return(NULL); @@ -1998,18 +2182,18 @@ X509 *ssl_get_server_send_cert(SSL *s) return(c->pkeys[i].x509); } -EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher) +EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher) { - unsigned long alg; + unsigned long alg_a; CERT *c; - alg=cipher->algorithms; + alg_a = cipher->algorithm_auth; c=s->cert; - if ((alg & SSL_aDSS) && + if ((alg_a & SSL_aDSS) && (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey); - else if (alg & SSL_aRSA) + else if (alg_a & SSL_aRSA) { if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey); @@ -2018,10 +2202,10 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher) else return(NULL); } - else if ((alg & SSL_aECDSA) && + else if ((alg_a & SSL_aECDSA) && (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) return(c->pkeys[SSL_PKEY_ECC].privatekey); - else /* if (alg & SSL_aNULL) */ + else /* if (alg_a & SSL_aNULL) */ { SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); return(NULL); @@ -2036,14 +2220,14 @@ void ssl_update_cache(SSL *s,int mode) * and it would be rather hard to do anyway :-) */ if (s->session->session_id_length == 0) return; - i=s->ctx->session_cache_mode; + i=s->session_ctx->session_cache_mode; if ((i & mode) && (!s->hit) && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) - || SSL_CTX_add_session(s->ctx,s->session)) - && (s->ctx->new_session_cb != NULL)) + || SSL_CTX_add_session(s->session_ctx,s->session)) + && (s->session_ctx->new_session_cb != NULL)) { CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION); - if (!s->ctx->new_session_cb(s,s->session)) + if (!s->session_ctx->new_session_cb(s,s->session)) SSL_SESSION_free(s->session); } @@ -2052,20 +2236,20 @@ void ssl_update_cache(SSL *s,int mode) ((i & mode) == mode)) { if ( (((mode & SSL_SESS_CACHE_CLIENT) - ?s->ctx->stats.sess_connect_good - :s->ctx->stats.sess_accept_good) & 0xff) == 0xff) + ?s->session_ctx->stats.sess_connect_good + :s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) { - SSL_CTX_flush_sessions(s->ctx,(unsigned long)time(NULL)); + SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL)); } } } -SSL_METHOD *SSL_get_ssl_method(SSL *s) +const SSL_METHOD *SSL_get_ssl_method(SSL *s) { return(s->method); } -int SSL_set_ssl_method(SSL *s,SSL_METHOD *meth) +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth) { int conn= -1; int ret=1; @@ -2208,6 +2392,8 @@ void SSL_set_accept_state(SSL *s) s->handshake_func=s->method->ssl_accept; /* clear the current cipher */ ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); } void SSL_set_connect_state(SSL *s) @@ -2218,6 +2404,8 @@ void SSL_set_connect_state(SSL *s) s->handshake_func=s->method->ssl_connect; /* clear the current cipher */ ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); } int ssl_undefined_function(SSL *s) @@ -2262,7 +2450,7 @@ SSL *SSL_dup(SSL *s) X509_NAME *xn; SSL *ret; int i; - + if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL) return(NULL); @@ -2432,7 +2620,7 @@ EVP_PKEY *SSL_get_privatekey(SSL *s) return(NULL); } -SSL_CIPHER *SSL_get_current_cipher(const SSL *s) +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) { if ((s->session != NULL) && (s->session->cipher != NULL)) return(s->session->cipher); @@ -2510,7 +2698,7 @@ void ssl_free_wbio_buffer(SSL *s) s->wbio=BIO_pop(s->wbio); #ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */ assert(s->wbio != NULL); -#endif +#endif } BIO_free(s->bbio); s->bbio=NULL; @@ -2595,7 +2783,7 @@ void SSL_set_info_callback(SSL *ssl, /* One compiler (Diab DCC) doesn't like argument names in returned function pointer. */ -void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/) +void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/) { return ssl->info_callback; } @@ -2716,13 +2904,13 @@ RSA *cb(SSL *ssl,int is_export,int keylength) #ifndef OPENSSL_NO_DH void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export, - int keylength)) + int keylength)) { SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); } void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export, - int keylength)) + int keylength)) { SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); } @@ -2730,18 +2918,109 @@ void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export, #ifndef OPENSSL_NO_ECDH void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export, - int keylength)) + int keylength)) { SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh); } void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export, - int keylength)) + int keylength)) { SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh); } #endif +#ifndef OPENSSL_NO_PSK +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) + { + SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (ctx->psk_identity_hint != NULL) + OPENSSL_free(ctx->psk_identity_hint); + if (identity_hint != NULL) + { + ctx->psk_identity_hint = BUF_strdup(identity_hint); + if (ctx->psk_identity_hint == NULL) + return 0; + } + else + ctx->psk_identity_hint = NULL; + return 1; + } + +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) + { + if (s == NULL) + return 0; + + if (s->session == NULL) + return 1; /* session not created yet, ignored */ + + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) + { + SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + if (identity_hint != NULL) + { + s->session->psk_identity_hint = BUF_strdup(identity_hint); + if (s->session->psk_identity_hint == NULL) + return 0; + } + else + s->session->psk_identity_hint = NULL; + return 1; + } + +const char *SSL_get_psk_identity_hint(const SSL *s) + { + if (s == NULL || s->session == NULL) + return NULL; + return(s->session->psk_identity_hint); + } + +const char *SSL_get_psk_identity(const SSL *s) + { + if (s == NULL || s->session == NULL) + return NULL; + return(s->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, unsigned char *psk, + unsigned int max_psk_len)) + { + s->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, unsigned char *psk, + unsigned int max_psk_len)) + { + ctx->psk_client_callback = cb; + } + +void SSL_set_psk_server_callback(SSL *s, + unsigned int (*cb)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len)) + { + s->psk_server_callback = cb; + } + +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*cb)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len)) + { + ctx->psk_server_callback = cb; + } +#endif void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)) { @@ -2752,7 +3031,25 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); } +/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer + * vairable, freeing EVP_MD_CTX previously stored in that variable, if + * any. If EVP_MD pointer is passed, initializes ctx with this md + * Returns newly allocated ctx; + */ + +EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) +{ + ssl_clear_hash_ctx(hash); + *hash = EVP_MD_CTX_create(); + if (md) EVP_DigestInit_ex(*hash,md,NULL); + return *hash; +} +void ssl_clear_hash_ctx(EVP_MD_CTX **hash) +{ + if (*hash) EVP_MD_CTX_destroy(*hash); + *hash=NULL; +} #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) #include "../crypto/bio/bss_file.c" @@ -2760,3 +3057,6 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con IMPLEMENT_STACK_OF(SSL_CIPHER) IMPLEMENT_STACK_OF(SSL_COMP) +IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, + ssl_cipher_id); + diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h index e305db43ff..4c78393f3f 100644 --- a/crypto/openssl/ssl/ssl_locl.h +++ b/crypto/openssl/ssl/ssl_locl.h @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * 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 @@ -113,6 +113,32 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #ifndef HEADER_SSL_LOCL_H #define HEADER_SSL_LOCL_H @@ -251,58 +277,84 @@ * that the different entities within are mutually exclusive: * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. */ -#define SSL_MKEY_MASK 0x000000FFL + +/* Bits for algorithm_mkey (key exchange algorithm) */ #define SSL_kRSA 0x00000001L /* RSA key exchange */ -#define SSL_kDHr 0x00000002L /* DH cert RSA CA cert */ -#define SSL_kDHd 0x00000004L /* DH cert DSA CA cert */ -#define SSL_kFZA 0x00000008L -#define SSL_kEDH 0x00000010L /* tmp DH key no DH cert */ -#define SSL_kKRB5 0x00000020L /* Kerberos5 key exchange */ -#define SSL_kECDH 0x00000040L /* ECDH w/ long-term keys */ -#define SSL_kECDHE 0x00000080L /* ephemeral ECDH */ -#define SSL_EDH (SSL_kEDH|(SSL_AUTH_MASK^SSL_aNULL)) - -#define SSL_AUTH_MASK 0x00007F00L -#define SSL_aRSA 0x00000100L /* Authenticate with RSA */ -#define SSL_aDSS 0x00000200L /* Authenticate with DSS */ -#define SSL_DSS SSL_aDSS -#define SSL_aFZA 0x00000400L -#define SSL_aNULL 0x00000800L /* no Authenticate, ADH */ -#define SSL_aDH 0x00001000L /* no Authenticate, ADH */ -#define SSL_aKRB5 0x00002000L /* Authenticate with KRB5 */ -#define SSL_aECDSA 0x00004000L /* Authenticate with ECDSA */ - -#define SSL_NULL (SSL_eNULL) -#define SSL_ADH (SSL_kEDH|SSL_aNULL) -#define SSL_RSA (SSL_kRSA|SSL_aRSA) -#define SSL_DH (SSL_kDHr|SSL_kDHd|SSL_kEDH) -#define SSL_ECDH (SSL_kECDH|SSL_kECDHE) -#define SSL_FZA (SSL_aFZA|SSL_kFZA|SSL_eFZA) -#define SSL_KRB5 (SSL_kKRB5|SSL_aKRB5) - -#define SSL_ENC_MASK 0x1C3F8000L -#define SSL_DES 0x00008000L -#define SSL_3DES 0x00010000L -#define SSL_RC4 0x00020000L -#define SSL_RC2 0x00040000L -#define SSL_IDEA 0x00080000L -#define SSL_eFZA 0x00100000L -#define SSL_eNULL 0x00200000L -#define SSL_AES 0x04000000L -#define SSL_CAMELLIA 0x08000000L -#define SSL_SEED 0x10000000L - -#define SSL_MAC_MASK 0x00c00000L -#define SSL_MD5 0x00400000L -#define SSL_SHA1 0x00800000L -#define SSL_SHA (SSL_SHA1) - -#define SSL_SSL_MASK 0x03000000L -#define SSL_SSLV2 0x01000000L -#define SSL_SSLV3 0x02000000L +#define SSL_kDHr 0x00000002L /* DH cert, RSA CA cert */ /* no such ciphersuites supported! */ +#define SSL_kDHd 0x00000004L /* DH cert, DSA CA cert */ /* no such ciphersuite supported! */ +#define SSL_kEDH 0x00000008L /* tmp DH key no DH cert */ +#define SSL_kKRB5 0x00000010L /* Kerberos5 key exchange */ +#define SSL_kECDHr 0x00000020L /* ECDH cert, RSA CA cert */ +#define SSL_kECDHe 0x00000040L /* ECDH cert, ECDSA CA cert */ +#define SSL_kEECDH 0x00000080L /* ephemeral ECDH */ +#define SSL_kPSK 0x00000100L /* PSK */ +#define SSL_kGOST 0x00000200L /* GOST key exchange */ + +/* Bits for algorithm_auth (server authentication) */ +#define SSL_aRSA 0x00000001L /* RSA auth */ +#define SSL_aDSS 0x00000002L /* DSS auth */ +#define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */ +#define SSL_aDH 0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no such ciphersuites supported! */ +#define SSL_aECDH 0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */ +#define SSL_aKRB5 0x00000020L /* KRB5 auth */ +#define SSL_aECDSA 0x00000040L /* ECDSA auth*/ +#define SSL_aPSK 0x00000080L /* PSK auth */ +#define SSL_aGOST94 0x00000100L /* GOST R 34.10-94 signature auth */ +#define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */ + + +/* Bits for algorithm_enc (symmetric encryption) */ +#define SSL_DES 0x00000001L +#define SSL_3DES 0x00000002L +#define SSL_RC4 0x00000004L +#define SSL_RC2 0x00000008L +#define SSL_IDEA 0x00000010L +#define SSL_eNULL 0x00000020L +#define SSL_AES128 0x00000040L +#define SSL_AES256 0x00000080L +#define SSL_CAMELLIA128 0x00000100L +#define SSL_CAMELLIA256 0x00000200L +#define SSL_eGOST2814789CNT 0x00000400L +#define SSL_SEED 0x00000800L + +#define SSL_AES (SSL_AES128|SSL_AES256) +#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) + + +/* Bits for algorithm_mac (symmetric authentication) */ +#define SSL_MD5 0x00000001L +#define SSL_SHA1 0x00000002L +#define SSL_GOST94 0x00000004L +#define SSL_GOST89MAC 0x00000008L + +/* Bits for algorithm_ssl (protocol version) */ +#define SSL_SSLV2 0x00000001L +#define SSL_SSLV3 0x00000002L #define SSL_TLSV1 SSL_SSLV3 /* for now */ -/* we have used 1fffffff - 3 bits left to go. */ + +/* 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_GOST94 0x40 +#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) + +/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX + * make sure to update this constant too */ +#define SSL_MAX_DIGEST 4 + +#define TLS1_PRF_DGST_SHIFT 8 +#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) + +/* Stream MAC for GOST ciphersuites from cryptopro draft + * (currently this also goes into algorithm2) */ +#define TLS1_STREAM_MAC 0x04 + + /* * Export and cipher strength information. For each cipher we have to decide @@ -320,10 +372,11 @@ * be possible. */ #define SSL_EXP_MASK 0x00000003L +#define SSL_STRONG_MASK 0x000001fcL + #define SSL_NOT_EXP 0x00000001L #define SSL_EXPORT 0x00000002L -#define SSL_STRONG_MASK 0x000000fcL #define SSL_STRONG_NONE 0x00000004L #define SSL_EXP40 0x00000008L #define SSL_MICRO (SSL_EXP40) @@ -357,17 +410,14 @@ #define SSL_C_IS_EXPORT40(c) SSL_IS_EXPORT40((c)->algo_strength) #define SSL_EXPORT_KEYLENGTH(a,s) (SSL_IS_EXPORT40(s) ? 5 : \ - ((a)&SSL_ENC_MASK) == SSL_DES ? 8 : 7) + (a) == SSL_DES ? 8 : 7) #define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024) -#define SSL_C_EXPORT_KEYLENGTH(c) SSL_EXPORT_KEYLENGTH((c)->algorithms, \ +#define SSL_C_EXPORT_KEYLENGTH(c) SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \ (c)->algo_strength) #define SSL_C_EXPORT_PKEYLENGTH(c) SSL_EXPORT_PKEYLENGTH((c)->algo_strength) -#define SSL_ALL 0xffffffffL -#define SSL_ALL_CIPHERS (SSL_MKEY_MASK|SSL_AUTH_MASK|SSL_ENC_MASK|\ - SSL_MAC_MASK) -#define SSL_ALL_STRENGTHS (SSL_EXP_MASK|SSL_STRONG_MASK) + /* Mostly for SSLv3 */ #define SSL_PKEY_RSA_ENC 0 @@ -376,7 +426,9 @@ #define SSL_PKEY_DH_RSA 3 #define SSL_PKEY_DH_DSA 4 #define SSL_PKEY_ECC 5 -#define SSL_PKEY_NUM 6 +#define SSL_PKEY_GOST94 6 +#define SSL_PKEY_GOST01 7 +#define SSL_PKEY_NUM 8 /* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) @@ -417,8 +469,10 @@ typedef struct cert_st /* The following masks are for the key and auth * algorithms that are supported by the certs below */ int valid; - unsigned long mask; - unsigned long export_mask; + unsigned long mask_k; + unsigned long mask_a; + unsigned long export_mask_k; + unsigned long export_mask_a; #ifndef OPENSSL_NO_RSA RSA *rsa_tmp; RSA *(*rsa_tmp_cb)(SSL *ssl,int is_export,int keysize); @@ -492,9 +546,9 @@ typedef struct ssl3_enc_method int (*setup_key_block)(SSL *); int (*generate_master_secret)(SSL *, unsigned char *, unsigned char *, int); int (*change_cipher_state)(SSL *, int); - int (*final_finish_mac)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char *, int, unsigned char *); + int (*final_finish_mac)(SSL *, const char *, int, unsigned char *); int finish_mac_length; - int (*cert_verify_mac)(SSL *, EVP_MD_CTX *, unsigned char *); + int (*cert_verify_mac)(SSL *, int, unsigned char *); const char *client_finished_label; int client_finished_label_len; const char *server_finished_label; @@ -512,24 +566,35 @@ typedef struct ssl3_comp_st } SSL3_COMP; #endif +#ifndef OPENSSL_NO_BUF_FREELISTS +typedef struct ssl3_buf_freelist_st + { + size_t chunklen; + unsigned int len; + struct ssl3_buf_freelist_entry_st *head; + } SSL3_BUF_FREELIST; + +typedef struct ssl3_buf_freelist_entry_st + { + struct ssl3_buf_freelist_entry_st *next; + } SSL3_BUF_FREELIST_ENTRY; +#endif + extern SSL3_ENC_METHOD ssl3_undef_enc_method; -OPENSSL_EXTERN SSL_CIPHER ssl2_ciphers[]; +OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[]; OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[]; SSL_METHOD *ssl_bad_method(int ver); -SSL_METHOD *sslv2_base_method(void); -SSL_METHOD *sslv23_base_method(void); -SSL_METHOD *sslv3_base_method(void); extern SSL3_ENC_METHOD TLSv1_enc_data; extern SSL3_ENC_METHOD SSLv3_enc_data; extern SSL3_ENC_METHOD DTLSv1_enc_data; #define IMPLEMENT_tls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -SSL_METHOD *func_name(void) \ +const SSL_METHOD *func_name(void) \ { \ - static SSL_METHOD func_name##_data= { \ + static const SSL_METHOD func_name##_data= { \ TLS1_VERSION, \ tls1_new, \ tls1_clear, \ @@ -564,9 +629,9 @@ SSL_METHOD *func_name(void) \ } #define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -SSL_METHOD *func_name(void) \ +const SSL_METHOD *func_name(void) \ { \ - static SSL_METHOD func_name##_data= { \ + static const SSL_METHOD func_name##_data= { \ SSL3_VERSION, \ ssl3_new, \ ssl3_clear, \ @@ -601,9 +666,9 @@ SSL_METHOD *func_name(void) \ } #define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -SSL_METHOD *func_name(void) \ +const SSL_METHOD *func_name(void) \ { \ - static SSL_METHOD func_name##_data= { \ + static const SSL_METHOD func_name##_data= { \ TLS1_VERSION, \ tls1_new, \ tls1_clear, \ @@ -638,9 +703,9 @@ SSL_METHOD *func_name(void) \ } #define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -SSL_METHOD *func_name(void) \ +const SSL_METHOD *func_name(void) \ { \ - static SSL_METHOD func_name##_data= { \ + static const SSL_METHOD func_name##_data= { \ SSL2_VERSION, \ ssl2_new, /* local */ \ ssl2_clear, /* local */ \ @@ -675,9 +740,9 @@ SSL_METHOD *func_name(void) \ } #define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -SSL_METHOD *func_name(void) \ +const SSL_METHOD *func_name(void) \ { \ - static SSL_METHOD func_name##_data= { \ + static const SSL_METHOD func_name##_data= { \ DTLS1_VERSION, \ dtls1_new, \ dtls1_clear, \ @@ -723,6 +788,8 @@ int ssl_set_peer_cert_type(SESS_CERT *c, int type); int ssl_get_new_session(SSL *s, int session); int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit); int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b); +DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, + ssl_cipher_id); int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap, const SSL_CIPHER * const *bp); STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, @@ -735,15 +802,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, const char *rule_str); void ssl_update_cache(SSL *s, int mode); int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc, - const EVP_MD **md,SSL_COMP **comp); + const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp); +int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md); int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk); int ssl_undefined_function(SSL *s); int ssl_undefined_void_function(void); int ssl_undefined_const_function(const SSL *s); X509 *ssl_get_server_send_cert(SSL *); -EVP_PKEY *ssl_get_sign_pkey(SSL *,SSL_CIPHER *); +EVP_PKEY *ssl_get_sign_pkey(SSL *,const SSL_CIPHER *); int ssl_cert_type(X509 *x,EVP_PKEY *pkey); -void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher); +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); int ssl_verify_alarm_type(long type); void ssl_load_ciphers(void); @@ -752,7 +820,7 @@ int ssl2_enc_init(SSL *s, int client); int ssl2_generate_key_material(SSL *s); void ssl2_enc(SSL *s,int send_data); void ssl2_mac(SSL *s,unsigned char *mac,int send_data); -SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p); int ssl2_part_read(SSL *s, unsigned long f, int i); int ssl2_do_write(SSL *s); @@ -760,7 +828,7 @@ int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data); void ssl2_return_error(SSL *s,int reason); void ssl2_write_error(SSL *s); int ssl2_num_ciphers(void); -SSL_CIPHER *ssl2_get_cipher(unsigned int u); +const SSL_CIPHER *ssl2_get_cipher(unsigned int u); int ssl2_new(SSL *s); void ssl2_free(SSL *s); int ssl2_accept(SSL *s); @@ -777,7 +845,7 @@ long ssl2_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)(void)); int ssl2_pending(const SSL *s); long ssl2_default_timeout(void ); -SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p); void ssl3_init_finished_mac(SSL *s); int ssl3_send_server_certificate(SSL *s); @@ -796,22 +864,27 @@ int ssl3_get_req_cert_type(SSL *s,unsigned char *p); long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); int ssl3_send_finished(SSL *s, int a, int b, const char *sender,int slen); int ssl3_num_ciphers(void); -SSL_CIPHER *ssl3_get_cipher(unsigned int u); +const SSL_CIPHER *ssl3_get_cipher(unsigned int u); int ssl3_renegotiate(SSL *ssl); int ssl3_renegotiate_check(SSL *ssl); int ssl3_dispatch_alert(SSL *s); int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); -int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2, - const char *sender, int slen,unsigned char *p); -int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p); +int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,unsigned char *p); +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); int ssl3_enc(SSL *s, int send_data); -int ssl3_mac(SSL *ssl, unsigned char *md, int send_data); +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data); +void ssl3_free_digest_list(SSL *s); unsigned long ssl3_output_cert_chain(SSL *s, X509 *x); SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,STACK_OF(SSL_CIPHER) *clnt, STACK_OF(SSL_CIPHER) *srvr); int ssl3_setup_buffers(SSL *s); +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); +int ssl3_digest_cached_records(SSL *s); int ssl3_new(SSL *s); void ssl3_free(SSL *s); int ssl3_accept(SSL *s); @@ -832,12 +905,12 @@ int ssl3_do_change_cipher_spec(SSL *ssl); long ssl3_default_timeout(void ); int ssl23_num_ciphers(void ); -SSL_CIPHER *ssl23_get_cipher(unsigned int u); +const SSL_CIPHER *ssl23_get_cipher(unsigned int u); int ssl23_read(SSL *s, void *buf, int len); int ssl23_peek(SSL *s, void *buf, int len); int ssl23_write(SSL *s, const void *buf, int len); int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p); +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p); long ssl23_default_timeout(void ); long tls1_default_timeout(void); @@ -871,14 +944,13 @@ void dtls1_reset_seq_numbers(SSL *s, int rw); long dtls1_default_timeout(void); struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); int dtls1_handle_timeout(SSL *s); -SSL_CIPHER *dtls1_get_cipher(unsigned int u); +const SSL_CIPHER *dtls1_get_cipher(unsigned int u); void dtls1_start_timer(SSL *s); void dtls1_stop_timer(SSL *s); int dtls1_is_timer_expired(SSL *s); void dtls1_double_timeout(SSL *s); int dtls1_send_newsession_ticket(SSL *s); - /* some client-only functions */ int ssl3_client_hello(SSL *s); int ssl3_get_server_hello(SSL *s); @@ -887,8 +959,8 @@ int ssl3_get_new_session_ticket(SSL *s); int ssl3_get_cert_status(SSL *s); int ssl3_get_server_done(SSL *s); int ssl3_send_client_verify(SSL *s); -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); int ssl3_send_client_certificate(SSL *s); +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); int ssl3_send_client_key_exchange(SSL *s); int ssl3_get_key_exchange(SSL *s); int ssl3_get_server_certificate(SSL *s); @@ -933,7 +1005,6 @@ void tls1_free(SSL *s); void tls1_clear(SSL *s); long tls1_ctrl(SSL *s,int cmd, long larg, void *parg); long tls1_callback_ctrl(SSL *s,int cmd, void (*fp)(void)); -SSL_METHOD *tlsv1_base_method(void ); int dtls1_new(SSL *s); int dtls1_accept(SSL *s); @@ -941,7 +1012,6 @@ int dtls1_connect(SSL *s); void dtls1_free(SSL *s); void dtls1_clear(SSL *s); long dtls1_ctrl(SSL *s,int cmd, long larg, void *parg); -SSL_METHOD *dtlsv1_base_method(void ); long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); int dtls1_get_record(SSL *s); @@ -956,9 +1026,9 @@ void ssl_free_wbio_buffer(SSL *s); int tls1_change_cipher_state(SSL *s, int which); int tls1_setup_key_block(SSL *s); int tls1_enc(SSL *s, int snd); -int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx, +int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *p); -int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p); +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); int tls1_mac(SSL *ssl, unsigned char *md, int snd); int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, int len); @@ -966,10 +1036,17 @@ int tls1_alert_code(int code); int ssl3_alert_code(int code); int ssl_ok(SSL *s); -int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs); +#ifndef OPENSSL_NO_ECDH +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs); +#endif SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); +#ifndef OPENSSL_NO_EC +int tls1_ec_curve_id2nid(int curve_id); +int tls1_ec_nid2curve_id(int nid); +#endif /* OPENSSL_NO_EC */ + #ifndef OPENSSL_NO_TLSEXT unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); @@ -987,9 +1064,9 @@ int ssl_check_serverhello_tlsext(SSL *s); #endif int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, const unsigned char *limit, SSL_SESSION **ret); +#endif EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ; void ssl_clear_hash_ctx(EVP_MD_CTX **hash); - int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, int maxlen); int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, @@ -999,5 +1076,3 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, int *al); #endif - -#endif diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c index e7802e1d9e..8e5d8a0972 100644 --- a/crypto/openssl/ssl/ssl_sess.c +++ b/crypto/openssl/ssl/ssl_sess.c @@ -55,6 +55,85 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 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 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include @@ -127,8 +206,18 @@ SSL_SESSION *SSL_SESSION_new(void) ss->compress_meth=0; #ifndef OPENSSL_NO_TLSEXT ss->tlsext_hostname = NULL; +#ifndef OPENSSL_NO_EC + ss->tlsext_ecpointformatlist_length = 0; + ss->tlsext_ecpointformatlist = NULL; + ss->tlsext_ellipticcurvelist_length = 0; + ss->tlsext_ellipticcurvelist = NULL; +#endif #endif CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); +#ifndef OPENSSL_NO_PSK + ss->psk_identity_hint=NULL; + ss->psk_identity=NULL; +#endif return(ss); } @@ -183,10 +272,10 @@ int ssl_get_new_session(SSL *s, int session) if ((ss=SSL_SESSION_new()) == NULL) return(0); /* If the context has a default timeout, use it */ - if (s->ctx->session_timeout == 0) + if (s->session_ctx->session_timeout == 0) ss->timeout=SSL_get_default_timeout(s); else - ss->timeout=s->ctx->session_timeout; + ss->timeout=s->session_ctx->session_timeout; if (s->session != NULL) { @@ -239,8 +328,8 @@ int ssl_get_new_session(SSL *s, int session) CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); if(s->generate_session_id) cb = s->generate_session_id; - else if(s->ctx->generate_session_id) - cb = s->ctx->generate_session_id; + else if(s->session_ctx->generate_session_id) + cb = s->session_ctx->generate_session_id; CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); /* Choose a session ID */ tmp = ss->session_id_length; @@ -286,6 +375,32 @@ int ssl_get_new_session(SSL *s, int session) return 0; } } +#ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist) + { + if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist); + if ((ss->tlsext_ecpointformatlist = OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) == NULL) + { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(ss); + return 0; + } + ss->tlsext_ecpointformatlist_length = s->tlsext_ecpointformatlist_length; + memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length); + } + if (s->tlsext_ellipticcurvelist) + { + if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist); + if ((ss->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL) + { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(ss); + return 0; + } + ss->tlsext_ellipticcurvelist_length = s->tlsext_ellipticcurvelist_length; + memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length); + } +#endif #endif } else @@ -318,15 +433,15 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, #ifndef OPENSSL_NO_TLSEXT int r; #endif - + if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) goto err; #ifndef OPENSSL_NO_TLSEXT - r = tls1_process_ticket(s, session_id, len, limit, &ret); + r = tls1_process_ticket(s, session_id, len, limit, &ret); if (r == -1) { fatal = 1; - goto err; + goto err; } else if (r == 0 || (!ret && !len)) goto err; @@ -334,7 +449,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, #else if (len == 0) goto err; - if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) + if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) #endif { SSL_SESSION data; @@ -342,9 +457,9 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, data.session_id_length=len; if (len == 0) return 0; - memcpy(data.session_id,session_id,len); + memcpy(data.session_id,session_id,len); CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data); + ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data); if (ret != NULL) /* don't allow other threads to steal it: */ CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION); @@ -355,13 +470,13 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, { int copy=1; - s->ctx->stats.sess_miss++; + s->session_ctx->stats.sess_miss++; ret=NULL; - if (s->ctx->get_session_cb != NULL - && (ret=s->ctx->get_session_cb(s,session_id,len,©)) + if (s->session_ctx->get_session_cb != NULL + && (ret=s->session_ctx->get_session_cb(s,session_id,len,©)) != NULL) { - s->ctx->stats.sess_cb_hit++; + s->session_ctx->stats.sess_cb_hit++; /* Increment reference count now if the session callback * asks us to do so (note that if the session structures @@ -373,10 +488,10 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, /* Add the externally cached session to the internal * cache as well if and only if we are supposed to. */ - if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE)) + if(!(s->session_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->ctx,ret); + SSL_CTX_add_session(s->session_ctx,ret); } if (ret == NULL) goto err; @@ -443,13 +558,13 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */ { - s->ctx->stats.sess_timeout++; + s->session_ctx->stats.sess_timeout++; /* remove it from the cache */ - SSL_CTX_remove_session(s->ctx,ret); + SSL_CTX_remove_session(s->session_ctx,ret); goto err; } - s->ctx->stats.sess_hit++; + s->session_ctx->stats.sess_hit++; /* ret->time=time(NULL); */ /* rezero timeout? */ /* again, just leave the session @@ -482,7 +597,7 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) /* if session c is in already in cache, we take back the increment later */ CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - s=(SSL_SESSION *)lh_insert(ctx->sessions,c); + s=lh_SSL_SESSION_insert(ctx->sessions,c); /* 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 @@ -548,10 +663,10 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) if ((c != NULL) && (c->session_id_length != 0)) { if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c) + if ((r = lh_SSL_SESSION_retrieve(ctx->sessions,c)) == c) { ret=1; - r=(SSL_SESSION *)lh_delete(ctx->sessions,c); + r=lh_SSL_SESSION_delete(ctx->sessions,c); SSL_SESSION_list_remove(ctx,c); } @@ -601,6 +716,18 @@ void SSL_SESSION_free(SSL_SESSION *ss) #ifndef OPENSSL_NO_TLSEXT if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname); if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick); +#ifndef OPENSSL_NO_EC + ss->tlsext_ecpointformatlist_length = 0; + if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist); + ss->tlsext_ellipticcurvelist_length = 0; + if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist); +#endif /* OPENSSL_NO_EC */ +#endif +#ifndef OPENSSL_NO_PSK + if (ss->psk_identity_hint != NULL) + OPENSSL_free(ss->psk_identity_hint); + if (ss->psk_identity != NULL) + OPENSSL_free(ss->psk_identity); #endif OPENSSL_cleanse(ss,sizeof(*ss)); OPENSSL_free(ss); @@ -609,7 +736,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) int SSL_set_session(SSL *s, SSL_SESSION *session) { int ret=0; - SSL_METHOD *meth; + const SSL_METHOD *meth; if (session != NULL) { @@ -712,20 +839,75 @@ long SSL_CTX_get_timeout(const SSL_CTX *s) return(s->session_timeout); } +#ifndef OPENSSL_NO_TLSEXT +int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg) + { + if (s == NULL) return(0); + s->tls_session_secret_cb = tls_session_secret_cb; + s->tls_session_secret_cb_arg = arg; + return(1); + } + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg) + { + if (s == NULL) return(0); + s->tls_session_ticket_ext_cb = cb; + s->tls_session_ticket_ext_cb_arg = arg; + return(1); + } + +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) + { + if (s->version >= TLS1_VERSION) + { + if (s->tlsext_session_ticket) + { + OPENSSL_free(s->tlsext_session_ticket); + s->tlsext_session_ticket = NULL; + } + + s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); + if (!s->tlsext_session_ticket) + { + SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ext_data) + { + s->tlsext_session_ticket->length = ext_len; + s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; + memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); + } + else + { + s->tlsext_session_ticket->length = 0; + s->tlsext_session_ticket->data = NULL; + } + + return 1; + } + + return 0; + } +#endif /* OPENSSL_NO_TLSEXT */ + typedef struct timeout_param_st { SSL_CTX *ctx; long time; - LHASH *cache; + LHASH_OF(SSL_SESSION) *cache; } TIMEOUT_PARAM; -static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p) +static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) { if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */ { /* The reason we don't call SSL_CTX_remove_session() is to * save on locking overhead */ - lh_delete(p->cache,s); + (void)lh_SSL_SESSION_delete(p->cache,s); SSL_SESSION_list_remove(p->ctx,s); s->not_resumable=1; if (p->ctx->remove_session_cb != NULL) @@ -734,7 +916,7 @@ static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p) } } -static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION *, TIMEOUT_PARAM *) +static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) void SSL_CTX_flush_sessions(SSL_CTX *s, long t) { @@ -746,10 +928,11 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t) if (tp.cache == NULL) return; tp.time=t; CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - i=tp.cache->down_load; - tp.cache->down_load=0; - lh_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), &tp); - tp.cache->down_load=i; + i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0; + lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), + TIMEOUT_PARAM, &tp); + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i; CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); } @@ -909,3 +1092,4 @@ void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, ctx->app_verify_cookie_cb=cb; } +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) diff --git a/crypto/openssl/ssl/ssl_stat.c b/crypto/openssl/ssl/ssl_stat.c index e7509f0303..144b81e55f 100644 --- a/crypto/openssl/ssl/ssl_stat.c +++ b/crypto/openssl/ssl/ssl_stat.c @@ -55,6 +55,32 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include "ssl_locl.h" @@ -414,6 +440,12 @@ const char *SSL_alert_desc_string(int value) case TLS1_AD_INTERNAL_ERROR: str="IE"; break; case TLS1_AD_USER_CANCELLED: str="US"; break; case TLS1_AD_NO_RENEGOTIATION: str="NR"; break; + case TLS1_AD_UNSUPPORTED_EXTENSION: str="UE"; break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: str="CO"; break; + case TLS1_AD_UNRECOGNIZED_NAME: str="UN"; break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: str="BR"; break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: str="BH"; break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: str="UP"; break; default: str="UK"; break; } return(str); @@ -497,6 +529,24 @@ const char *SSL_alert_desc_string_long(int value) case TLS1_AD_NO_RENEGOTIATION: str="no renegotiation"; break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str="unsupported extension"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str="certificate unobtainable"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str="unrecognized name"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str="bad certificate status response"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str="bad certificate hash value"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str="unknown PSK identity"; + break; default: str="unknown"; break; } return(str); diff --git a/crypto/openssl/ssl/ssl_txt.c b/crypto/openssl/ssl/ssl_txt.c index 81c1361698..3122440e26 100644 --- a/crypto/openssl/ssl/ssl_txt.c +++ b/crypto/openssl/ssl/ssl_txt.c @@ -55,6 +55,32 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include @@ -155,6 +181,12 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) if (BIO_printf(bp,"%02X",x->krb5_client_princ[i]) <= 0) goto err; } #endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + if (BIO_puts(bp,"\n PSK identity: ") <= 0) goto err; + if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) goto err; + if (BIO_puts(bp,"\n PSK identity hint: ") <= 0) goto err; + if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err; +#endif #ifndef OPENSSL_NO_TLSEXT if (x->tlsext_tick_lifetime_hint) { @@ -170,12 +202,13 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) goto err; } #endif + #ifndef OPENSSL_NO_COMP if (x->compress_meth != 0) { SSL_COMP *comp = NULL; - ssl_cipher_get_evp(x,NULL,NULL,&comp); + ssl_cipher_get_evp(x,NULL,NULL,NULL,NULL,&comp); if (comp == NULL) { if (BIO_printf(bp,"\n Compression: %d",x->compress_meth) <= 0) goto err; diff --git a/crypto/openssl/ssl/t1_clnt.c b/crypto/openssl/ssl/t1_clnt.c index 4d1e198cdc..c87af17712 100644 --- a/crypto/openssl/ssl/t1_clnt.c +++ b/crypto/openssl/ssl/t1_clnt.c @@ -63,8 +63,8 @@ #include #include -static SSL_METHOD *tls1_get_client_method(int ver); -static SSL_METHOD *tls1_get_client_method(int ver) +static const SSL_METHOD *tls1_get_client_method(int ver); +static const SSL_METHOD *tls1_get_client_method(int ver) { if (ver == TLS1_VERSION) return(TLSv1_client_method()); diff --git a/crypto/openssl/ssl/t1_enc.c b/crypto/openssl/ssl/t1_enc.c index dab6e4485b..9719541f2b 100644 --- a/crypto/openssl/ssl/t1_enc.c +++ b/crypto/openssl/ssl/t1_enc.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * 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 @@ -108,6 +108,32 @@ * Hudson (tjh@cryptsoft.com). * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #include #include "ssl_locl.h" @@ -121,8 +147,14 @@ #include #endif -static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, - int sec_len, unsigned char *seed, int seed_len, +/* seed1 through seed5 are virtually concatenated */ +static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, + int sec_len, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, unsigned char *out, int olen) { int chunk,n; @@ -131,84 +163,133 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, HMAC_CTX ctx_tmp; unsigned char A1[EVP_MAX_MD_SIZE]; unsigned int A1_len; + int ret = 0; chunk=EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx_tmp); - HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); - HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); - HMAC_Update(&ctx,seed,seed_len); - HMAC_Final(&ctx,A1,&A1_len); + if (!HMAC_Init_ex(&ctx,sec,sec_len,md, NULL)) + goto err; + if (!HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL)) + goto err; + if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len)) + goto err; + if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len)) + goto err; + if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len)) + goto err; + if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len)) + goto err; + if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len)) + goto err; + if (!HMAC_Final(&ctx,A1,&A1_len)) + goto err; n=0; for (;;) { - HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */ - HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */ - HMAC_Update(&ctx,A1,A1_len); - HMAC_Update(&ctx_tmp,A1,A1_len); - HMAC_Update(&ctx,seed,seed_len); + if (!HMAC_Init_ex(&ctx,NULL,0,NULL,NULL)) /* re-init */ + goto err; + if (!HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL)) /* re-init */ + goto err; + if (!HMAC_Update(&ctx,A1,A1_len)) + goto err; + if (!HMAC_Update(&ctx_tmp,A1,A1_len)) + goto err; + if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len)) + goto err; + if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len)) + goto err; + if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len)) + goto err; + if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len)) + goto err; + if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len)) + goto err; if (olen > chunk) { - HMAC_Final(&ctx,out,&j); + if (!HMAC_Final(&ctx,out,&j)) + goto err; out+=j; olen-=j; - HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */ + if (!HMAC_Final(&ctx_tmp,A1,&A1_len)) /* calc the next A1 value */ + goto err; } else /* last one */ { - HMAC_Final(&ctx,A1,&A1_len); + if (!HMAC_Final(&ctx,A1,&A1_len)) + goto err; memcpy(out,A1,olen); break; } } + ret = 1; +err: HMAC_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&ctx_tmp); OPENSSL_cleanse(A1,sizeof(A1)); + return ret; } -static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1, - unsigned char *label, int label_len, - const unsigned char *sec, int slen, unsigned char *out1, +/* seed1 through seed5 are virtually concatenated */ +static int tls1_PRF(long digest_mask, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, + const unsigned char *sec, int slen, + unsigned char *out1, unsigned char *out2, int olen) { - int len,i; - const unsigned char *S1,*S2; - - len=slen/2; + int len,i,idx,count; + const unsigned char *S1; + long m; + const EVP_MD *md; + int ret = 0; + + /* Count number of digests and partition sec evenly */ + count=0; + for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) { + if ((m<s3->server_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - - tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf), + int ret; + ret = tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE, + s->s3->server_random,SSL3_RANDOM_SIZE, + s->s3->client_random,SSL3_RANDOM_SIZE, + NULL,0,NULL,0, s->session->master_key,s->session->master_key_length, km,tmp,num); #ifdef KSSL_DEBUG @@ -222,14 +303,14 @@ static void tls1_generate_key_block(SSL *s, unsigned char *km, } printf("\n"); } #endif /* KSSL_DEBUG */ + return ret; } int tls1_change_cipher_state(SSL *s, int which) { static const unsigned char empty[]=""; unsigned char *p,*key_block,*mac_secret; - unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+ - SSL3_RANDOM_SIZE*2]; + unsigned char *exp_label; unsigned char tmp1[EVP_MAX_KEY_LENGTH]; unsigned char tmp2[EVP_MAX_KEY_LENGTH]; unsigned char iv1[EVP_MAX_IV_LENGTH*2]; @@ -242,12 +323,17 @@ int tls1_change_cipher_state(SSL *s, int which) const SSL_COMP *comp; #endif const EVP_MD *m; + int mac_type; + int *mac_secret_size; + EVP_MD_CTX *mac_ctx; + EVP_PKEY *mac_key; int is_export,n,i,j,k,exp_label_len,cl; int reuse_dd = 0; is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; + mac_type = s->s3->tmp.new_mac_pkey_type; #ifndef OPENSSL_NO_COMP comp=s->s3->tmp.new_compression; #endif @@ -255,21 +341,28 @@ int tls1_change_cipher_state(SSL *s, int which) #ifdef KSSL_DEBUG printf("tls1_change_cipher_state(which= %d) w/\n", which); - printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms, - (void *)comp); - printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)c); + printf("\talg= %ld/%ld, comp= %p\n", + s->s3->tmp.new_cipher->algorithm_mkey, + s->s3->tmp.new_cipher->algorithm_auth, + comp); + printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", c->nid,c->block_size,c->key_len,c->iv_len); printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); { - int ki; - for (ki=0; kis3->tmp.key_block_length; ki++) - printf("%02x", key_block[ki]); printf("\n"); + int i; + for (i=0; is3->tmp.key_block_length; i++) + printf("%02x", key_block[i]); printf("\n"); } #endif /* KSSL_DEBUG */ if (which & SSL3_CC_READ) { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; + if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) @@ -278,7 +371,7 @@ int tls1_change_cipher_state(SSL *s, int which) /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; - s->read_hash=m; + mac_ctx=ssl_replace_hash(&s->read_hash,NULL); #ifndef OPENSSL_NO_COMP if (s->expand != NULL) { @@ -304,9 +397,14 @@ int tls1_change_cipher_state(SSL *s, int which) if (s->version != DTLS1_VERSION) memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); + mac_secret_size=&(s->s3->read_mac_secret_size); } else { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) @@ -315,7 +413,7 @@ int tls1_change_cipher_state(SSL *s, int which) /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; - s->write_hash=m; + mac_ctx = ssl_replace_hash(&s->write_hash,NULL); #ifndef OPENSSL_NO_COMP if (s->compress != NULL) { @@ -336,13 +434,15 @@ int tls1_change_cipher_state(SSL *s, int which) if (s->version != DTLS1_VERSION) memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); + mac_secret_size = &(s->s3->write_mac_secret_size); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p=s->s3->tmp.key_block; - i=EVP_MD_size(m); + i=*mac_secret_size=s->s3->tmp.new_mac_secret_size; + cl=EVP_CIPHER_key_length(c); j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; @@ -378,6 +478,10 @@ int tls1_change_cipher_state(SSL *s, int which) } memcpy(mac_secret,ms,i); + mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, + mac_secret,*mac_secret_size); + EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key); + EVP_PKEY_free(mac_key); #ifdef TLS_DEBUG printf("which = %04X\nmac key=",which); { int z; for (z=0; zs3->tmp.key_block_length != 0) return(1); - if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) + if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp)) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); @@ -474,20 +573,27 @@ int tls1_setup_key_block(SSL *s) s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; - - num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); + s->s3->tmp.new_mac_pkey_type = mac_type; + s->s3->tmp.new_mac_secret_size = mac_secret_size; + num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) + { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); goto err; - if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) - goto err; + } s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p1; + if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) + { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); + goto err; + } #ifdef TLS_DEBUG printf("client random\n"); @@ -497,9 +603,8 @@ printf("server random\n"); printf("pre-master\n"); { int z; for (z=0; zsession->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif - tls1_generate_key_block(s,p1,p2,num); - OPENSSL_cleanse(p2,num); - OPENSSL_free(p2); + if (!tls1_generate_key_block(s,p1,p2,num)) + goto err; #ifdef TLS_DEBUG printf("\nkey block\n"); { int z; for (z=0; zsession->cipher != NULL) { - if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) + if (s->session->cipher->algorithm_enc == SSL_eNULL) s->s3->need_empty_fragments = 0; #ifndef OPENSSL_NO_RC4 - if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) + if (s->session->cipher->algorithm_enc == SSL_RC4) s->s3->need_empty_fragments = 0; #endif } } - return(1); + ret = 1; err: - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); - return(0); + if (p2) + { + OPENSSL_cleanse(p2,num); + OPENSSL_free(p2); + } + return(ret); } int tls1_enc(SSL *s, int send) @@ -540,8 +649,11 @@ int tls1_enc(SSL *s, int send) if (send) { - if (s->write_hash != NULL) - n=EVP_MD_size(s->write_hash); + if (EVP_MD_CTX_md(s->write_hash)) + { + n=EVP_MD_CTX_size(s->write_hash); + OPENSSL_assert(n >= 0); + } ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) @@ -551,8 +663,11 @@ int tls1_enc(SSL *s, int send) } else { - if (s->read_hash != NULL) - n=EVP_MD_size(s->read_hash); + if (EVP_MD_CTX_md(s->read_hash)) + { + n=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(n >= 0); + } ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) @@ -599,11 +714,10 @@ int tls1_enc(SSL *s, int send) { unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - (void *)ds,rec->data,rec->input,l); - printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", + ds,rec->data,rec->input,l); + printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", ds->buf_len, ds->cipher->key_len, - (unsigned long)DES_KEY_SZ, - (unsigned long)DES_SCHEDULE_SZ, + DES_KEY_SZ, DES_SCHEDULE_SZ, ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; icipher->iv_len; i++) printf("%02X", ds->iv[i]); @@ -628,10 +742,10 @@ int tls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long ki; + unsigned long i; printf("\trec->data="); - for (ki=0; kidata[ki]); printf("\n"); + for (i=0; idata[i]); printf("\n"); } #endif /* KSSL_DEBUG */ @@ -679,56 +793,101 @@ int tls1_enc(SSL *s, int send) } return(1); } - -int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out) +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) { unsigned int ret; - EVP_MD_CTX ctx; + EVP_MD_CTX ctx, *d=NULL; + int i; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + for (i=0;is3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) + { + d=s->s3->handshake_dgst[i]; + break; + } + } + if (!d) { + SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC,SSL_R_NO_REQUIRED_DIGEST); + return 0; + } EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_copy_ex(&ctx,in_ctx); + EVP_MD_CTX_copy_ex(&ctx,d); EVP_DigestFinal_ex(&ctx,out,&ret); EVP_MD_CTX_cleanup(&ctx); return((int)ret); } -int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx, +int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out) { unsigned int i; EVP_MD_CTX ctx; - unsigned char buf[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; + unsigned char buf[2*EVP_MAX_MD_SIZE]; unsigned char *q,buf2[12]; + int idx; + long mask; + int err=0; + const EVP_MD *md; q=buf; - memcpy(q,str,slen); - q+=slen; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_copy_ex(&ctx,in1_ctx); - EVP_DigestFinal_ex(&ctx,q,&i); - q+=i; - EVP_MD_CTX_copy_ex(&ctx,in2_ctx); - EVP_DigestFinal_ex(&ctx,q,&i); - q+=i; - - tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf), - s->session->master_key,s->session->master_key_length, - out,buf2,sizeof buf2); + + for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++) + { + if (mask & s->s3->tmp.new_cipher->algorithm2) + { + int hashsize = EVP_MD_size(md); + if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) + { + /* internal error: 'buf' is too small for this cipersuite! */ + err = 1; + } + else + { + EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]); + EVP_DigestFinal_ex(&ctx,q,&i); + if (i != (unsigned int)hashsize) /* can't really happen */ + err = 1; + q+=i; + } + } + } + + if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0, + s->session->master_key,s->session->master_key_length, + out,buf2,sizeof buf2)) + err = 1; EVP_MD_CTX_cleanup(&ctx); - return sizeof buf2; + if (err) + return 0; + else + return sizeof buf2; } int tls1_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *mac_sec,*seq; - const EVP_MD *hash; - unsigned int md_size; + EVP_MD_CTX *hash; + size_t md_size; int i; - HMAC_CTX hmac; + EVP_MD_CTX hmac, *mac_ctx; unsigned char buf[5]; + int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); + int t; if (send) { @@ -745,43 +904,45 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) hash=ssl->read_hash; } - md_size=EVP_MD_size(hash); + t=EVP_MD_CTX_size(hash); + OPENSSL_assert(t >= 0); + md_size=t; buf[0]=rec->type; - if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) - { - buf[1]=TLS1_VERSION_MAJOR; - buf[2]=TLS1_VERSION_MINOR; - } - else { - buf[1]=(unsigned char)(ssl->version>>8); - buf[2]=(unsigned char)(ssl->version); - } - + buf[1]=(unsigned char)(ssl->version>>8); + buf[2]=(unsigned char)(ssl->version); buf[3]=rec->length>>8; buf[4]=rec->length&0xff; /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ - HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); + if (stream_mac) + { + mac_ctx = hash; + } + else + { + EVP_MD_CTX_copy(&hmac,hash); + mac_ctx = &hmac; + } - if (ssl->version == DTLS1_BAD_VER || - (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER)) + if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER) { unsigned char dtlsseq[8],*p=dtlsseq; + s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); memcpy (p,&seq[2],6); - HMAC_Update(&hmac,dtlsseq,8); + EVP_DigestSignUpdate(mac_ctx,dtlsseq,8); } else - HMAC_Update(&hmac,seq,8); - - HMAC_Update(&hmac,buf,5); - HMAC_Update(&hmac,rec->input,rec->length); - HMAC_Final(&hmac,md,&md_size); - HMAC_CTX_cleanup(&hmac); + EVP_DigestSignUpdate(mac_ctx,seq,8); + EVP_DigestSignUpdate(mac_ctx,buf,5); + EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); + t=EVP_DigestSignFinal(mac_ctx,md,&md_size); + OPENSSL_assert(t > 0); + + if (!stream_mac) EVP_MD_CTX_cleanup(&hmac); #ifdef TLS_DEBUG printf("sec="); {unsigned int z; for (z=0; zversion != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER) { for (i=7; i>=0; i--) { @@ -811,23 +972,35 @@ printf("rec="); int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, int len) { - unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE]; unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; + const void *co = NULL, *so = NULL; + int col = 0, sol = 0; #ifdef KSSL_DEBUG - printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", (void *)s,out, p,len); + printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len); #endif /* KSSL_DEBUG */ - /* Setup the stuff to munge */ - memcpy(buf,TLS_MD_MASTER_SECRET_CONST, - TLS_MD_MASTER_SECRET_CONST_SIZE); - memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]), - s->s3->client_random,SSL3_RANDOM_SIZE); - memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]), - s->s3->server_random,SSL3_RANDOM_SIZE); - tls1_PRF(s->ctx->md5,s->ctx->sha1, - buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len, +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL && s->s3->server_opaque_prf_input != NULL && + s->s3->client_opaque_prf_input_len > 0 && + s->s3->client_opaque_prf_input_len == s->s3->server_opaque_prf_input_len) + { + co = s->s3->client_opaque_prf_input; + col = s->s3->server_opaque_prf_input_len; + so = s->s3->server_opaque_prf_input; + sol = s->s3->client_opaque_prf_input_len; /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */ + } +#endif + + tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE, + s->s3->client_random,SSL3_RANDOM_SIZE, + co, col, + s->s3->server_random,SSL3_RANDOM_SIZE, + so, sol, + p,len, s->session->master_key,buff,sizeof buff); + #ifdef KSSL_DEBUG printf ("tls1_generate_master_secret() complete\n"); #endif /* KSSL_DEBUG */ @@ -862,7 +1035,13 @@ int tls1_alert_code(int code) case SSL_AD_INTERNAL_ERROR: return(TLS1_AD_INTERNAL_ERROR); case SSL_AD_USER_CANCELLED: return(TLS1_AD_USER_CANCELLED); case SSL_AD_NO_RENEGOTIATION: return(TLS1_AD_NO_RENEGOTIATION); -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE); + case SSL_AD_UNRECOGNIZED_NAME: return(TLS1_AD_UNRECOGNIZED_NAME); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); + case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); +#if 0 /* not appropriate for TLS, not used for DTLS */ case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); #endif diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c index 8b53112770..e8bc34c111 100644 --- a/crypto/openssl/ssl/t1_lib.c +++ b/crypto/openssl/ssl/t1_lib.c @@ -55,6 +55,59 @@ * 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 #include @@ -92,11 +145,6 @@ long tls1_default_timeout(void) return(60*60*2); } -IMPLEMENT_tls1_meth_func(tlsv1_base_method, - ssl_undefined_function, - ssl_undefined_function, - ssl_bad_method) - int tls1_new(SSL *s) { if (!ssl3_new(s)) return(0); @@ -106,6 +154,12 @@ int tls1_new(SSL *s) void tls1_free(SSL *s) { +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_session_ticket) + { + OPENSSL_free(s->tlsext_session_ticket); + } +#endif /* OPENSSL_NO_TLSEXT */ ssl3_free(s); } @@ -115,17 +169,105 @@ void tls1_clear(SSL *s) s->version=TLS1_VERSION; } -#if 0 -long tls1_ctrl(SSL *s, int cmd, long larg, char *parg) +#ifndef OPENSSL_NO_EC +static int nid_list[] = + { + NID_sect163k1, /* sect163k1 (1) */ + NID_sect163r1, /* sect163r1 (2) */ + NID_sect163r2, /* sect163r2 (3) */ + NID_sect193r1, /* sect193r1 (4) */ + NID_sect193r2, /* sect193r2 (5) */ + NID_sect233k1, /* sect233k1 (6) */ + NID_sect233r1, /* sect233r1 (7) */ + NID_sect239k1, /* sect239k1 (8) */ + NID_sect283k1, /* sect283k1 (9) */ + NID_sect283r1, /* sect283r1 (10) */ + NID_sect409k1, /* sect409k1 (11) */ + NID_sect409r1, /* sect409r1 (12) */ + NID_sect571k1, /* sect571k1 (13) */ + NID_sect571r1, /* sect571r1 (14) */ + NID_secp160k1, /* secp160k1 (15) */ + NID_secp160r1, /* secp160r1 (16) */ + NID_secp160r2, /* secp160r2 (17) */ + NID_secp192k1, /* secp192k1 (18) */ + NID_X9_62_prime192v1, /* secp192r1 (19) */ + NID_secp224k1, /* secp224k1 (20) */ + NID_secp224r1, /* secp224r1 (21) */ + NID_secp256k1, /* secp256k1 (22) */ + NID_X9_62_prime256v1, /* secp256r1 (23) */ + NID_secp384r1, /* secp384r1 (24) */ + NID_secp521r1 /* secp521r1 (25) */ + }; + +int tls1_ec_curve_id2nid(int curve_id) { - return(0); + /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ + if ((curve_id < 1) || ((unsigned int)curve_id > + sizeof(nid_list)/sizeof(nid_list[0]))) + return 0; + return nid_list[curve_id-1]; } -long tls1_callback_ctrl(SSL *s, int cmd, void *(*fp)()) +int tls1_ec_nid2curve_id(int nid) { - return(0); + /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ + switch (nid) + { + case NID_sect163k1: /* sect163k1 (1) */ + return 1; + case NID_sect163r1: /* sect163r1 (2) */ + return 2; + case NID_sect163r2: /* sect163r2 (3) */ + return 3; + case NID_sect193r1: /* sect193r1 (4) */ + return 4; + case NID_sect193r2: /* sect193r2 (5) */ + return 5; + case NID_sect233k1: /* sect233k1 (6) */ + return 6; + case NID_sect233r1: /* sect233r1 (7) */ + return 7; + case NID_sect239k1: /* sect239k1 (8) */ + return 8; + case NID_sect283k1: /* sect283k1 (9) */ + return 9; + case NID_sect283r1: /* sect283r1 (10) */ + return 10; + case NID_sect409k1: /* sect409k1 (11) */ + return 11; + case NID_sect409r1: /* sect409r1 (12) */ + return 12; + case NID_sect571k1: /* sect571k1 (13) */ + return 13; + case NID_sect571r1: /* sect571r1 (14) */ + return 14; + case NID_secp160k1: /* secp160k1 (15) */ + return 15; + case NID_secp160r1: /* secp160r1 (16) */ + return 16; + case NID_secp160r2: /* secp160r2 (17) */ + return 17; + case NID_secp192k1: /* secp192k1 (18) */ + return 18; + case NID_X9_62_prime192v1: /* secp192r1 (19) */ + return 19; + case NID_secp224k1: /* secp224k1 (20) */ + return 20; + case NID_secp224r1: /* secp224r1 (21) */ + return 21; + case NID_secp256k1: /* secp256k1 (22) */ + return 22; + case NID_X9_62_prime256v1: /* secp256r1 (23) */ + return 23; + case NID_secp384r1: /* secp384r1 (24) */ + return 24; + case NID_secp521r1: /* secp521r1 (25) */ + return 25; + default: + return 0; + } } -#endif +#endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_TLSEXT unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) @@ -157,7 +299,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha */ if ((lenmax = limit - ret - 9) < 0 - || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) + || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) return NULL; /* extension type and length */ @@ -172,9 +314,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha s2n(size_str,ret); memcpy(ret, s->tlsext_hostname, size_str); ret+=size_str; - } - + /* Add RI if renegotiating */ if (s->new_session) { @@ -200,19 +341,81 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha ret += el; } - +#ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist != NULL && + s->version != DTLS1_VERSION) + { + /* Add TLS extension ECPointFormats to the ClientHello message */ + long lenmax; + + if ((lenmax = limit - ret - 5) < 0) return NULL; + if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL; + if (s->tlsext_ecpointformatlist_length > 255) + { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_ec_point_formats,ret); + s2n(s->tlsext_ecpointformatlist_length + 1,ret); + *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length; + memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length); + ret+=s->tlsext_ecpointformatlist_length; + } + if (s->tlsext_ellipticcurvelist != NULL && + s->version != DTLS1_VERSION) + { + /* Add TLS extension EllipticCurves to the ClientHello message */ + long lenmax; + + if ((lenmax = limit - ret - 6) < 0) return NULL; + if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL; + if (s->tlsext_ellipticcurvelist_length > 65532) + { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_elliptic_curves,ret); + s2n(s->tlsext_ellipticcurvelist_length + 2, ret); + + /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for + * elliptic_curve_list, but the examples use two bytes. + * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html + * resolves this to two bytes. + */ + s2n(s->tlsext_ellipticcurvelist_length, ret); + memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length); + ret+=s->tlsext_ellipticcurvelist_length; + } +#endif /* OPENSSL_NO_EC */ + if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { int ticklen; if (!s->new_session && s->session && s->session->tlsext_tick) ticklen = s->session->tlsext_ticklen; + else if (s->session && s->tlsext_session_ticket && + s->tlsext_session_ticket->data) + { + ticklen = s->tlsext_session_ticket->length; + s->session->tlsext_tick = OPENSSL_malloc(ticklen); + if (!s->session->tlsext_tick) + return NULL; + memcpy(s->session->tlsext_tick, + s->tlsext_session_ticket->data, + ticklen); + s->session->tlsext_ticklen = ticklen; + } else ticklen = 0; + if (ticklen == 0 && s->tlsext_session_ticket && + s->tlsext_session_ticket->data == NULL) + goto skip_ext; /* Check for enough room 2 for extension type, 2 for len * rest for ticket */ - if (limit - ret - 4 - ticklen < 0) - return NULL; + if ((long)(limit - ret - 4 - ticklen) < 0) return NULL; s2n(TLSEXT_TYPE_session_ticket,ret); s2n(ticklen,ret); if (ticklen) @@ -221,6 +424,26 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha ret += ticklen; } } + skip_ext: + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL && + s->version != DTLS1_VERSION) + { + size_t col = s->s3->client_opaque_prf_input_len; + + if ((long)(limit - ret - 6 - col < 0)) + return NULL; + if (col > 0xFFFD) /* can't happen */ + return NULL; + + s2n(TLSEXT_TYPE_opaque_prf_input, ret); + s2n(col + 2, ret); + s2n(col, ret); + memcpy(ret, s->s3->client_opaque_prf_input, col); + ret += col; + } +#endif if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && s->version != DTLS1_VERSION) @@ -292,7 +515,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL) { - if (limit - ret - 4 < 0) return NULL; + if ((long)(limit - ret - 4) < 0) return NULL; s2n(TLSEXT_TYPE_server_name,ret); s2n(0,ret); @@ -321,11 +544,36 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha ret += el; } - + +#ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist != NULL && + s->version != DTLS1_VERSION) + { + /* Add TLS extension ECPointFormats to the ServerHello message */ + long lenmax; + + if ((lenmax = limit - ret - 5) < 0) return NULL; + if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL; + if (s->tlsext_ecpointformatlist_length > 255) + { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_ec_point_formats,ret); + s2n(s->tlsext_ecpointformatlist_length + 1,ret); + *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length; + memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length); + ret+=s->tlsext_ecpointformatlist_length; + + } + /* Currently the server should not respond with a SupportedCurves extension */ +#endif /* OPENSSL_NO_EC */ + if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - if (limit - ret - 4 < 0) return NULL; + if ((long)(limit - ret - 4) < 0) return NULL; s2n(TLSEXT_TYPE_session_ticket,ret); s2n(0,ret); } @@ -337,6 +585,39 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha s2n(0,ret); } +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->server_opaque_prf_input != NULL && + s->version != DTLS1_VERSION) + { + size_t sol = s->s3->server_opaque_prf_input_len; + + if ((long)(limit - ret - 6 - sol) < 0) + return NULL; + if (sol > 0xFFFD) /* can't happen */ + return NULL; + + s2n(TLSEXT_TYPE_opaque_prf_input, ret); + s2n(sol + 2, ret); + s2n(sol, ret); + memcpy(ret, s->s3->server_opaque_prf_input, sol); + ret += sol; + } +#endif + if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) + && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) + { const unsigned char cryptopro_ext[36] = { + 0xfd, 0xe8, /*65000*/ + 0x00, 0x20, /*32 bytes length*/ + 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, + 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, + 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17}; + if (limit-ret<36) return NULL; + memcpy(ret,cryptopro_ext,36); + ret+=36; + + } + if ((extdatalen = ret-p-2)== 0) return p; @@ -357,7 +638,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in if (data >= (d+n-2)) goto ri_check; - n2s(data,len); if (data > (d+n-len)) @@ -370,7 +650,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in if (data+size > (d+n)) goto ri_check; - +#if 0 + fprintf(stderr,"Received extension type %d size %d\n",type,size); +#endif if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); @@ -470,6 +752,106 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } } + +#ifndef OPENSSL_NO_EC + else if (type == TLSEXT_TYPE_ec_point_formats && + s->version != DTLS1_VERSION) + { + unsigned char *sdata = data; + int ecpointformatlist_length = *(sdata++); + + if (ecpointformatlist_length != size - 1) + { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = 0; + if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); + if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); +#if 0 + fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length); + sdata = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + fprintf(stderr,"%i ",*(sdata++)); + fprintf(stderr,"\n"); +#endif + } + else if (type == TLSEXT_TYPE_elliptic_curves && + s->version != DTLS1_VERSION) + { + unsigned char *sdata = data; + int ellipticcurvelist_length = (*(sdata++) << 8); + ellipticcurvelist_length += (*(sdata++)); + + if (ellipticcurvelist_length != size - 2) + { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = 0; + if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist); + if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; + memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); +#if 0 + fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length); + sdata = s->session->tlsext_ellipticcurvelist; + for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) + fprintf(stderr,"%i ",*(sdata++)); + fprintf(stderr,"\n"); +#endif + } +#endif /* OPENSSL_NO_EC */ +#ifdef TLSEXT_TYPE_opaque_prf_input + else if (type == TLSEXT_TYPE_opaque_prf_input && + s->version != DTLS1_VERSION) + { + unsigned char *sdata = data; + + if (size < 2) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, s->s3->client_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input_len != size - 2) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */ + OPENSSL_free(s->s3->client_opaque_prf_input); + if (s->s3->client_opaque_prf_input_len == 0) + s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */ + else + s->s3->client_opaque_prf_input = BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } +#endif + else if (type == TLSEXT_TYPE_session_ticket) + { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg)) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } else if (type == TLSEXT_TYPE_renegotiate) { if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) @@ -578,9 +960,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } /* session ticket processed earlier */ - - data+=size; + data+=size; } + *p = data; ri_check: @@ -634,8 +1016,46 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } tlsext_servername = 1; } + +#ifndef OPENSSL_NO_EC + else if (type == TLSEXT_TYPE_ec_point_formats && + s->version != DTLS1_VERSION) + { + unsigned char *sdata = data; + int ecpointformatlist_length = *(sdata++); + + if (ecpointformatlist_length != size - 1) + { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = 0; + if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); + if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); +#if 0 + fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); + sdata = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + fprintf(stderr,"%i ",*(sdata++)); + fprintf(stderr,"\n"); +#endif + } +#endif /* OPENSSL_NO_EC */ + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg)) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } if ((SSL_get_options(s) & SSL_OP_NO_TICKET) || (size > 0)) { @@ -644,6 +1064,38 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } s->tlsext_ticket_expected = 1; } +#ifdef TLSEXT_TYPE_opaque_prf_input + else if (type == TLSEXT_TYPE_opaque_prf_input && + s->version != DTLS1_VERSION) + { + unsigned char *sdata = data; + + if (size < 2) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, s->s3->server_opaque_prf_input_len); + if (s->s3->server_opaque_prf_input_len != size - 2) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */ + OPENSSL_free(s->s3->server_opaque_prf_input); + if (s->s3->server_opaque_prf_input_len == 0) + s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */ + else + s->s3->server_opaque_prf_input = BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); + + if (s->s3->server_opaque_prf_input == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } +#endif else if (type == TLSEXT_TYPE_status_request && s->version != DTLS1_VERSION) { @@ -718,11 +1170,142 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in return 1; } + +int ssl_prepare_clienthello_tlsext(SSL *s) + { +#ifndef OPENSSL_NO_EC + /* If we are client and using an elliptic curve cryptography cipher suite, send the point formats + * and elliptic curves we support. + */ + int using_ecc = 0; + int i; + unsigned char *j; + unsigned long 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++) + { + SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA))) + { + using_ecc = 1; + break; + } + } + using_ecc = using_ecc && (s->version == TLS1_VERSION); + if (using_ecc) + { + if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist); + if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL) + { + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE); + return -1; + } + s->tlsext_ecpointformatlist_length = 3; + s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed; + s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + + /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */ + if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist); + s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2; + if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL) + { + s->tlsext_ellipticcurvelist_length = 0; + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE); + return -1; + } + for (i = 1, j = s->tlsext_ellipticcurvelist; (unsigned int)i <= + sizeof(nid_list)/sizeof(nid_list[0]); i++) + s2n(i,j); + } +#endif /* OPENSSL_NO_EC */ + +#ifdef TLSEXT_TYPE_opaque_prf_input + { + int r = 1; + + if (s->ctx->tlsext_opaque_prf_input_callback != 0) + { + r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg); + if (!r) + return -1; + } + + if (s->tlsext_opaque_prf_input != NULL) + { + if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */ + OPENSSL_free(s->s3->client_opaque_prf_input); + + if (s->tlsext_opaque_prf_input_len == 0) + s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */ + else + s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input == NULL) + { + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE); + return -1; + } + s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len; + } + + if (r == 2) + /* at callback's request, insist on receiving an appropriate server opaque PRF input */ + s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len; + } +#endif + + return 1; + } + +int ssl_prepare_serverhello_tlsext(SSL *s) + { +#ifndef OPENSSL_NO_EC + /* If we are server and using an ECC cipher suite, send the point formats we support + * if the client sent us an ECPointsFormat extension. Note that the server is not + * supposed to send an EllipticCurves extension. + */ + + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA); + using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); + + if (using_ecc) + { + if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist); + if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL) + { + SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE); + return -1; + } + s->tlsext_ecpointformatlist_length = 3; + s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed; + s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + } +#endif /* OPENSSL_NO_EC */ + + return 1; + } + int ssl_check_clienthello_tlsext(SSL *s) { int ret=SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; +#ifndef OPENSSL_NO_EC + /* The handling of the ECPointFormats extension is done elsewhere, namely in + * ssl3_choose_cipher in s3_lib.c. + */ + /* The handling of the EllipticCurves extension is done elsewhere, namely in + * ssl3_choose_cipher in s3_lib.c. + */ +#endif + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg); else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) @@ -732,7 +1315,7 @@ int ssl_check_clienthello_tlsext(SSL *s) * Note: this must be called after servername callbacks in case * the certificate has changed. */ - if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb) + if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { int r; r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); @@ -758,7 +1341,65 @@ int ssl_check_clienthello_tlsext(SSL *s) } else s->tlsext_status_expected = 0; - err: + +#ifdef TLSEXT_TYPE_opaque_prf_input + { + /* This sort of belongs into ssl_prepare_serverhello_tlsext(), + * but we might be sending an alert in response to the client hello, + * so this has to happen here in ssl_check_clienthello_tlsext(). */ + + int r = 1; + + if (s->ctx->tlsext_opaque_prf_input_callback != 0) + { + r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg); + if (!r) + { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + + if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */ + OPENSSL_free(s->s3->server_opaque_prf_input); + s->s3->server_opaque_prf_input = NULL; + + if (s->tlsext_opaque_prf_input != NULL) + { + if (s->s3->client_opaque_prf_input != NULL && + s->s3->client_opaque_prf_input_len == s->tlsext_opaque_prf_input_len) + { + /* can only use this extension if we have a server opaque PRF input + * of the same length as the client opaque PRF input! */ + + if (s->tlsext_opaque_prf_input_len == 0) + s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */ + else + s->s3->server_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len); + if (s->s3->server_opaque_prf_input == NULL) + { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len; + } + } + + if (r == 2 && s->s3->server_opaque_prf_input == NULL) + { + /* The callback wants to enforce use of the extension, + * but we can't do that with the client opaque PRF input; + * abort the handshake. + */ + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_HANDSHAKE_FAILURE; + } + } + +#endif + err: switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: @@ -781,16 +1422,75 @@ int ssl_check_serverhello_tlsext(SSL *s) int ret=SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; +#ifndef OPENSSL_NO_EC + /* If we are client and using an elliptic curve cryptography cipher suite, then server + * must return a an EC point formats lists containing uncompressed. + */ + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) && + ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA))) + { + /* we are using an ECC cipher */ + size_t i; + unsigned char *list; + int found_uncompressed = 0; + if ((s->session->tlsext_ecpointformatlist == NULL) || (s->session->tlsext_ecpointformatlist_length == 0)) + { + SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); + return -1; + } + list = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + { + if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) + { + found_uncompressed = 1; + break; + } + } + if (!found_uncompressed) + { + SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); + return -1; + } + } + ret = SSL_TLSEXT_ERR_OK; +#endif /* OPENSSL_NO_EC */ + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg); else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->server_opaque_prf_input_len > 0) + { + /* This case may indicate that we, as a client, want to insist on using opaque PRF inputs. + * So first verify that we really have a value from the server too. */ + + if (s->s3->server_opaque_prf_input == NULL) + { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_HANDSHAKE_FAILURE; + } + + /* Anytime the server *has* sent an opaque PRF input, we need to check + * that we have a client opaque PRF input of the same size. */ + if (s->s3->client_opaque_prf_input == NULL || + s->s3->client_opaque_prf_input_len != s->s3->server_opaque_prf_input_len) + { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_ILLEGAL_PARAMETER; + } + } +#endif + /* If we've requested certificate status and we wont get one * tell the callback */ if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) - && s->ctx->tlsext_status_cb) + && s->ctx && s->ctx->tlsext_status_cb) { int r; /* Set resp to NULL, resplen to -1 so callback knows @@ -885,6 +1585,11 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, return 1; if (type == TLSEXT_TYPE_session_ticket) { + /* If tickets disabled indicate cache miss which will + * trigger a full handshake + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 1; /* If zero length note client will accept a ticket * and indicate cache miss to trigger full handshake */ @@ -893,6 +1598,15 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, s->tlsext_ticket_expected = 1; return 0; /* Cache miss */ } + if (s->tls_session_secret_cb) + { + /* Indicate cache miss here and instead of + * generating the session from ticket now, + * trigger abbreviated handshake based on + * external mechanism to calculate the master + * secret later. */ + return 0; + } return tls_decrypt_ticket(s, p, size, session_id, len, ret); } @@ -945,6 +1659,11 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, * integrity checks on ticket. */ mlen = HMAC_size(&hctx); + if (mlen < 0) + { + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } eticklen -= mlen; /* Check HMAC of encrypted ticket */ HMAC_Update(&hctx, etick, eticklen); diff --git a/crypto/openssl/ssl/t1_meth.c b/crypto/openssl/ssl/t1_meth.c index f5d8df634e..6ce7c0bbf5 100644 --- a/crypto/openssl/ssl/t1_meth.c +++ b/crypto/openssl/ssl/t1_meth.c @@ -60,8 +60,8 @@ #include #include "ssl_locl.h" -static SSL_METHOD *tls1_get_method(int ver); -static SSL_METHOD *tls1_get_method(int ver) +static const SSL_METHOD *tls1_get_method(int ver); +static const SSL_METHOD *tls1_get_method(int ver) { if (ver == TLS1_VERSION) return(TLSv1_method()); diff --git a/crypto/openssl/ssl/t1_srvr.c b/crypto/openssl/ssl/t1_srvr.c index b75636abba..42525e9e89 100644 --- a/crypto/openssl/ssl/t1_srvr.c +++ b/crypto/openssl/ssl/t1_srvr.c @@ -64,8 +64,8 @@ #include #include -static SSL_METHOD *tls1_get_server_method(int ver); -static SSL_METHOD *tls1_get_server_method(int ver) +static const SSL_METHOD *tls1_get_server_method(int ver); +static const SSL_METHOD *tls1_get_server_method(int ver) { if (ver == TLS1_VERSION) return(TLSv1_server_method()); diff --git a/crypto/openssl/ssl/tls1.h b/crypto/openssl/ssl/tls1.h index afe4807fa9..b3cc8f098b 100644 --- a/crypto/openssl/ssl/tls1.h +++ b/crypto/openssl/ssl/tls1.h @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -68,6 +121,32 @@ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. * */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #ifndef HEADER_TLS1_H #define HEADER_TLS1_H @@ -104,16 +183,23 @@ extern "C" { #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 #define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ -/* ExtensionType values from RFC 3546 */ +/* ExtensionType values from RFC3546 / RFC4366 */ #define TLSEXT_TYPE_server_name 0 #define TLSEXT_TYPE_max_fragment_length 1 #define TLSEXT_TYPE_client_certificate_url 2 #define TLSEXT_TYPE_trusted_ca_keys 3 #define TLSEXT_TYPE_truncated_hmac 4 #define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4492 */ #define TLSEXT_TYPE_elliptic_curves 10 #define TLSEXT_TYPE_ec_point_formats 11 #define TLSEXT_TYPE_session_ticket 35 +/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ +#if 0 /* will have to be provided externally for now , + * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183 + * using whatever extension number you'd like to try */ +# define TLSEXT_TYPE_opaque_prf_input ?? */ +#endif /* Temporary extension type */ #define TLSEXT_TYPE_renegotiate 0xff01 @@ -123,6 +209,13 @@ extern "C" { /* status request value from RFC 3546 */ #define TLSEXT_STATUSTYPE_ocsp 1 +/* ECPointFormat values from draft-ietf-tls-ecc-12 */ +#define TLSEXT_ECPOINTFORMAT_first 0 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +#define TLSEXT_ECPOINTFORMAT_last 2 + #ifndef OPENSSL_NO_TLSEXT #define TLSEXT_MAXLEN_host_name 255 @@ -182,17 +275,31 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) #define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) +#define SSL_set_tlsext_opaque_prf_input(s, src, len) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src) +#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb) +#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) + #define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #endif -/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt +/* PSK ciphersuites from 4279 */ +#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see * s3_lib.c). We actually treat them like SSL 3.0 ciphers, which we probably - * shouldn't. */ -#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060 -#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061 + * shouldn't. Note that the first two are actually not in the IDs. */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061 /* not in ID */ #define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 #define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 #define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 @@ -330,6 +437,12 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" #define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" +/* PSK ciphersuites from RFC 4279 */ +#define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + /* Camellia ciphersuites from RFC4132 */ #define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" #define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" @@ -353,6 +466,7 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" #define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + #define TLS_CT_RSA_SIGN 1 #define TLS_CT_DSS_SIGN 2 #define TLS_CT_RSA_FIXED_DH 3 @@ -360,7 +474,11 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS_CT_ECDSA_SIGN 64 #define TLS_CT_RSA_FIXED_ECDH 65 #define TLS_CT_ECDSA_FIXED_ECDH 66 -#define TLS_CT_NUMBER 7 +#define TLS_CT_GOST94_SIGN 21 +#define TLS_CT_GOST01_SIGN 22 +/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) */ +#define TLS_CT_NUMBER 9 #define TLS1_FINISH_MAC_LENGTH 12 @@ -401,10 +519,14 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ #endif +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st + { + unsigned short length; + void *data; + }; + #ifdef __cplusplus } #endif #endif - - - -- 2.41.0