summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto
diff options
context:
space:
mode:
authorMathieu Trudel-Lapierre <cyphermox@ubuntu.com>2017-08-04 12:10:50 -0400
committerMathieu Trudel-Lapierre <cyphermox@ubuntu.com>2017-08-04 12:10:50 -0400
commitbbfd2ab18f52600aa41f061b2da9a2afe2a9d6ac (patch)
tree56132d617fff7c4f05e67024ec872d88fcafa92d /Cryptlib/OpenSSL/crypto
downloadefi-boot-shim-upstream/0.9+1474479173.6c180c6.tar.gz
efi-boot-shim-upstream/0.9+1474479173.6c180c6.zip
Import Upstream version 0.9+1474479173.6c180c6upstream/0.9+1474479173.6c180c6
Diffstat (limited to 'Cryptlib/OpenSSL/crypto')
-rw-r--r--Cryptlib/OpenSSL/crypto/LPdir_nyi.c47
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_cbc.c66
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_cfb.c85
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_core.c1363
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_ctr.c63
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_ecb.c73
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_ige.c323
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_locl.h89
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_misc.c86
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_ofb.c61
-rw-r--r--Cryptlib/OpenSSL/crypto/aes/aes_wrap.c72
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c262
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_bool.c111
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_bytes.c306
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c284
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_digest.c111
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_dup.c117
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_enum.c181
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_gentm.c312
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_i2d_fp.c157
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_int.c464
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_mbstr.c423
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_object.c402
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_octet.c78
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_print.c129
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_set.c238
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_sign.c331
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_strex.c651
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_strnid.c313
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_time.c228
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_type.c155
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_utctm.c352
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_utf8.c237
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_verify.c231
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c484
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_err.c354
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c831
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c479
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h135
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_par.c424
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn_mime.c974
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn_moid.c153
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn_pack.c207
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c482
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c248
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/charmap.h15
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c175
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c136
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/evp_asn1.c195
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/f_enum.c203
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/f_int.c215
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/f_string.c209
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c78
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/i2d_pu.c93
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/n_pkey.c354
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/nsseq.c84
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c143
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c280
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c145
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_bitst.c105
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_crl.c133
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_pkey.c113
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_req.c254
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_spki.c108
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_x509.c556
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_x509a.c115
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c1227
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c659
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c249
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_new.c381
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c585
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_utl.c275
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_algor.c148
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_attrib.c124
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_bignum.c153
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_crl.c517
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_exten.c77
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_info.c117
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_long.c196
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_name.c538
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_nx509.c72
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_pkey.c153
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c374
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_req.c116
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_sig.c69
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_spki.c82
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_val.c69
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_x509.c239
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_x509a.c196
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/b_dump.c208
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/b_print.c873
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/b_sock.c962
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bf_buff.c517
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bf_nbio.c253
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bf_null.c189
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bio_cb.c145
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bio_err.c157
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bio_lcl.h36
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bio_lib.c596
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_acpt.c463
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_bio.c886
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_conn.c612
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_dgram.c2081
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_fd.c330
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_file.c472
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_log.c453
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_mem.c313
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_null.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/bio/bss_sock.c287
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn.h949
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_add.c313
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_asm.c1093
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_blind.c385
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_const.c547
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_ctx.c448
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_depr.c115
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_div.c477
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_err.c154
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_exp.c1457
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_exp2.c303
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_gcd.c702
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_gf2m.c1300
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_kron.c186
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_lcl.h537
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_lib.c916
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_mod.c316
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_mont.c558
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_mpi.c128
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_mul.c1164
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_nist.c1262
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_prime.c519
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_prime.h326
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_print.c397
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_rand.c295
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_recp.c252
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_shift.c224
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_sqr.c290
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c409
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_word.c227
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_x931p.c277
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/rsaz_exp.h68
-rw-r--r--Cryptlib/OpenSSL/crypto/buffer/buf_err.c97
-rw-r--r--Cryptlib/OpenSSL/crypto/buffer/buf_str.c137
-rw-r--r--Cryptlib/OpenSSL/crypto/buffer/buffer.c187
-rw-r--r--Cryptlib/OpenSSL/crypto/cmac/cm_ameth.c96
-rw-r--r--Cryptlib/OpenSSL/crypto/cmac/cm_pmeth.c216
-rw-r--r--Cryptlib/OpenSSL/crypto/cmac/cmac.c306
-rw-r--r--Cryptlib/OpenSSL/crypto/comp/c_rle.c62
-rw-r--r--Cryptlib/OpenSSL/crypto/comp/c_zlib.c763
-rw-r--r--Cryptlib/OpenSSL/crypto/comp/comp_err.c98
-rw-r--r--Cryptlib/OpenSSL/crypto/comp/comp_lib.c66
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_api.c305
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_def.c711
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_def.h181
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_err.c133
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_lib.c395
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_mall.c81
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_mod.c599
-rw-r--r--Cryptlib/OpenSSL/crypto/conf/conf_sap.c101
-rw-r--r--Cryptlib/OpenSSL/crypto/constant_time_locl.h211
-rw-r--r--Cryptlib/OpenSSL/crypto/cpt_err.c104
-rw-r--r--Cryptlib/OpenSSL/crypto/cryptlib.c1035
-rw-r--r--Cryptlib/OpenSSL/crypto/cryptlib.h113
-rw-r--r--Cryptlib/OpenSSL/crypto/cversion.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/des/cbc_cksm.c103
-rw-r--r--Cryptlib/OpenSSL/crypto/des/cbc_enc.c61
-rw-r--r--Cryptlib/OpenSSL/crypto/des/cfb64ede.c249
-rw-r--r--Cryptlib/OpenSSL/crypto/des/cfb64enc.c122
-rw-r--r--Cryptlib/OpenSSL/crypto/des/cfb_enc.c199
-rw-r--r--Cryptlib/OpenSSL/crypto/des/des_enc.c389
-rw-r--r--Cryptlib/OpenSSL/crypto/des/des_locl.h443
-rw-r--r--Cryptlib/OpenSSL/crypto/des/des_old.c345
-rw-r--r--Cryptlib/OpenSSL/crypto/des/des_old2.c80
-rw-r--r--Cryptlib/OpenSSL/crypto/des/des_ver.h73
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ecb3_enc.c82
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ecb_enc.c124
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ede_cbcm_enc.c189
-rw-r--r--Cryptlib/OpenSSL/crypto/des/enc_read.c235
-rw-r--r--Cryptlib/OpenSSL/crypto/des/enc_writ.c182
-rw-r--r--Cryptlib/OpenSSL/crypto/des/fcrypt.c167
-rw-r--r--Cryptlib/OpenSSL/crypto/des/fcrypt_b.c140
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ncbc_enc.c154
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ofb64ede.c123
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ofb64enc.c109
-rw-r--r--Cryptlib/OpenSSL/crypto/des/ofb_enc.c131
-rw-r--r--Cryptlib/OpenSSL/crypto/des/pcbc_enc.c115
-rw-r--r--Cryptlib/OpenSSL/crypto/des/qud_cksm.c143
-rw-r--r--Cryptlib/OpenSSL/crypto/des/rand_key.c67
-rw-r--r--Cryptlib/OpenSSL/crypto/des/read2pwd.c144
-rw-r--r--Cryptlib/OpenSSL/crypto/des/rpc_des.h130
-rw-r--r--Cryptlib/OpenSSL/crypto/des/rpc_enc.c100
-rw-r--r--Cryptlib/OpenSSL/crypto/des/set_key.c447
-rw-r--r--Cryptlib/OpenSSL/crypto/des/spr.h212
-rw-r--r--Cryptlib/OpenSSL/crypto/des/str2key.c164
-rw-r--r--Cryptlib/OpenSSL/crypto/des/xcbc_enc.c216
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_ameth.c957
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_asn1.c189
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_check.c187
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_depr.c82
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_err.c126
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_gen.c204
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_key.c289
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_lib.c263
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c558
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_prn.c79
-rw-r--r--Cryptlib/OpenSSL/crypto/dh/dh_rfc5114.c285
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_beos.c253
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_dl.c380
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_dlfcn.c465
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_err.c158
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_lib.c448
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_null.c92
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_openssl.c83
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_vms.c547
-rw-r--r--Cryptlib/OpenSSL/crypto/dso/dso_win32.c788
-rw-r--r--Cryptlib/OpenSSL/crypto/ebcdic.c284
-rw-r--r--Cryptlib/OpenSSL/crypto/err/err.c1145
-rw-r--r--Cryptlib/OpenSSL/crypto/err/err_all.c168
-rw-r--r--Cryptlib/OpenSSL/crypto/err/err_prn.c113
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_b64.c573
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_enc.c428
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_md.c272
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_ok.c624
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/c_all.c90
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/c_allc.c241
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/c_alld.c114
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/digest.c408
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_aes.c2024
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c1008
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c985
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_bf.c87
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_camellia.c394
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_cast.c89
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_des.c269
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_des3.c495
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_idea.c119
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_null.c100
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_old.c164
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc2.c235
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc4.c133
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c308
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc5.c122
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_seed.c82
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c130
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/encode.c460
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_acnf.c73
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_cnf.c118
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_enc.c666
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_err.c254
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_key.c197
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_lib.c391
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_locl.h373
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_pbe.c312
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_pkey.c229
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_dss.c104
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_dss1.c105
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c154
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_md2.c106
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_md4.c108
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_md5.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_mdc2.c108
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_null.c98
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_ripemd.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_sha.c106
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_sha1.c235
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_sigver.c203
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_wp.c48
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/names.c215
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p5_crpt.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c334
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_dec.c87
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_enc.c87
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_lib.c456
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_open.c129
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_seal.c121
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_sign.c133
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_verify.c116
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c346
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c220
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c613
-rw-r--r--Cryptlib/OpenSSL/crypto/ex_data.c646
-rw-r--r--Cryptlib/OpenSSL/crypto/fips_ers.c7
-rw-r--r--Cryptlib/OpenSSL/crypto/hmac/hm_ameth.c167
-rw-r--r--Cryptlib/OpenSSL/crypto/hmac/hm_pmeth.c262
-rw-r--r--Cryptlib/OpenSSL/crypto/hmac/hmac.c268
-rw-r--r--Cryptlib/OpenSSL/crypto/krb5/krb5_asn.c162
-rw-r--r--Cryptlib/OpenSSL/crypto/lhash/lh_stats.c246
-rw-r--r--Cryptlib/OpenSSL/crypto/lhash/lhash.c458
-rw-r--r--Cryptlib/OpenSSL/crypto/md32_common.h428
-rw-r--r--Cryptlib/OpenSSL/crypto/md4/md4_dgst.c199
-rw-r--r--Cryptlib/OpenSSL/crypto/md4/md4_locl.h113
-rw-r--r--Cryptlib/OpenSSL/crypto/md4/md4_one.c96
-rw-r--r--Cryptlib/OpenSSL/crypto/md5/md5_dgst.c216
-rw-r--r--Cryptlib/OpenSSL/crypto/md5/md5_locl.h133
-rw-r--r--Cryptlib/OpenSSL/crypto/md5/md5_one.c96
-rw-r--r--Cryptlib/OpenSSL/crypto/mem.c466
-rw-r--r--Cryptlib/OpenSSL/crypto/mem_clr.c81
-rw-r--r--Cryptlib/OpenSSL/crypto/mem_dbg.c830
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/cbc128.c207
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/ccm128.c479
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/cfb128.c254
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/ctr128.c263
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/cts128.c544
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/gcm128.c2371
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/modes_lcl.h143
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/ofb128.c124
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/wrap128.c138
-rw-r--r--Cryptlib/OpenSSL/crypto/modes/xts128.c204
-rw-r--r--Cryptlib/OpenSSL/crypto/o_dir.c86
-rw-r--r--Cryptlib/OpenSSL/crypto/o_dir.h55
-rw-r--r--Cryptlib/OpenSSL/crypto/o_fips.c96
-rw-r--r--Cryptlib/OpenSSL/crypto/o_init.c83
-rw-r--r--Cryptlib/OpenSSL/crypto/o_str.c116
-rw-r--r--Cryptlib/OpenSSL/crypto/o_str.h69
-rw-r--r--Cryptlib/OpenSSL/crypto/o_time.c440
-rw-r--r--Cryptlib/OpenSSL/crypto/o_time.h70
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/o_names.c366
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/obj_dat.c801
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/obj_dat.h5319
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/obj_err.c100
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/obj_lib.c135
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/obj_xref.c222
-rw-r--r--Cryptlib/OpenSSL/crypto/objects/obj_xref.h99
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_asn.c183
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_cl.c383
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_err.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_ext.c566
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_ht.c555
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_lib.c284
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_prn.c299
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_srv.c271
-rw-r--r--Cryptlib/OpenSSL/crypto/ocsp/ocsp_vfy.c454
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_all.c427
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_err.c168
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_info.c394
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_lib.c865
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_oth.c86
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_pk8.c261
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_pkey.c293
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_seal.c191
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_sign.c101
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_x509.c68
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pem_xaux.c70
-rw-r--r--Cryptlib/OpenSSL/crypto/pem/pvkfmt.c888
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c258
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_asn.c125
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_attr.c147
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_crpt.c119
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_crt.c358
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_decr.c202
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_init.c92
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_key.c238
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_kiss.c299
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c195
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c235
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_p8d.c70
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_p8e.c105
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/p12_utl.c161
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs12/pk12err.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/bio_pk7.c70
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pk7_asn1.c251
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pk7_attr.c165
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c1295
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pk7_lib.c646
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c96
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c603
-rw-r--r--Cryptlib/OpenSSL/crypto/pkcs7/pkcs7err.c207
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/md_rand.c592
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/rand_err.c100
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/rand_lcl.h158
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/rand_lib.c300
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/rand_unix.c447
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/randfile.c337
-rw-r--r--Cryptlib/OpenSSL/crypto/rc4/rc4_enc.c334
-rw-r--r--Cryptlib/OpenSSL/crypto/rc4/rc4_locl.h5
-rw-r--r--Cryptlib/OpenSSL/crypto/rc4/rc4_skey.c116
-rw-r--r--Cryptlib/OpenSSL/crypto/rc4/rc4_utl.c62
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_ameth.c967
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_asn1.c131
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_chk.c214
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_crpt.c247
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_depr.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_eay.c904
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_err.c247
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c250
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_lib.c336
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_locl.h4
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_none.c94
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_null.c155
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_oaep.c283
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_pk1.c275
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c784
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_prn.c92
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_pss.c290
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_saos.c148
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_sign.c301
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_ssl.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/rsa/rsa_x931.c167
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha1_one.c79
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha1dgst.c74
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha256.c387
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha512.c684
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha_dgst.c74
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha_locl.h500
-rw-r--r--Cryptlib/OpenSSL/crypto/sha/sha_one.c79
-rw-r--r--Cryptlib/OpenSSL/crypto/stack/stack.c384
-rw-r--r--Cryptlib/OpenSSL/crypto/txt_db/txt_db.c381
-rw-r--r--Cryptlib/OpenSSL/crypto/ui/ui_compat.c69
-rw-r--r--Cryptlib/OpenSSL/crypto/ui/ui_lib.c870
-rw-r--r--Cryptlib/OpenSSL/crypto/ui/ui_locl.h145
-rw-r--r--Cryptlib/OpenSSL/crypto/ui/ui_util.c97
-rw-r--r--Cryptlib/OpenSSL/crypto/uid.c88
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/vpm_int.h70
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_att.c384
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_cmp.c498
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_d2.c109
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_def.c92
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_err.c187
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_ext.c211
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_lu.c710
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_obj.c230
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_r2x.c113
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_req.c328
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_set.c152
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_trs.c318
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_txt.c211
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_v3.c284
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_vfy.c2501
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_vpm.c662
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509cset.c167
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509name.c397
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509rset.c85
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509spki.c123
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509type.c127
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x_all.c558
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/ext_dat.h138
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_cache.c269
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_data.c129
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_int.h217
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_lib.c167
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_map.c130
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_node.c190
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/pcy_tree.c831
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c1344
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_akey.c205
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_akeya.c73
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_alt.c609
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_asid.c896
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_bcons.c132
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_bitst.c142
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_conf.c532
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_cpols.c491
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_crld.c562
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_enum.c100
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_extku.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c250
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_ia5.c119
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_info.c210
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_int.c92
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_lib.c363
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_ncons.c479
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_ocsp.c312
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_pci.c319
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_pcia.c56
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_pcons.c139
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_pku.c114
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_pmaps.c156
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_prn.c259
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_purp.c852
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_skey.c150
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_sxnet.c273
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3_utl.c1351
-rw-r--r--Cryptlib/OpenSSL/crypto/x509v3/v3err.c249
474 files changed, 151842 insertions, 0 deletions
diff --git a/Cryptlib/OpenSSL/crypto/LPdir_nyi.c b/Cryptlib/OpenSSL/crypto/LPdir_nyi.c
new file mode 100644
index 00000000..283d5b06
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/LPdir_nyi.c
@@ -0,0 +1,47 @@
+/*
+ * $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $
+ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 THE REGENTS 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 LPDIR_H
+# include "LPdir.h"
+#endif
+
+struct LP_dir_context_st {
+ void *dummy;
+};
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+ errno = EINVAL;
+ return 0;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+ errno = EINVAL;
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_cbc.c b/Cryptlib/OpenSSL/crypto/aes/aes_cbc.c
new file mode 100644
index 00000000..805d0e26
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_cbc.c
@@ -0,0 +1,66 @@
+/* crypto/aes/aes_cbc.c */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec, const int enc)
+{
+
+ 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);
+}
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_cfb.c b/Cryptlib/OpenSSL/crypto/aes/aes_cfb.c
new file mode 100644
index 00000000..12250009
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_cfb.c
@@ -0,0 +1,85 @@
+/* crypto/aes/aes_cfb.c */
+/* ====================================================================
+ * 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+/*
+ * 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 AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num, const int enc)
+{
+
+ CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+ (block128_f) AES_encrypt);
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num, const int enc)
+{
+ 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,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num, const int enc)
+{
+ CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
+ (block128_f) AES_encrypt);
+}
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_core.c b/Cryptlib/OpenSSL/crypto/aes/aes_core.c
new file mode 100644
index 00000000..7019b5d7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_core.c
@@ -0,0 +1,1363 @@
+/* crypto/aes/aes_core.c */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * 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.
+ */
+
+/* Note: rewritten a little bit to provide error control and an OpenSSL-
+ compatible API */
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+#ifndef AES_ASM
+/*-
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+
+static const u32 Te0[256] = {
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const u32 Td0[256] = {
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u8 Td4[256] = {
+ 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+ 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+ 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+ 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+ 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+ 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+ 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+ 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+ 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+ 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+ 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+ 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+ 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+ 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+ 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+ 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+ 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+ 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+ 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+ 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+ 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+ 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+ 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+ 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+ 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+ 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+ 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+ 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+ 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+ 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+ 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+ 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+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 private_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] ^
+ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te0[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te1[(temp >> 24) ] & 0x000000ff) ^
+ 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] ^
+ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te0[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te1[(temp >> 24) ] & 0x000000ff) ^
+ 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] ^
+ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te0[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te1[(temp >> 24) ] & 0x000000ff) ^
+ 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] ^
+ (Te2[(temp >> 24) ] & 0xff000000) ^
+ (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te1[(temp ) & 0xff] & 0x000000ff);
+ 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 private_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 = private_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;
+ rk[0] =
+ Td0[Te1[(rk[0] >> 24) ] & 0xff] ^
+ Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
+ Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^
+ Td3[Te1[(rk[0] ) & 0xff] & 0xff];
+ rk[1] =
+ Td0[Te1[(rk[1] >> 24) ] & 0xff] ^
+ Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
+ Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^
+ Td3[Te1[(rk[1] ) & 0xff] & 0xff];
+ rk[2] =
+ Td0[Te1[(rk[2] >> 24) ] & 0xff] ^
+ Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
+ Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^
+ Td3[Te1[(rk[2] ) & 0xff] & 0xff];
+ rk[3] =
+ Td0[Te1[(rk[3] >> 24) ] & 0xff] ^
+ Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
+ Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^
+ Td3[Te1[(rk[3] ) & 0xff] & 0xff];
+ }
+ return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key) {
+
+ const u32 *rk;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ assert(in && out && key);
+ rk = key->rd_key;
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(in ) ^ rk[0];
+ s1 = GETU32(in + 4) ^ rk[1];
+ s2 = GETU32(in + 8) ^ rk[2];
+ s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+ if (key->rounds > 10) {
+ /* round 10: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+ if (key->rounds > 12) {
+ /* round 12: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+ }
+ }
+ rk += key->rounds << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = key->rounds >> 1;
+ for (;;) {
+ t0 =
+ Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
+
+ s0 =
+ Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Te2[(t0 >> 24) ] & 0xff000000) ^
+ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te1[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(out , s0);
+ s1 =
+ (Te2[(t1 >> 24) ] & 0xff000000) ^
+ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te1[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(out + 4, s1);
+ s2 =
+ (Te2[(t2 >> 24) ] & 0xff000000) ^
+ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te1[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(out + 8, s2);
+ s3 =
+ (Te2[(t3 >> 24) ] & 0xff000000) ^
+ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te1[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(out + 12, s3);
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key)
+{
+
+ const u32 *rk;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ assert(in && out && key);
+ rk = key->rd_key;
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(in ) ^ rk[0];
+ s1 = GETU32(in + 4) ^ rk[1];
+ s2 = GETU32(in + 8) ^ rk[2];
+ s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+ if (key->rounds > 10) {
+ /* round 10: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+ if (key->rounds > 12) {
+ /* round 12: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+ }
+ }
+ rk += key->rounds << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = key->rounds >> 1;
+ for (;;) {
+ t0 =
+ Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
+
+ s0 =
+ Td0[(t0 >> 24) ] ^
+ Td1[(t3 >> 16) & 0xff] ^
+ Td2[(t2 >> 8) & 0xff] ^
+ Td3[(t1 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Td0[(t1 >> 24) ] ^
+ Td1[(t0 >> 16) & 0xff] ^
+ Td2[(t3 >> 8) & 0xff] ^
+ Td3[(t2 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Td0[(t2 >> 24) ] ^
+ Td1[(t1 >> 16) & 0xff] ^
+ Td2[(t0 >> 8) & 0xff] ^
+ Td3[(t3 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Td0[(t3 >> 24) ] ^
+ Td1[(t2 >> 16) & 0xff] ^
+ Td2[(t1 >> 8) & 0xff] ^
+ Td3[(t0 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ ((u32)Td4[(t0 >> 24) ] << 24) ^
+ ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^
+ ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^
+ ((u32)Td4[(t1 ) & 0xff]) ^
+ rk[0];
+ PUTU32(out , s0);
+ s1 =
+ ((u32)Td4[(t1 >> 24) ] << 24) ^
+ ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^
+ ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^
+ ((u32)Td4[(t2 ) & 0xff]) ^
+ rk[1];
+ PUTU32(out + 4, s1);
+ s2 =
+ ((u32)Td4[(t2 >> 24) ] << 24) ^
+ ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^
+ ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^
+ ((u32)Td4[(t3 ) & 0xff]) ^
+ rk[2];
+ PUTU32(out + 8, s2);
+ s3 =
+ ((u32)Td4[(t3 >> 24) ] << 24) ^
+ ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^
+ ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^
+ ((u32)Td4[(t0 ) & 0xff]) ^
+ rk[3];
+ 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 private_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] ^
+ ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
+ ((u32)Te4[(temp >> 8) & 0xff] << 16) ^
+ ((u32)Te4[(temp ) & 0xff] << 8) ^
+ ((u32)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] ^
+ ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
+ ((u32)Te4[(temp >> 8) & 0xff] << 16) ^
+ ((u32)Te4[(temp ) & 0xff] << 8) ^
+ ((u32)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] ^
+ ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
+ ((u32)Te4[(temp >> 8) & 0xff] << 16) ^
+ ((u32)Te4[(temp ) & 0xff] << 8) ^
+ ((u32)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] ^
+ ((u32)Te4[(temp >> 24) ] << 24) ^
+ ((u32)Te4[(temp >> 16) & 0xff] << 16) ^
+ ((u32)Te4[(temp >> 8) & 0xff] << 8) ^
+ ((u32)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 private_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 = private_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/Cryptlib/OpenSSL/crypto/aes/aes_ctr.c b/Cryptlib/OpenSSL/crypto/aes/aes_ctr.c
new file mode 100644
index 00000000..9e760c4b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_ctr.c
@@ -0,0 +1,63 @@
+/* crypto/aes/aes_ctr.c */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+ 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/Cryptlib/OpenSSL/crypto/aes/aes_ecb.c b/Cryptlib/OpenSSL/crypto/aes/aes_ecb.c
new file mode 100644
index 00000000..52151a5c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_ecb.c
@@ -0,0 +1,73 @@
+/* crypto/aes/aes_ecb.c */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key, const int enc)
+{
+
+ assert(in && out && key);
+ assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
+
+ if (AES_ENCRYPT == enc)
+ AES_encrypt(in, out, key);
+ else
+ AES_decrypt(in, out, key);
+}
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_ige.c b/Cryptlib/OpenSSL/crypto/aes/aes_ige.c
new file mode 100644
index 00000000..8f2b7706
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_ige.c
@@ -0,0 +1,323 @@
+/* crypto/aes/aes_ige.c */
+/* ====================================================================
+ * 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
+ * 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 "cryptlib.h"
+
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
+typedef struct {
+ unsigned long data[N_WORDS];
+} aes_block_t;
+
+/* XXX: probably some better way to do this */
+#if defined(__i386__) || defined(__x86_64__)
+# define UNALIGNED_MEMOPS_ARE_FAST 1
+#else
+# define UNALIGNED_MEMOPS_ARE_FAST 0
+#endif
+
+#if UNALIGNED_MEMOPS_ARE_FAST
+# define load_block(d, s) (d) = *(const aes_block_t *)(s)
+# define store_block(d, s) *(aes_block_t *)(d) = (s)
+#else
+# define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE)
+# define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE)
+#endif
+
+/* N.B. The IV for this mode is _twice_ the block size */
+
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, const int enc)
+{
+ size_t n;
+ size_t len = length;
+
+ OPENSSL_assert(in && out && key && ivec);
+ OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
+ OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
+
+ len = length / AES_BLOCK_SIZE;
+
+ if (AES_ENCRYPT == enc) {
+ if (in != out &&
+ (UNALIGNED_MEMOPS_ARE_FAST
+ || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
+ 0)) {
+ aes_block_t *ivp = (aes_block_t *) ivec;
+ aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
+
+ while (len) {
+ aes_block_t *inp = (aes_block_t *) in;
+ aes_block_t *outp = (aes_block_t *) out;
+
+ for (n = 0; n < N_WORDS; ++n)
+ outp->data[n] = inp->data[n] ^ ivp->data[n];
+ AES_encrypt((unsigned char *)outp->data,
+ (unsigned char *)outp->data, key);
+ for (n = 0; n < N_WORDS; ++n)
+ outp->data[n] ^= iv2p->data[n];
+ ivp = outp;
+ iv2p = inp;
+ --len;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+ memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+ } else {
+ aes_block_t tmp, tmp2;
+ aes_block_t iv;
+ aes_block_t iv2;
+
+ load_block(iv, ivec);
+ load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+ while (len) {
+ load_block(tmp, in);
+ for (n = 0; n < N_WORDS; ++n)
+ tmp2.data[n] = tmp.data[n] ^ iv.data[n];
+ AES_encrypt((unsigned char *)tmp2.data,
+ (unsigned char *)tmp2.data, key);
+ for (n = 0; n < N_WORDS; ++n)
+ tmp2.data[n] ^= iv2.data[n];
+ store_block(out, tmp2);
+ iv = tmp2;
+ iv2 = tmp;
+ --len;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+ memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+ }
+ } else {
+ if (in != out &&
+ (UNALIGNED_MEMOPS_ARE_FAST
+ || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
+ 0)) {
+ aes_block_t *ivp = (aes_block_t *) ivec;
+ aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
+
+ while (len) {
+ aes_block_t tmp;
+ aes_block_t *inp = (aes_block_t *) in;
+ aes_block_t *outp = (aes_block_t *) out;
+
+ for (n = 0; n < N_WORDS; ++n)
+ tmp.data[n] = inp->data[n] ^ iv2p->data[n];
+ AES_decrypt((unsigned char *)tmp.data,
+ (unsigned char *)outp->data, key);
+ for (n = 0; n < N_WORDS; ++n)
+ outp->data[n] ^= ivp->data[n];
+ ivp = inp;
+ iv2p = outp;
+ --len;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+ memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+ } else {
+ aes_block_t tmp, tmp2;
+ aes_block_t iv;
+ aes_block_t iv2;
+
+ load_block(iv, ivec);
+ load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+ while (len) {
+ load_block(tmp, in);
+ tmp2 = tmp;
+ for (n = 0; n < N_WORDS; ++n)
+ tmp.data[n] ^= iv2.data[n];
+ AES_decrypt((unsigned char *)tmp.data,
+ (unsigned char *)tmp.data, key);
+ for (n = 0; n < N_WORDS; ++n)
+ tmp.data[n] ^= iv.data[n];
+ store_block(out, tmp);
+ iv = tmp2;
+ iv2 = tmp;
+ --len;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+ memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+ }
+ }
+}
+
+/*
+ * Note that its effectively impossible to do biIGE in anything other
+ * than a single pass, so no provision is made for chaining.
+ */
+
+/* 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,
+ size_t length, const AES_KEY *key,
+ const AES_KEY *key2, const unsigned char *ivec,
+ const int enc)
+{
+ 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];
+ unsigned char prev[AES_BLOCK_SIZE];
+ const unsigned char *iv;
+ const unsigned char *iv2;
+
+ OPENSSL_assert(in && out && key && ivec);
+ OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
+ OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
+
+ if (AES_ENCRYPT == enc) {
+ /*
+ * XXX: Do a separate case for when in != out (strictly should check
+ * for overlap, too)
+ */
+
+ /* First the forward pass */
+ iv = ivec;
+ iv2 = ivec + AES_BLOCK_SIZE;
+ while (len >= AES_BLOCK_SIZE) {
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ out[n] = in[n] ^ iv[n];
+ AES_encrypt(out, out, key);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= iv2[n];
+ iv = out;
+ memcpy(prev, in, AES_BLOCK_SIZE);
+ iv2 = prev;
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+
+ /* And now backwards */
+ iv = ivec + AES_BLOCK_SIZE * 2;
+ iv2 = ivec + AES_BLOCK_SIZE * 3;
+ len = length;
+ while (len >= AES_BLOCK_SIZE) {
+ out -= AES_BLOCK_SIZE;
+ /*
+ * XXX: reduce copies by alternating between buffers
+ */
+ memcpy(tmp, out, AES_BLOCK_SIZE);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= iv[n];
+ /*
+ * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE);
+ */
+ AES_encrypt(out, out, key);
+ /*
+ * hexdump(stdout,"enc", out, AES_BLOCK_SIZE);
+ */
+ /*
+ * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE);
+ */
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= iv2[n];
+ /*
+ * hexdump(stdout,"out", out, AES_BLOCK_SIZE);
+ */
+ iv = out;
+ memcpy(prev, tmp, AES_BLOCK_SIZE);
+ iv2 = prev;
+ len -= AES_BLOCK_SIZE;
+ }
+ } else {
+ /* First backwards */
+ iv = ivec + AES_BLOCK_SIZE * 2;
+ iv2 = ivec + AES_BLOCK_SIZE * 3;
+ in += length;
+ out += length;
+ while (len >= AES_BLOCK_SIZE) {
+ in -= AES_BLOCK_SIZE;
+ out -= AES_BLOCK_SIZE;
+ memcpy(tmp, in, AES_BLOCK_SIZE);
+ memcpy(tmp2, in, AES_BLOCK_SIZE);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ tmp[n] ^= iv2[n];
+ AES_decrypt(tmp, out, key);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= iv[n];
+ memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
+ iv = tmp3;
+ iv2 = out;
+ len -= AES_BLOCK_SIZE;
+ }
+
+ /* And now forwards */
+ iv = ivec;
+ iv2 = ivec + AES_BLOCK_SIZE;
+ len = length;
+ while (len >= AES_BLOCK_SIZE) {
+ memcpy(tmp, out, AES_BLOCK_SIZE);
+ memcpy(tmp2, out, AES_BLOCK_SIZE);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ tmp[n] ^= iv2[n];
+ AES_decrypt(tmp, out, key);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= iv[n];
+ memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
+ iv = tmp3;
+ iv2 = out;
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_locl.h b/Cryptlib/OpenSSL/crypto/aes/aes_locl.h
new file mode 100644
index 00000000..7acd74ec
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_locl.h
@@ -0,0 +1,89 @@
+/* crypto/aes/aes.h */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_LOCL_H
+# define HEADER_AES_LOCL_H
+
+# include <openssl/e_os2.h>
+
+# ifdef OPENSSL_NO_AES
+# error AES is disabled.
+# endif
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+# 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)); }
+# else
+# 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); }
+# endif
+
+# ifdef AES_LONG
+typedef unsigned long u32;
+# else
+typedef unsigned int u32;
+# endif
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+# define MAXKC (256/32)
+# define MAXKB (256/8)
+# define MAXNR 14
+
+/* This controls loop-unrolling in aes_core.c */
+# undef FULL_UNROLL
+
+#endif /* !HEADER_AES_LOCL_H */
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_misc.c b/Cryptlib/OpenSSL/crypto/aes/aes_misc.c
new file mode 100644
index 00000000..fafad4d6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_misc.c
@@ -0,0 +1,86 @@
+/* crypto/aes/aes_misc.c */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+const char AES_version[] = "AES" OPENSSL_VERSION_PTEXT;
+
+const char *AES_options(void)
+{
+#ifdef FULL_UNROLL
+ return "aes(full)";
+#else
+ return "aes(partial)";
+#endif
+}
+
+/* FIPS wrapper functions to block low level AES calls in FIPS mode */
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key)
+{
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(AES);
+#endif
+ return private_AES_set_encrypt_key(userKey, bits, key);
+}
+
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key)
+{
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(AES);
+#endif
+ return private_AES_set_decrypt_key(userKey, bits, key);
+}
diff --git a/Cryptlib/OpenSSL/crypto/aes/aes_ofb.c b/Cryptlib/OpenSSL/crypto/aes/aes_ofb.c
new file mode 100644
index 00000000..64a08caa
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_ofb.c
@@ -0,0 +1,61 @@
+/* crypto/aes/aes_ofb.c */
+/* ====================================================================
+ * 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+ 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/Cryptlib/OpenSSL/crypto/aes/aes_wrap.c b/Cryptlib/OpenSSL/crypto/aes/aes_wrap.c
new file mode 100644
index 00000000..b7b64d57
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/aes/aes_wrap.c
@@ -0,0 +1,72 @@
+/* crypto/aes/aes_wrap.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 "cryptlib.h"
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+ unsigned char *out,
+ const unsigned char *in, unsigned int inlen)
+{
+ return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt);
+}
+
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+ unsigned char *out,
+ const unsigned char *in, unsigned int inlen)
+{
+ return CRYPTO_128_unwrap(key, iv, out, in, inlen,
+ (block128_f) AES_decrypt);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c b/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c
new file mode 100644
index 00000000..f906188b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c
@@ -0,0 +1,262 @@
+/* crypto/asn1/a_bitstr.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
+{
+ return M_ASN1_BIT_STRING_set(x, d, len);
+}
+
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
+{
+ int ret, j, bits, len;
+ unsigned char *p, *d;
+
+ if (a == NULL)
+ return (0);
+
+ len = a->length;
+
+ if (len > 0) {
+ if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
+ bits = (int)a->flags & 0x07;
+ } else {
+ for (; len > 0; len--) {
+ if (a->data[len - 1])
+ break;
+ }
+ j = a->data[len - 1];
+ if (j & 0x01)
+ bits = 0;
+ else if (j & 0x02)
+ bits = 1;
+ else if (j & 0x04)
+ bits = 2;
+ else if (j & 0x08)
+ bits = 3;
+ else if (j & 0x10)
+ bits = 4;
+ else if (j & 0x20)
+ bits = 5;
+ else if (j & 0x40)
+ bits = 6;
+ else if (j & 0x80)
+ bits = 7;
+ else
+ bits = 0; /* should not happen */
+ }
+ } else
+ bits = 0;
+
+ ret = 1 + len;
+ if (pp == NULL)
+ return (ret);
+
+ p = *pp;
+
+ *(p++) = (unsigned char)bits;
+ d = a->data;
+ memcpy(p, d, len);
+ p += len;
+ if (len > 0)
+ p[-1] &= (0xff << bits);
+ *pp = p;
+ return (ret);
+}
+
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+ const unsigned char **pp, long len)
+{
+ ASN1_BIT_STRING *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ int i;
+
+ if (len < 1) {
+ i = ASN1_R_STRING_TOO_SHORT;
+ goto err;
+ }
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ p = *pp;
+ i = *(p++);
+ if (i > 7) {
+ i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
+ goto err;
+ }
+ /*
+ * We do this to preserve the settings. If we modify the settings, via
+ * the _set_bit function, we will recalculate on output
+ */
+ ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
+ ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
+
+ if (len-- > 1) { /* using one because of the bits left byte */
+ s = (unsigned char *)OPENSSL_malloc((int)len);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ memcpy(s, p, (int)len);
+ s[len - 1] &= (0xff << i);
+ p += len;
+ } else
+ s = NULL;
+
+ ret->length = (int)len;
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->data = s;
+ ret->type = V_ASN1_BIT_STRING;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_BIT_STRING_free(ret);
+ return (NULL);
+}
+
+/*
+ * These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
+ */
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
+{
+ int w, v, iv;
+ unsigned char *c;
+
+ w = n / 8;
+ v = 1 << (7 - (n & 0x07));
+ iv = ~v;
+ if (!value)
+ v = 0;
+
+ if (a == NULL)
+ return 0;
+
+ a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+
+ if ((a->length < (w + 1)) || (a->data == NULL)) {
+ if (!value)
+ return (1); /* Don't need to set */
+ if (a->data == NULL)
+ c = (unsigned char *)OPENSSL_malloc(w + 1);
+ else
+ c = (unsigned char *)OPENSSL_realloc_clean(a->data,
+ a->length, w + 1);
+ if (c == NULL) {
+ ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (w + 1 - a->length > 0)
+ memset(c + a->length, 0, w + 1 - a->length);
+ a->data = c;
+ a->length = w + 1;
+ }
+ a->data[w] = ((a->data[w]) & iv) | v;
+ while ((a->length > 0) && (a->data[a->length - 1] == 0))
+ a->length--;
+ return (1);
+}
+
+int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
+{
+ int w, v;
+
+ w = n / 8;
+ v = 1 << (7 - (n & 0x07));
+ if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
+ return (0);
+ 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/Cryptlib/OpenSSL/crypto/asn1/a_bool.c b/Cryptlib/OpenSSL/crypto/asn1/a_bool.c
new file mode 100644
index 00000000..1b85bc9e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_bool.c
@@ -0,0 +1,111 @@
+/* crypto/asn1/a_bool.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+
+int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
+{
+ int r;
+ unsigned char *p;
+
+ r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
+ if (pp == NULL)
+ return (r);
+ p = *pp;
+
+ ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
+ *(p++) = (unsigned char)a;
+ *pp = p;
+ return (r);
+}
+
+int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
+{
+ int ret = -1;
+ const unsigned char *p;
+ long len;
+ int inf, tag, xclass;
+ int i = 0;
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
+
+ if (tag != V_ASN1_BOOLEAN) {
+ i = ASN1_R_EXPECTING_A_BOOLEAN;
+ goto err;
+ }
+
+ if (len != 1) {
+ i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
+ goto err;
+ }
+ ret = (int)*(p++);
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ ASN1err(ASN1_F_D2I_ASN1_BOOLEAN, i);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c b/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c
new file mode 100644
index 00000000..385b5398
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c
@@ -0,0 +1,306 @@
+/* crypto/asn1/a_bytes.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
+/*
+ * type is a 'bitmap' of acceptable string types.
+ */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
+ long length, int type)
+{
+ ASN1_STRING *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ long len;
+ int inf, tag, xclass;
+ int i = 0;
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80)
+ goto err;
+
+ if (tag >= 32) {
+ i = ASN1_R_TAG_VALUE_TOO_HIGH;
+ goto err;
+ }
+ if (!(ASN1_tag2bit(tag) & type)) {
+ i = ASN1_R_WRONG_TYPE;
+ goto err;
+ }
+
+ /* If a bit-string, exit early */
+ if (tag == V_ASN1_BIT_STRING)
+ return (d2i_ASN1_BIT_STRING(a, pp, length));
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = ASN1_STRING_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ if (len != 0) {
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ memcpy(s, p, (int)len);
+ s[len] = '\0';
+ p += len;
+ } else
+ s = NULL;
+
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->length = (int)len;
+ ret->data = s;
+ ret->type = tag;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ ASN1_STRING_free(ret);
+ return (NULL);
+}
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
+{
+ int ret, r, constructed;
+ unsigned char *p;
+
+ if (a == NULL)
+ return (0);
+
+ if (tag == V_ASN1_BIT_STRING)
+ return (i2d_ASN1_BIT_STRING(a, pp));
+
+ ret = a->length;
+ r = ASN1_object_size(0, ret, tag);
+ if (pp == NULL)
+ return (r);
+ p = *pp;
+
+ if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
+ constructed = 1;
+ else
+ constructed = 0;
+ ASN1_put_object(&p, constructed, ret, tag, xclass);
+ memcpy(p, a->data, a->length);
+ p += a->length;
+ *pp = p;
+ return (r);
+}
+
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+ long length, int Ptag, int Pclass)
+{
+ ASN1_STRING *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ long len;
+ int inf, tag, xclass;
+ int i = 0;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = ASN1_STRING_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
+
+ if (tag != Ptag) {
+ i = ASN1_R_WRONG_TAG;
+ goto err;
+ }
+
+ if (inf & V_ASN1_CONSTRUCTED) {
+ ASN1_const_CTX c;
+
+ c.pp = pp;
+ c.p = p;
+ c.inf = inf;
+ c.slen = len;
+ c.tag = Ptag;
+ c.xclass = Pclass;
+ c.max = (length == 0) ? 0 : (p + length);
+ if (!asn1_collate_primitive(ret, &c))
+ goto err;
+ else {
+ p = c.p;
+ }
+ } else {
+ if (len != 0) {
+ if ((ret->length < len) || (ret->data == NULL)) {
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ } else
+ s = ret->data;
+ memcpy(s, p, (int)len);
+ s[len] = '\0';
+ p += len;
+ } else {
+ s = NULL;
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ }
+
+ ret->length = (int)len;
+ ret->data = s;
+ ret->type = Ptag;
+ }
+
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ ASN1_STRING_free(ret);
+ ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
+ return (NULL);
+}
+
+/*
+ * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
+ * into the one structure that is then returned
+ */
+/*
+ * There have been a few bug fixes for this function from Paul Keogh
+ * <paul.keogh@sse.ie>, many thanks to him
+ */
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
+{
+ ASN1_STRING *os = NULL;
+ BUF_MEM b;
+ int num;
+
+ b.length = 0;
+ b.max = 0;
+ b.data = NULL;
+
+ if (a == NULL) {
+ c->error = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ num = 0;
+ for (;;) {
+ if (c->inf & 1) {
+ c->eos = ASN1_const_check_infinite_end(&c->p,
+ (long)(c->max - c->p));
+ if (c->eos)
+ break;
+ } else {
+ if (c->slen <= 0)
+ break;
+ }
+
+ c->q = c->p;
+ if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
+ == NULL) {
+ c->error = ERR_R_ASN1_LIB;
+ goto err;
+ }
+
+ if (!BUF_MEM_grow_clean(&b, num + os->length)) {
+ c->error = ERR_R_BUF_LIB;
+ goto err;
+ }
+ memcpy(&(b.data[num]), os->data, os->length);
+ if (!(c->inf & 1))
+ c->slen -= (c->p - c->q);
+ num += os->length;
+ }
+
+ if (!asn1_const_Finish(c))
+ goto err;
+
+ a->length = num;
+ if (a->data != NULL)
+ OPENSSL_free(a->data);
+ a->data = (unsigned char *)b.data;
+ if (os != NULL)
+ ASN1_STRING_free(os);
+ return (1);
+ err:
+ ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error);
+ if (os != NULL)
+ ASN1_STRING_free(os);
+ if (b.data != NULL)
+ OPENSSL_free(b.data);
+ return (0);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c b/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c
new file mode 100644
index 00000000..51b6f245
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c
@@ -0,0 +1,284 @@
+/* crypto/asn1/a_d2i_fp.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 <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1_mac.h>
+
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+
+#ifndef NO_OLD_ASN1
+# ifndef OPENSSL_NO_FP_API
+
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
+{
+ BIO *b;
+ void *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB);
+ return (NULL);
+ }
+ BIO_set_fp(b, in, BIO_NOCLOSE);
+ ret = ASN1_d2i_bio(xnew, d2i, b, x);
+ BIO_free(b);
+ return (ret);
+}
+# endif
+
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
+{
+ BUF_MEM *b = NULL;
+ const unsigned char *p;
+ void *ret = NULL;
+ int len;
+
+ len = asn1_d2i_read_bio(in, &b);
+ if (len < 0)
+ goto err;
+
+ p = (unsigned char *)b->data;
+ ret = d2i(x, &p, len);
+ err:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return (ret);
+}
+
+#endif
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
+{
+ BUF_MEM *b = NULL;
+ const unsigned char *p;
+ void *ret = NULL;
+ int len;
+
+ len = asn1_d2i_read_bio(in, &b);
+ if (len < 0)
+ goto err;
+
+ p = (const unsigned char *)b->data;
+ ret = ASN1_item_d2i(x, &p, len, it);
+ err:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return (ret);
+}
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
+{
+ BIO *b;
+ char *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB);
+ return (NULL);
+ }
+ BIO_set_fp(b, in, BIO_NOCLOSE);
+ ret = ASN1_item_d2i_bio(it, b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+#define HEADER_SIZE 8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
+{
+ BUF_MEM *b;
+ unsigned char *p;
+ int i;
+ ASN1_const_CTX c;
+ size_t want = HEADER_SIZE;
+ int eos = 0;
+ size_t off = 0;
+ size_t len = 0;
+
+ b = BUF_MEM_new();
+ if (b == NULL) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ ERR_clear_error();
+ for (;;) {
+ if (want >= (len - off)) {
+ want -= (len - off);
+
+ if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ i = BIO_read(in, &(b->data[len]), want);
+ if ((i < 0) && ((len - off) == 0)) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
+ goto err;
+ }
+ if (i > 0) {
+ if (len + i < len) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+ goto err;
+ }
+ len += i;
+ }
+ }
+ /* else data already loaded */
+
+ p = (unsigned char *)&(b->data[off]);
+ c.p = p;
+ c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
+ len - off);
+ if (c.inf & 0x80) {
+ unsigned long e;
+
+ e = ERR_GET_REASON(ERR_peek_error());
+ if (e != ASN1_R_TOO_LONG)
+ goto err;
+ else
+ ERR_clear_error(); /* clear error */
+ }
+ i = c.p - p; /* header length */
+ off += i; /* end of data */
+
+ if (c.inf & 1) {
+ /* no data body so go round again */
+ eos++;
+ if (eos < 0) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
+ goto err;
+ }
+ want = HEADER_SIZE;
+ } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
+ /* eos value, so go back and read another header */
+ eos--;
+ if (eos <= 0)
+ break;
+ else
+ want = HEADER_SIZE;
+ } else {
+ /* suck in c.slen bytes of data */
+ want = c.slen;
+ if (want > (len - off)) {
+ size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+
+ want -= (len - off);
+ if (want > INT_MAX /* BIO_read takes an int length */ ||
+ len + want < len) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+ goto err;
+ }
+ while (want > 0) {
+ /*
+ * Read content in chunks of increasing size
+ * so we can return an error for EOF without
+ * having to allocate the entire content length
+ * in one go.
+ */
+ size_t chunk = want > chunk_max ? chunk_max : want;
+
+ if (!BUF_MEM_grow_clean(b, len + chunk)) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ want -= chunk;
+ while (chunk > 0) {
+ i = BIO_read(in, &(b->data[len]), chunk);
+ if (i <= 0) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+ ASN1_R_NOT_ENOUGH_DATA);
+ goto err;
+ }
+ /*
+ * This can't overflow because |len+want| didn't
+ * overflow.
+ */
+ len += i;
+ chunk -= i;
+ }
+ if (chunk_max < INT_MAX/2)
+ chunk_max *= 2;
+ }
+ }
+ if (off + c.slen < off) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+ goto err;
+ }
+ off += c.slen;
+ if (eos <= 0) {
+ break;
+ } else
+ want = HEADER_SIZE;
+ }
+ }
+
+ if (off > INT_MAX) {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+ goto err;
+ }
+
+ *pb = b;
+ return off;
+ err:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return -1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_digest.c b/Cryptlib/OpenSSL/crypto/asn1/a_digest.c
new file mode 100644
index 00000000..7cbc4751
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_digest.c
@@ -0,0 +1,111 @@
+/* crypto/asn1/a_digest.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 <stdio.h>
+#include <time.h>
+
+#include "cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+ unsigned char *md, unsigned int *len)
+{
+ int i;
+ unsigned char *str, *p;
+
+ i = i2d(data, NULL);
+ if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
+ ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ p = str;
+ i2d(data, &p);
+
+ if (!EVP_Digest(str, i, md, len, type, NULL))
+ return 0;
+ OPENSSL_free(str);
+ return (1);
+}
+
+#endif
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
+ unsigned char *md, unsigned int *len)
+{
+ int i;
+ unsigned char *str = NULL;
+
+ i = ASN1_item_i2d(asn, &str, it);
+ if (!str)
+ return (0);
+
+ if (!EVP_Digest(str, i, md, len, type, NULL))
+ return 0;
+ OPENSSL_free(str);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_dup.c b/Cryptlib/OpenSSL/crypto/asn1/a_dup.c
new file mode 100644
index 00000000..349ab562
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_dup.c
@@ -0,0 +1,117 @@
+/* crypto/asn1/a_dup.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
+{
+ unsigned char *b, *p;
+ const unsigned char *p2;
+ int i;
+ char *ret;
+
+ if (x == NULL)
+ return (NULL);
+
+ i = i2d(x, NULL);
+ b = OPENSSL_malloc(i + 10);
+ if (b == NULL) {
+ ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ p = b;
+ i = i2d(x, &p);
+ p2 = b;
+ ret = d2i(NULL, &p2, i);
+ OPENSSL_free(b);
+ return (ret);
+}
+
+#endif
+
+/*
+ * ASN1_ITEM version of dup: this follows the model above except we don't
+ * need to allocate the buffer. At some point this could be rewritten to
+ * directly dup the underlying structure instead of doing and encode and
+ * decode.
+ */
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
+{
+ unsigned char *b = NULL;
+ const unsigned char *p;
+ long i;
+ void *ret;
+
+ if (x == NULL)
+ return (NULL);
+
+ i = ASN1_item_i2d(x, &b, it);
+ if (b == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ p = b;
+ ret = ASN1_item_d2i(NULL, &p, i, it);
+ OPENSSL_free(b);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_enum.c b/Cryptlib/OpenSSL/crypto/asn1/a_enum.c
new file mode 100644
index 00000000..c3498ac9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_enum.c
@@ -0,0 +1,181 @@
+/* crypto/asn1/a_enum.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+
+/*
+ * Code for ENUMERATED type: identical to INTEGER apart from a different tag.
+ * for comments on encoding see a_int.c
+ */
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
+{
+ int j, k;
+ unsigned int i;
+ unsigned char buf[sizeof(long) + 1];
+ long d;
+
+ a->type = V_ASN1_ENUMERATED;
+ if (a->length < (int)(sizeof(long) + 1)) {
+ if (a->data != NULL)
+ OPENSSL_free(a->data);
+ if ((a->data =
+ (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
+ memset((char *)a->data, 0, sizeof(long) + 1);
+ }
+ if (a->data == NULL) {
+ ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ d = v;
+ if (d < 0) {
+ d = -d;
+ a->type = V_ASN1_NEG_ENUMERATED;
+ }
+
+ for (i = 0; i < sizeof(long); i++) {
+ if (d == 0)
+ break;
+ buf[i] = (int)d & 0xff;
+ d >>= 8;
+ }
+ j = 0;
+ for (k = i - 1; k >= 0; k--)
+ a->data[j++] = buf[k];
+ a->length = j;
+ return (1);
+}
+
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
+{
+ int neg = 0, i;
+ long r = 0;
+
+ if (a == NULL)
+ return (0L);
+ i = a->type;
+ if (i == V_ASN1_NEG_ENUMERATED)
+ neg = 1;
+ else if (i != V_ASN1_ENUMERATED)
+ return -1;
+
+ if (a->length > (int)sizeof(long)) {
+ /* hmm... a bit ugly */
+ return (0xffffffffL);
+ }
+ if (a->data == NULL)
+ return 0;
+
+ for (i = 0; i < a->length; i++) {
+ r <<= 8;
+ r |= (unsigned char)a->data[i];
+ }
+ if (neg)
+ r = -r;
+ return (r);
+}
+
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
+{
+ ASN1_ENUMERATED *ret;
+ int len, j;
+
+ if (ai == NULL)
+ ret = M_ASN1_ENUMERATED_new();
+ else
+ ret = ai;
+ if (ret == NULL) {
+ ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if (BN_is_negative(bn))
+ ret->type = V_ASN1_NEG_ENUMERATED;
+ else
+ ret->type = V_ASN1_ENUMERATED;
+ j = BN_num_bits(bn);
+ len = ((j == 0) ? 0 : ((j / 8) + 1));
+ if (ret->length < len + 4) {
+ unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
+ if (!new_data) {
+ ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ret->data = new_data;
+ }
+
+ ret->length = BN_bn2bin(bn, ret->data);
+ return (ret);
+ err:
+ if (ret != ai)
+ M_ASN1_ENUMERATED_free(ret);
+ return (NULL);
+}
+
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
+{
+ BIGNUM *ret;
+
+ if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+ ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB);
+ else if (ai->type == V_ASN1_NEG_ENUMERATED)
+ BN_set_negative(ret, 1);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c b/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c
new file mode 100644
index 00000000..fa76dcac
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c
@@ -0,0 +1,312 @@
+/* crypto/asn1/a_gentm.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.]
+ */
+
+/*
+ * GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "o_time.h"
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+#if 0
+
+int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
+{
+# ifdef CHARSET_EBCDIC
+ /* KLUDGE! We convert to ascii before writing DER */
+ int len;
+ char tmp[24];
+ ASN1_STRING tmpstr = *(ASN1_STRING *)a;
+
+ len = tmpstr.length;
+ ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
+ tmpstr.data = tmp;
+
+ a = (ASN1_GENERALIZEDTIME *)&tmpstr;
+# endif
+ return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
+ V_ASN1_GENERALIZEDTIME, V_ASN1_UNIVERSAL));
+}
+
+ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
+ unsigned char **pp,
+ long length)
+{
+ ASN1_GENERALIZEDTIME *ret = NULL;
+
+ ret =
+ (ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
+ V_ASN1_GENERALIZEDTIME,
+ V_ASN1_UNIVERSAL);
+ if (ret == NULL) {
+ ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ERR_R_NESTED_ASN1_ERROR);
+ return (NULL);
+ }
+# ifdef CHARSET_EBCDIC
+ ascii2ebcdic(ret->data, ret->data, ret->length);
+# endif
+ if (!ASN1_GENERALIZEDTIME_check(ret)) {
+ ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ASN1_R_INVALID_TIME_FORMAT);
+ goto err;
+ }
+
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_GENERALIZEDTIME_free(ret);
+ return (NULL);
+}
+
+#endif
+
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
+{
+ 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;
+
+ if (d->type != V_ASN1_GENERALIZEDTIME)
+ return (0);
+ l = d->length;
+ a = (char *)d->data;
+ o = 0;
+ /*
+ * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+ * as YYYY. This stuff treats everything as a two digit field so make
+ * first two fields 00 to 99
+ */
+ if (l < 13)
+ goto err;
+ for (i = 0; i < 7; i++) {
+ if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+ i++;
+ if (tm)
+ tm->tm_sec = 0;
+ break;
+ }
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n * 100 - 1900;
+ break;
+ case 1:
+ tm->tm_year += n;
+ break;
+ case 2:
+ tm->tm_mon = n - 1;
+ break;
+ case 3:
+ tm->tm_mday = n;
+ break;
+ case 4:
+ tm->tm_hour = n;
+ break;
+ case 5:
+ tm->tm_min = n;
+ break;
+ case 6:
+ tm->tm_sec = n;
+ break;
+ }
+ }
+ }
+ /*
+ * Optional fractional seconds: decimal point followed by one or more
+ * digits.
+ */
+ if (a[o] == '.') {
+ if (++o > l)
+ goto err;
+ i = o;
+ while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
+ o++;
+ /* Must have at least one digit after decimal point */
+ if (i == o)
+ goto err;
+ }
+
+ if (a[o] == 'Z')
+ o++;
+ else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ o++;
+ if (o + 4 > l)
+ goto err;
+ for (i = 7; i < 9; i++) {
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ o++;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ if (i == 7)
+ offset = n * 3600;
+ else if (i == 8)
+ offset += n * 60;
+ }
+ o++;
+ }
+ if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+ return 0;
+ } else if (a[o]) {
+ /* Missing time zone information. */
+ goto err;
+ }
+ return (o == l);
+ err:
+ return (0);
+}
+
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
+{
+ return asn1_generalizedtime_to_tm(NULL, d);
+}
+
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
+{
+ ASN1_GENERALIZEDTIME t;
+
+ t.type = V_ASN1_GENERALIZEDTIME;
+ t.length = strlen(str);
+ t.data = (unsigned char *)str;
+ if (ASN1_GENERALIZEDTIME_check(&t)) {
+ if (s != NULL) {
+ if (!ASN1_STRING_set((ASN1_STRING *)s,
+ (unsigned char *)str, t.length))
+ return 0;
+ s->type = V_ASN1_GENERALIZEDTIME;
+ }
+ return (1);
+ } else
+ return (0);
+}
+
+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;
+ struct tm data;
+ size_t len = 20;
+
+ if (s == NULL)
+ s = M_ASN1_GENERALIZEDTIME_new();
+ if (s == NULL)
+ return (NULL);
+
+ ts = OPENSSL_gmtime(&t, &data);
+ 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_ADJ, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ if (s->data != NULL)
+ OPENSSL_free(s->data);
+ s->data = (unsigned char *)p;
+ }
+
+ BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
+ ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+ ts->tm_sec);
+ s->length = strlen(p);
+ s->type = V_ASN1_GENERALIZEDTIME;
+#ifdef CHARSET_EBCDIC_not
+ ebcdic2ascii(s->data, s->data, s->length);
+#endif
+ return (s);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_i2d_fp.c b/Cryptlib/OpenSSL/crypto/asn1/a_i2d_fp.c
new file mode 100644
index 00000000..0f56cd4e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_i2d_fp.c
@@ -0,0 +1,157 @@
+/* crypto/asn1/a_i2d_fp.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+# ifndef OPENSSL_NO_FP_API
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, out, BIO_NOCLOSE);
+ ret = ASN1_i2d_bio(i2d, b, x);
+ BIO_free(b);
+ return (ret);
+}
+# endif
+
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+{
+ char *b;
+ unsigned char *p;
+ int i, j = 0, n, ret = 1;
+
+ n = i2d(x, NULL);
+ b = (char *)OPENSSL_malloc(n);
+ if (b == NULL) {
+ ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+
+ p = (unsigned char *)b;
+ i2d(x, &p);
+
+ for (;;) {
+ i = BIO_write(out, &(b[j]), n);
+ if (i == n)
+ break;
+ if (i <= 0) {
+ ret = 0;
+ break;
+ }
+ j += i;
+ n -= i;
+ }
+ OPENSSL_free(b);
+ return (ret);
+}
+
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, out, BIO_NOCLOSE);
+ ret = ASN1_item_i2d_bio(it, b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
+{
+ unsigned char *b = NULL;
+ int i, j = 0, n, ret = 1;
+
+ n = ASN1_item_i2d(x, &b, it);
+ if (b == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+
+ for (;;) {
+ i = BIO_write(out, &(b[j]), n);
+ if (i == n)
+ break;
+ if (i <= 0) {
+ ret = 0;
+ break;
+ }
+ j += i;
+ n -= i;
+ }
+ OPENSSL_free(b);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_int.c b/Cryptlib/OpenSSL/crypto/asn1/a_int.c
new file mode 100644
index 00000000..7e26704a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_int.c
@@ -0,0 +1,464 @@
+/* crypto/asn1/a_int.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
+{
+ return M_ASN1_INTEGER_dup(x);
+}
+
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
+{
+ int neg, ret;
+ /* Compare signs */
+ neg = x->type & V_ASN1_NEG;
+ if (neg != (y->type & V_ASN1_NEG)) {
+ if (neg)
+ return -1;
+ else
+ return 1;
+ }
+
+ ret = ASN1_STRING_cmp(x, y);
+
+ if (neg)
+ return -ret;
+ else
+ return ret;
+}
+
+/*-
+ * This converts an ASN1 INTEGER into its content encoding.
+ * The internal representation is an ASN1_STRING whose data is a big endian
+ * representation of the value, ignoring the sign. The sign is determined by
+ * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
+ *
+ * Positive integers are no problem: they are almost the same as the DER
+ * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
+ *
+ * Negative integers are a bit trickier...
+ * The DER representation of negative integers is in 2s complement form.
+ * The internal form is converted by complementing each octet and finally
+ * adding one to the result. This can be done less messily with a little trick.
+ * If the internal form has trailing zeroes then they will become FF by the
+ * complement and 0 by the add one (due to carry) so just copy as many trailing
+ * zeros to the destination as there are in the source. The carry will add one
+ * to the last none zero octet: so complement this octet and add one and finally
+ * complement any left over until you get to the start of the string.
+ *
+ * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
+ * with 0xff. However if the first byte is 0x80 and one of the following bytes
+ * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
+ * followed by optional zeros isn't padded.
+ */
+
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+{
+ int pad = 0, ret, i, neg;
+ unsigned char *p, *n, pb = 0;
+
+ if (a == NULL)
+ return (0);
+ neg = a->type & V_ASN1_NEG;
+ if (a->length == 0)
+ ret = 1;
+ else {
+ ret = a->length;
+ i = a->data[0];
+ if (ret == 1 && i == 0)
+ neg = 0;
+ if (!neg && (i > 127)) {
+ pad = 1;
+ pb = 0;
+ } else if (neg) {
+ if (i > 128) {
+ pad = 1;
+ pb = 0xFF;
+ } else if (i == 128) {
+ /*
+ * Special case: if any other bytes non zero we pad:
+ * otherwise we don't.
+ */
+ for (i = 1; i < a->length; i++)
+ if (a->data[i]) {
+ pad = 1;
+ pb = 0xFF;
+ break;
+ }
+ }
+ }
+ ret += pad;
+ }
+ if (pp == NULL)
+ return (ret);
+ p = *pp;
+
+ if (pad)
+ *(p++) = pb;
+ if (a->length == 0)
+ *(p++) = 0;
+ else if (!neg)
+ memcpy(p, a->data, (unsigned int)a->length);
+ else {
+ /* Begin at the end of the encoding */
+ n = a->data + a->length - 1;
+ p += a->length - 1;
+ i = a->length;
+ /* Copy zeros to destination as long as source is zero */
+ while (!*n && i > 1) {
+ *(p--) = 0;
+ n--;
+ i--;
+ }
+ /* Complement and increment next octet */
+ *(p--) = ((*(n--)) ^ 0xff) + 1;
+ i--;
+ /* Complement any octets left */
+ for (; i > 0; i--)
+ *(p--) = *(n--) ^ 0xff;
+ }
+
+ *pp += ret;
+ return (ret);
+}
+
+/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
+
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+ long len)
+{
+ ASN1_INTEGER *ret = NULL;
+ const unsigned char *p, *pend;
+ unsigned char *to, *s;
+ int i;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = M_ASN1_INTEGER_new()) == NULL)
+ return (NULL);
+ ret->type = V_ASN1_INTEGER;
+ } else
+ ret = (*a);
+
+ p = *pp;
+ pend = p + len;
+
+ /*
+ * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+ * a missing NULL parameter.
+ */
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ to = s;
+ if (!len) {
+ /*
+ * Strictly speaking this is an illegal INTEGER but we tolerate it.
+ */
+ ret->type = V_ASN1_INTEGER;
+ } else if (*p & 0x80) { /* a negative number */
+ ret->type = V_ASN1_NEG_INTEGER;
+ if ((*p == 0xff) && (len != 1)) {
+ p++;
+ len--;
+ }
+ i = len;
+ p += i - 1;
+ to += i - 1;
+ while ((!*p) && i) {
+ *(to--) = 0;
+ i--;
+ p--;
+ }
+ /*
+ * Special case: if all zeros then the number will be of the form FF
+ * followed by n zero bytes: this corresponds to 1 followed by n zero
+ * bytes. We've already written n zeros so we just append an extra
+ * one and set the first byte to a 1. This is treated separately
+ * because it is the only case where the number of bytes is larger
+ * than len.
+ */
+ if (!i) {
+ *s = 1;
+ s[len] = 0;
+ len++;
+ } else {
+ *(to--) = (*(p--) ^ 0xff) + 1;
+ i--;
+ for (; i > 0; i--)
+ *(to--) = *(p--) ^ 0xff;
+ }
+ } else {
+ ret->type = V_ASN1_INTEGER;
+ if ((*p == 0) && (len != 1)) {
+ p++;
+ len--;
+ }
+ memcpy(s, p, (int)len);
+ }
+
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->data = s;
+ ret->length = (int)len;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = pend;
+ return (ret);
+ err:
+ ASN1err(ASN1_F_C2I_ASN1_INTEGER, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_INTEGER_free(ret);
+ return (NULL);
+}
+
+/*
+ * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
+ * integers: some broken software can encode a positive INTEGER with its MSB
+ * set as negative (it doesn't add a padding zero).
+ */
+
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+ long length)
+{
+ ASN1_INTEGER *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ long len;
+ int inf, tag, xclass;
+ int i;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = M_ASN1_INTEGER_new()) == NULL)
+ return (NULL);
+ ret->type = V_ASN1_INTEGER;
+ } else
+ ret = (*a);
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
+
+ if (tag != V_ASN1_INTEGER) {
+ i = ASN1_R_EXPECTING_AN_INTEGER;
+ goto err;
+ }
+
+ /*
+ * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+ * a missing NULL parameter.
+ */
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ ret->type = V_ASN1_INTEGER;
+ if (len) {
+ if ((*p == 0) && (len != 1)) {
+ p++;
+ len--;
+ }
+ memcpy(s, p, (int)len);
+ p += len;
+ }
+
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->data = s;
+ ret->length = (int)len;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_INTEGER_free(ret);
+ return (NULL);
+}
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
+{
+ int j, k;
+ unsigned int i;
+ unsigned char buf[sizeof(long) + 1];
+ long d;
+
+ a->type = V_ASN1_INTEGER;
+ if (a->length < (int)(sizeof(long) + 1)) {
+ if (a->data != NULL)
+ OPENSSL_free(a->data);
+ if ((a->data =
+ (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
+ memset((char *)a->data, 0, sizeof(long) + 1);
+ }
+ if (a->data == NULL) {
+ ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ d = v;
+ if (d < 0) {
+ d = -d;
+ a->type = V_ASN1_NEG_INTEGER;
+ }
+
+ for (i = 0; i < sizeof(long); i++) {
+ if (d == 0)
+ break;
+ buf[i] = (int)d & 0xff;
+ d >>= 8;
+ }
+ j = 0;
+ for (k = i - 1; k >= 0; k--)
+ a->data[j++] = buf[k];
+ a->length = j;
+ return (1);
+}
+
+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
+{
+ int neg = 0, i;
+ long r = 0;
+
+ if (a == NULL)
+ return (0L);
+ i = a->type;
+ if (i == V_ASN1_NEG_INTEGER)
+ neg = 1;
+ else if (i != V_ASN1_INTEGER)
+ return -1;
+
+ if (a->length > (int)sizeof(long)) {
+ /* hmm... a bit ugly, return all ones */
+ return -1;
+ }
+ if (a->data == NULL)
+ return 0;
+
+ for (i = 0; i < a->length; i++) {
+ r <<= 8;
+ r |= (unsigned char)a->data[i];
+ }
+ if (neg)
+ r = -r;
+ return (r);
+}
+
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
+{
+ ASN1_INTEGER *ret;
+ int len, j;
+
+ if (ai == NULL)
+ ret = M_ASN1_INTEGER_new();
+ else
+ ret = ai;
+ if (ret == NULL) {
+ ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if (BN_is_negative(bn) && !BN_is_zero(bn))
+ ret->type = V_ASN1_NEG_INTEGER;
+ else
+ ret->type = V_ASN1_INTEGER;
+ j = BN_num_bits(bn);
+ len = ((j == 0) ? 0 : ((j / 8) + 1));
+ if (ret->length < len + 4) {
+ unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
+ if (!new_data) {
+ ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ret->data = new_data;
+ }
+ ret->length = BN_bn2bin(bn, ret->data);
+ /* Correct zero case */
+ if (!ret->length) {
+ ret->data[0] = 0;
+ ret->length = 1;
+ }
+ return (ret);
+ err:
+ if (ret != ai)
+ M_ASN1_INTEGER_free(ret);
+ return (NULL);
+}
+
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
+{
+ BIGNUM *ret;
+
+ if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+ ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB);
+ else if (ai->type == V_ASN1_NEG_INTEGER)
+ BN_set_negative(ret, 1);
+ return (ret);
+}
+
+IMPLEMENT_STACK_OF(ASN1_INTEGER)
+
+IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_mbstr.c b/Cryptlib/OpenSSL/crypto/asn1/a_mbstr.c
new file mode 100644
index 00000000..6935efe0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_mbstr.c
@@ -0,0 +1,423 @@
+/* a_mbstr.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+ int (*rfunc) (unsigned long value, void *in),
+ void *arg);
+static int in_utf8(unsigned long value, void *arg);
+static int out_utf8(unsigned long value, void *arg);
+static int type_str(unsigned long value, void *arg);
+static int cpy_asc(unsigned long value, void *arg);
+static int cpy_bmp(unsigned long value, void *arg);
+static int cpy_univ(unsigned long value, void *arg);
+static int cpy_utf8(unsigned long value, void *arg);
+static int is_printable(unsigned long value);
+
+/*
+ * These functions take a string in UTF8, ASCII or multibyte form and a mask
+ * of permissible ASN1 string types. It then works out the minimal type
+ * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
+ * creates a string of the correct type with the supplied data. Yes this is
+ * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
+ * size limits too.
+ */
+
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+ int inform, unsigned long mask)
+{
+ return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+}
+
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+ int inform, unsigned long mask,
+ long minsize, long maxsize)
+{
+ int str_type;
+ int ret;
+ char free_out;
+ int outform, outlen = 0;
+ ASN1_STRING *dest;
+ unsigned char *p;
+ int nchar;
+ char strbuf[32];
+ int (*cpyfunc) (unsigned long, void *) = NULL;
+ if (len == -1)
+ len = strlen((const char *)in);
+ if (!mask)
+ mask = DIRSTRING_TYPE;
+
+ /* First do a string check and work out the number of characters */
+ switch (inform) {
+
+ case MBSTRING_BMP:
+ if (len & 1) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+ ASN1_R_INVALID_BMPSTRING_LENGTH);
+ return -1;
+ }
+ nchar = len >> 1;
+ break;
+
+ case MBSTRING_UNIV:
+ if (len & 3) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+ ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+ return -1;
+ }
+ nchar = len >> 2;
+ break;
+
+ case MBSTRING_UTF8:
+ nchar = 0;
+ /* This counts the characters and does utf8 syntax checking */
+ ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
+ if (ret < 0) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING);
+ return -1;
+ }
+ break;
+
+ case MBSTRING_ASC:
+ nchar = len;
+ break;
+
+ default:
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
+ return -1;
+ }
+
+ if ((minsize > 0) && (nchar < minsize)) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
+ BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
+ ERR_add_error_data(2, "minsize=", strbuf);
+ return -1;
+ }
+
+ if ((maxsize > 0) && (nchar > maxsize)) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
+ BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
+ ERR_add_error_data(2, "maxsize=", strbuf);
+ return -1;
+ }
+
+ /* Now work out minimal type (if any) */
+ if (traverse_string(in, len, inform, type_str, &mask) < 0) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
+ return -1;
+ }
+
+ /* Now work out output format and string type */
+ outform = MBSTRING_ASC;
+ if (mask & B_ASN1_PRINTABLESTRING)
+ str_type = V_ASN1_PRINTABLESTRING;
+ else if (mask & B_ASN1_IA5STRING)
+ str_type = V_ASN1_IA5STRING;
+ else if (mask & B_ASN1_T61STRING)
+ str_type = V_ASN1_T61STRING;
+ else if (mask & B_ASN1_BMPSTRING) {
+ str_type = V_ASN1_BMPSTRING;
+ outform = MBSTRING_BMP;
+ } else if (mask & B_ASN1_UNIVERSALSTRING) {
+ str_type = V_ASN1_UNIVERSALSTRING;
+ outform = MBSTRING_UNIV;
+ } else {
+ str_type = V_ASN1_UTF8STRING;
+ outform = MBSTRING_UTF8;
+ }
+ if (!out)
+ return str_type;
+ if (*out) {
+ free_out = 0;
+ dest = *out;
+ if (dest->data) {
+ dest->length = 0;
+ OPENSSL_free(dest->data);
+ dest->data = NULL;
+ }
+ dest->type = str_type;
+ } else {
+ free_out = 1;
+ dest = ASN1_STRING_type_new(str_type);
+ if (!dest) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ *out = dest;
+ }
+ /* If both the same type just copy across */
+ if (inform == outform) {
+ if (!ASN1_STRING_set(dest, in, len)) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ return str_type;
+ }
+
+ /* Work out how much space the destination will need */
+ switch (outform) {
+ case MBSTRING_ASC:
+ outlen = nchar;
+ cpyfunc = cpy_asc;
+ break;
+
+ case MBSTRING_BMP:
+ outlen = nchar << 1;
+ cpyfunc = cpy_bmp;
+ break;
+
+ case MBSTRING_UNIV:
+ outlen = nchar << 2;
+ cpyfunc = cpy_univ;
+ break;
+
+ case MBSTRING_UTF8:
+ outlen = 0;
+ traverse_string(in, len, inform, out_utf8, &outlen);
+ cpyfunc = cpy_utf8;
+ break;
+ }
+ if (!(p = OPENSSL_malloc(outlen + 1))) {
+ if (free_out)
+ ASN1_STRING_free(dest);
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ dest->length = outlen;
+ dest->data = p;
+ p[outlen] = 0;
+ traverse_string(in, len, inform, cpyfunc, &p);
+ return str_type;
+}
+
+/*
+ * This function traverses a string and passes the value of each character to
+ * an optional function along with a void * argument.
+ */
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+ int (*rfunc) (unsigned long value, void *in),
+ void *arg)
+{
+ unsigned long value;
+ int ret;
+ while (len) {
+ if (inform == MBSTRING_ASC) {
+ value = *p++;
+ len--;
+ } else if (inform == MBSTRING_BMP) {
+ value = *p++ << 8;
+ value |= *p++;
+ len -= 2;
+ } else if (inform == MBSTRING_UNIV) {
+ value = ((unsigned long)*p++) << 24;
+ value |= ((unsigned long)*p++) << 16;
+ value |= *p++ << 8;
+ value |= *p++;
+ len -= 4;
+ } else {
+ ret = UTF8_getc(p, len, &value);
+ if (ret < 0)
+ return -1;
+ len -= ret;
+ p += ret;
+ }
+ if (rfunc) {
+ ret = rfunc(value, arg);
+ if (ret <= 0)
+ return ret;
+ }
+ }
+ return 1;
+}
+
+/* Various utility functions for traverse_string */
+
+/* Just count number of characters */
+
+static int in_utf8(unsigned long value, void *arg)
+{
+ int *nchar;
+ nchar = arg;
+ (*nchar)++;
+ return 1;
+}
+
+/* Determine size of output as a UTF8 String */
+
+static int out_utf8(unsigned long value, void *arg)
+{
+ int *outlen;
+ outlen = arg;
+ *outlen += UTF8_putc(NULL, -1, value);
+ return 1;
+}
+
+/*
+ * Determine the "type" of a string: check each character against a supplied
+ * "mask".
+ */
+
+static int type_str(unsigned long value, void *arg)
+{
+ unsigned long types;
+ types = *((unsigned long *)arg);
+ if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
+ types &= ~B_ASN1_PRINTABLESTRING;
+ if ((types & B_ASN1_IA5STRING) && (value > 127))
+ types &= ~B_ASN1_IA5STRING;
+ if ((types & B_ASN1_T61STRING) && (value > 0xff))
+ types &= ~B_ASN1_T61STRING;
+ if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+ types &= ~B_ASN1_BMPSTRING;
+ if (!types)
+ return -1;
+ *((unsigned long *)arg) = types;
+ return 1;
+}
+
+/* Copy one byte per character ASCII like strings */
+
+static int cpy_asc(unsigned long value, void *arg)
+{
+ unsigned char **p, *q;
+ p = arg;
+ q = *p;
+ *q = (unsigned char)value;
+ (*p)++;
+ return 1;
+}
+
+/* Copy two byte per character BMPStrings */
+
+static int cpy_bmp(unsigned long value, void *arg)
+{
+ unsigned char **p, *q;
+ p = arg;
+ q = *p;
+ *q++ = (unsigned char)((value >> 8) & 0xff);
+ *q = (unsigned char)(value & 0xff);
+ *p += 2;
+ return 1;
+}
+
+/* Copy four byte per character UniversalStrings */
+
+static int cpy_univ(unsigned long value, void *arg)
+{
+ unsigned char **p, *q;
+ p = arg;
+ q = *p;
+ *q++ = (unsigned char)((value >> 24) & 0xff);
+ *q++ = (unsigned char)((value >> 16) & 0xff);
+ *q++ = (unsigned char)((value >> 8) & 0xff);
+ *q = (unsigned char)(value & 0xff);
+ *p += 4;
+ return 1;
+}
+
+/* Copy to a UTF8String */
+
+static int cpy_utf8(unsigned long value, void *arg)
+{
+ unsigned char **p;
+ int ret;
+ p = arg;
+ /* We already know there is enough room so pass 0xff as the length */
+ ret = UTF8_putc(*p, 0xff, value);
+ *p += ret;
+ return 1;
+}
+
+/* Return 1 if the character is permitted in a PrintableString */
+static int is_printable(unsigned long value)
+{
+ int ch;
+ if (value > 0x7f)
+ return 0;
+ ch = (int)value;
+ /*
+ * Note: we can't use 'isalnum' because certain accented characters may
+ * count as alphanumeric in some environments.
+ */
+#ifndef CHARSET_EBCDIC
+ if ((ch >= 'a') && (ch <= 'z'))
+ return 1;
+ if ((ch >= 'A') && (ch <= 'Z'))
+ return 1;
+ if ((ch >= '0') && (ch <= '9'))
+ return 1;
+ if ((ch == ' ') || strchr("'()+,-./:=?", ch))
+ return 1;
+#else /* CHARSET_EBCDIC */
+ if ((ch >= os_toascii['a']) && (ch <= os_toascii['z']))
+ return 1;
+ if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z']))
+ return 1;
+ if ((ch >= os_toascii['0']) && (ch <= os_toascii['9']))
+ return 1;
+ if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch]))
+ return 1;
+#endif /* CHARSET_EBCDIC */
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_object.c b/Cryptlib/OpenSSL/crypto/asn1/a_object.c
new file mode 100644
index 00000000..27f9c169
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_object.c
@@ -0,0 +1,402 @@
+/* crypto/asn1/a_object.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 <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+
+int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
+{
+ unsigned char *p;
+ int objsize;
+
+ if ((a == NULL) || (a->data == NULL))
+ return (0);
+
+ objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
+ if (pp == NULL)
+ return objsize;
+
+ p = *pp;
+ ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+ memcpy(p, a->data, a->length);
+ p += a->length;
+
+ *pp = p;
+ return (objsize);
+}
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
+{
+ int i, first, len = 0, c, use_bn;
+ char ftmp[24], *tmp = ftmp;
+ int tmpsize = sizeof ftmp;
+ const char *p;
+ unsigned long l;
+ BIGNUM *bl = NULL;
+
+ if (num == 0)
+ return (0);
+ else if (num == -1)
+ num = strlen(buf);
+
+ p = buf;
+ c = *(p++);
+ num--;
+ if ((c >= '0') && (c <= '2')) {
+ first = c - '0';
+ } else {
+ ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+ goto err;
+ }
+
+ if (num <= 0) {
+ ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+ goto err;
+ }
+ c = *(p++);
+ num--;
+ for (;;) {
+ if (num <= 0)
+ break;
+ if ((c != '.') && (c != ' ')) {
+ ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
+ goto err;
+ }
+ l = 0;
+ use_bn = 0;
+ for (;;) {
+ if (num <= 0)
+ break;
+ num--;
+ c = *(p++);
+ if ((c == ' ') || (c == '.'))
+ break;
+ if ((c < '0') || (c > '9')) {
+ ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
+ goto err;
+ }
+ if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
+ use_bn = 1;
+ if (!bl)
+ bl = BN_new();
+ if (!bl || !BN_set_word(bl, l))
+ goto err;
+ }
+ if (use_bn) {
+ if (!BN_mul_word(bl, 10L)
+ || !BN_add_word(bl, c - '0'))
+ goto err;
+ } else
+ l = l * 10L + (long)(c - '0');
+ }
+ if (len == 0) {
+ if ((first < 2) && (l >= 40)) {
+ ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+ ASN1_R_SECOND_NUMBER_TOO_LARGE);
+ goto err;
+ }
+ if (use_bn) {
+ if (!BN_add_word(bl, first * 40))
+ goto err;
+ } else
+ l += (long)first *40;
+ }
+ i = 0;
+ if (use_bn) {
+ int blsize;
+ blsize = BN_num_bits(bl);
+ blsize = (blsize + 6) / 7;
+ if (blsize > tmpsize) {
+ if (tmp != ftmp)
+ OPENSSL_free(tmp);
+ tmpsize = blsize + 32;
+ tmp = OPENSSL_malloc(tmpsize);
+ if (!tmp)
+ goto err;
+ }
+ while (blsize--)
+ tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+ } else {
+
+ for (;;) {
+ tmp[i++] = (unsigned char)l & 0x7f;
+ l >>= 7L;
+ if (l == 0L)
+ break;
+ }
+
+ }
+ if (out != NULL) {
+ if (len + i > olen) {
+ ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+ while (--i > 0)
+ out[len++] = tmp[i] | 0x80;
+ out[len++] = tmp[0];
+ } else
+ len += i;
+ }
+ if (tmp != ftmp)
+ OPENSSL_free(tmp);
+ if (bl)
+ BN_free(bl);
+ return (len);
+ err:
+ if (tmp != ftmp)
+ OPENSSL_free(tmp);
+ if (bl)
+ BN_free(bl);
+ return (0);
+}
+
+int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
+{
+ return OBJ_obj2txt(buf, buf_len, a, 0);
+}
+
+int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
+{
+ char buf[80], *p = buf;
+ int i;
+
+ if ((a == NULL) || (a->data == NULL))
+ return (BIO_write(bp, "NULL", 4));
+ i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
+ if (i > (int)(sizeof(buf) - 1)) {
+ p = OPENSSL_malloc(i + 1);
+ if (!p)
+ return -1;
+ i2t_ASN1_OBJECT(p, i + 1, a);
+ }
+ if (i <= 0)
+ return BIO_write(bp, "<INVALID>", 9);
+ BIO_write(bp, p, i);
+ if (p != buf)
+ OPENSSL_free(p);
+ return (i);
+}
+
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+ long length)
+{
+ const unsigned char *p;
+ long len;
+ int tag, xclass;
+ int inf, i;
+ ASN1_OBJECT *ret = NULL;
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
+
+ if (tag != V_ASN1_OBJECT) {
+ i = ASN1_R_EXPECTING_AN_OBJECT;
+ goto err;
+ }
+ ret = c2i_ASN1_OBJECT(a, &p, len);
+ if (ret)
+ *pp = p;
+ return ret;
+ err:
+ ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
+ return (NULL);
+}
+
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+ long len)
+{
+ ASN1_OBJECT *ret = NULL;
+ const unsigned char *p;
+ unsigned char *data;
+ int i, length;
+
+ /*
+ * Sanity check OID encoding. Need at least one content octet. MSB must
+ * be clear in the last octet. can't have leading 0x80 in subidentifiers,
+ * see: X.690 8.19.2
+ */
+ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+ p[len - 1] & 0x80) {
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ /* Now 0 < len <= INT_MAX, so the cast is safe. */
+ length = (int)len;
+ for (i = 0; i < length; i++, p++) {
+ if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ }
+
+ /*
+ * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
+ * ->ln
+ */
+ if ((a == NULL) || ((*a) == NULL) ||
+ !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
+ if ((ret = ASN1_OBJECT_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ p = *pp;
+ /* detach data from object */
+ data = (unsigned char *)ret->data;
+ ret->data = NULL;
+ /* once detached we can change it */
+ if ((data == NULL) || (ret->length < length)) {
+ ret->length = 0;
+ if (data != NULL)
+ OPENSSL_free(data);
+ data = (unsigned char *)OPENSSL_malloc(length);
+ if (data == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+ }
+ memcpy(data, p, length);
+ /* reattach data to object, after which it remains const */
+ ret->data = data;
+ ret->length = length;
+ ret->sn = NULL;
+ ret->ln = NULL;
+ /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+ p += length;
+
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ ASN1_OBJECT_free(ret);
+ return (NULL);
+}
+
+ASN1_OBJECT *ASN1_OBJECT_new(void)
+{
+ ASN1_OBJECT *ret;
+
+ ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
+ if (ret == NULL) {
+ ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->length = 0;
+ ret->data = NULL;
+ ret->nid = 0;
+ ret->sn = NULL;
+ ret->ln = NULL;
+ ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
+ return (ret);
+}
+
+void ASN1_OBJECT_free(ASN1_OBJECT *a)
+{
+ if (a == NULL)
+ return;
+ if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
+#ifndef CONST_STRICT /* disable purely for compile-time strict
+ * const checking. Doing this on a "real"
+ * compile will cause memory leaks */
+ if (a->sn != NULL)
+ OPENSSL_free((void *)a->sn);
+ if (a->ln != NULL)
+ OPENSSL_free((void *)a->ln);
+#endif
+ a->sn = a->ln = NULL;
+ }
+ if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
+ if (a->data != NULL)
+ OPENSSL_free((void *)a->data);
+ a->data = NULL;
+ a->length = 0;
+ }
+ if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+ OPENSSL_free(a);
+}
+
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+ const char *sn, const char *ln)
+{
+ ASN1_OBJECT o;
+
+ o.sn = sn;
+ o.ln = ln;
+ o.data = data;
+ o.nid = nid;
+ o.length = len;
+ o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+ ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+ return (OBJ_dup(&o));
+}
+
+IMPLEMENT_STACK_OF(ASN1_OBJECT)
+
+IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_octet.c b/Cryptlib/OpenSSL/crypto/asn1/a_octet.c
new file mode 100644
index 00000000..1a6e9ca9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_octet.c
@@ -0,0 +1,78 @@
+/* crypto/asn1/a_octet.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
+{
+ return M_ASN1_OCTET_STRING_dup(x);
+}
+
+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)
+{
+ return M_ASN1_OCTET_STRING_set(x, d, len);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_print.c b/Cryptlib/OpenSSL/crypto/asn1/a_print.c
new file mode 100644
index 00000000..d83e4ad8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_print.c
@@ -0,0 +1,129 @@
+/* crypto/asn1/a_print.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+int ASN1_PRINTABLE_type(const unsigned char *s, int len)
+{
+ int c;
+ int ia5 = 0;
+ int t61 = 0;
+
+ if (len <= 0)
+ len = -1;
+ if (s == NULL)
+ return (V_ASN1_PRINTABLESTRING);
+
+ while ((*s) && (len-- != 0)) {
+ c = *(s++);
+#ifndef CHARSET_EBCDIC
+ if (!(((c >= 'a') && (c <= 'z')) ||
+ ((c >= 'A') && (c <= 'Z')) ||
+ (c == ' ') ||
+ ((c >= '0') && (c <= '9')) ||
+ (c == ' ') || (c == '\'') ||
+ (c == '(') || (c == ')') ||
+ (c == '+') || (c == ',') ||
+ (c == '-') || (c == '.') ||
+ (c == '/') || (c == ':') || (c == '=') || (c == '?')))
+ ia5 = 1;
+ if (c & 0x80)
+ t61 = 1;
+#else
+ if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL)
+ ia5 = 1;
+ if (os_toascii[c] & 0x80)
+ t61 = 1;
+#endif
+ }
+ if (t61)
+ return (V_ASN1_T61STRING);
+ if (ia5)
+ return (V_ASN1_IA5STRING);
+ return (V_ASN1_PRINTABLESTRING);
+}
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
+{
+ int i;
+ unsigned char *p;
+
+ if (s->type != V_ASN1_UNIVERSALSTRING)
+ return (0);
+ if ((s->length % 4) != 0)
+ return (0);
+ p = s->data;
+ for (i = 0; i < s->length; i += 4) {
+ if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+ break;
+ else
+ p += 4;
+ }
+ if (i < s->length)
+ return (0);
+ p = s->data;
+ for (i = 3; i < s->length; i += 4) {
+ *(p++) = s->data[i];
+ }
+ *(p) = '\0';
+ s->length /= 4;
+ s->type = ASN1_PRINTABLE_type(s->data, s->length);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_set.c b/Cryptlib/OpenSSL/crypto/asn1/a_set.c
new file mode 100644
index 00000000..bf3f9718
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_set.c
@@ -0,0 +1,238 @@
+/* crypto/asn1/a_set.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1_mac.h>
+
+#ifndef NO_ASN1_OLD
+
+typedef struct {
+ unsigned char *pbData;
+ int cbData;
+} MYBLOB;
+
+/*
+ * SetBlobCmp This function compares two elements of SET_OF block
+ */
+static int SetBlobCmp(const void *elem1, const void *elem2)
+{
+ const MYBLOB *b1 = (const MYBLOB *)elem1;
+ const MYBLOB *b2 = (const MYBLOB *)elem2;
+ int r;
+
+ r = memcmp(b1->pbData, b2->pbData,
+ b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
+ if (r != 0)
+ return r;
+ return b1->cbData - b2->cbData;
+}
+
+/*
+ * int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)
+ */
+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;
+ unsigned char *p;
+ unsigned char *pStart, *pTempMem;
+ MYBLOB *rgSetBlob;
+ int totSize;
+
+ if (a == NULL)
+ return (0);
+ 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);
+
+ p = *pp;
+ ASN1_put_object(&p, 1, ret, ex_tag, ex_class);
+
+/* Modified by gp@nsj.co.jp */
+ /* And then again by Ben */
+ /* And again by Steve */
+
+ if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) {
+ for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++)
+ i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
+
+ *pp = p;
+ return (r);
+ }
+
+ pStart = p; /* Catch the beg of Setblobs */
+ /* In this array we will store the SET blobs */
+ rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
+ if (rgSetBlob == NULL) {
+ ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+
+ for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) {
+ rgSetBlob[i].pbData = p; /* catch each set encode blob */
+ i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
+ rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
+ * SetBlob */
+ }
+ *pp = p;
+ totSize = p - pStart; /* This is the total size of all set blobs */
+
+ /*
+ * Now we have to sort the blobs. I am using a simple algo. *Sort ptrs
+ * *Copy to temp-mem *Copy from temp-mem to user-mem
+ */
+ qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
+ if (!(pTempMem = OPENSSL_malloc(totSize))) {
+ ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+
+/* Copy to temp mem */
+ p = pTempMem;
+ for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) {
+ memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
+ p += rgSetBlob[i].cbData;
+ }
+
+/* Copy back to user mem*/
+ memcpy(pStart, pTempMem, totSize);
+ OPENSSL_free(pTempMem);
+ OPENSSL_free(rgSetBlob);
+
+ return (r);
+}
+
+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)
+{
+ ASN1_const_CTX c;
+ STACK_OF(OPENSSL_BLOCK) *ret = NULL;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) {
+ ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else
+ ret = (*a);
+
+ c.p = *pp;
+ c.max = (length == 0) ? 0 : (c.p + length);
+
+ c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p);
+ if (c.inf & 0x80)
+ goto err;
+ if (ex_class != c.xclass) {
+ ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS);
+ goto err;
+ }
+ if (ex_tag != c.tag) {
+ ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG);
+ goto err;
+ }
+ if ((c.slen + c.p) > c.max) {
+ ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR);
+ goto err;
+ }
+ /*
+ * check for infinite constructed - it can be as long as the amount of
+ * data passed to us
+ */
+ if (c.inf == (V_ASN1_CONSTRUCTED + 1))
+ c.slen = length + *pp - c.p;
+ c.max = c.p + c.slen;
+
+ while (c.p < c.max) {
+ char *s;
+
+ if (M_ASN1_D2I_end_sequence())
+ break;
+ /*
+ * XXX: This was called with 4 arguments, incorrectly, it seems if
+ * ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL)
+ */
+ if ((s = d2i(NULL, &c.p, c.slen)) == NULL) {
+ ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT);
+ asn1_add_error(*pp, (int)(c.p - *pp));
+ goto err;
+ }
+ if (!sk_OPENSSL_BLOCK_push(ret, s))
+ goto err;
+ }
+ if (a != NULL)
+ (*a) = ret;
+ *pp = c.p;
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret))) {
+ if (free_func != NULL)
+ sk_OPENSSL_BLOCK_pop_free(ret, free_func);
+ else
+ sk_OPENSSL_BLOCK_free(ret);
+ }
+ return (NULL);
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_sign.c b/Cryptlib/OpenSSL/crypto/asn1/a_sign.c
new file mode 100644
index 00000000..51c6a0c3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_sign.c
@@ -0,0 +1,331 @@
+/* crypto/asn1/a_sign.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-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 <stdio.h>
+#include <time.h>
+
+#include "cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "asn1_locl.h"
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
+ const EVP_MD *type)
+{
+ EVP_MD_CTX ctx;
+ unsigned char *p, *buf_in = NULL, *buf_out = NULL;
+ int i, inl = 0, outl = 0, outll = 0;
+ X509_ALGOR *a;
+
+ EVP_MD_CTX_init(&ctx);
+ for (i = 0; i < 2; i++) {
+ if (i == 0)
+ a = algor1;
+ else
+ a = algor2;
+ if (a == NULL)
+ continue;
+ if (type->pkey_type == NID_dsaWithSHA1) {
+ /*
+ * special case: RFC 2459 tells us to omit 'parameters' with
+ * id-dsa-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_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
+ goto err;
+ }
+ if (a->algorithm->length == 0) {
+ ASN1err(ASN1_F_ASN1_SIGN,
+ ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+ goto err;
+ }
+ }
+ inl = i2d(data, NULL);
+ buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl);
+ outll = outl = EVP_PKEY_size(pkey);
+ buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl);
+ if ((buf_in == NULL) || (buf_out == NULL)) {
+ outl = 0;
+ ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = buf_in;
+
+ i2d(data, &p);
+ if (!EVP_SignInit_ex(&ctx, type, NULL)
+ || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl)
+ || !EVP_SignFinal(&ctx, (unsigned char *)buf_out,
+ (unsigned int *)&outl, pkey)) {
+ outl = 0;
+ ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
+ goto err;
+ }
+ if (signature->data != NULL)
+ OPENSSL_free(signature->data);
+ signature->data = buf_out;
+ buf_out = NULL;
+ signature->length = outl;
+ /*
+ * In the interests of compatibility, I'll make sure that the bit string
+ * has a 'not-used bits' value of 0
+ */
+ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ if (buf_in != NULL) {
+ OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+ }
+ if (buf_out != NULL) {
+ OPENSSL_cleanse((char *)buf_out, outll);
+ OPENSSL_free(buf_out);
+ }
+ return (outl);
+}
+
+#endif
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
+ EVP_PKEY *pkey, const EVP_MD *type)
+{
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
+ EVP_MD_CTX_cleanup(&ctx);
+ return 0;
+ }
+ return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+}
+
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+ X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+ const EVP_MD *type;
+ EVP_PKEY *pkey;
+ unsigned char *buf_in = NULL, *buf_out = NULL;
+ size_t inl = 0, outl = 0, outll = 0;
+ int signid, paramtype;
+ int rv;
+
+ type = EVP_MD_CTX_md(ctx);
+ pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+
+ if (!type || !pkey) {
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+ return 0;
+ }
+
+ if (pkey->ameth->item_sign) {
+ rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
+ if (rv == 1)
+ outl = signature->length;
+ /*-
+ * Return value meanings:
+ * <=0: error.
+ * 1: method does everything.
+ * 2: carry on as normal.
+ * 3: ASN1 method sets algorithm identifiers: just sign.
+ */
+ if (rv <= 0)
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+ if (rv <= 1)
+ goto err;
+ } else
+ rv = 2;
+
+ if (rv == 2) {
+ 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_CTX,
+ 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);
+
+ }
+
+ inl = ASN1_item_i2d(asn, &buf_in, it);
+ outll = outl = EVP_PKEY_size(pkey);
+ buf_out = OPENSSL_malloc((unsigned int)outl);
+ if ((buf_in == NULL) || (buf_out == NULL)) {
+ outl = 0;
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+ || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+ outl = 0;
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+ goto err;
+ }
+ if (signature->data != NULL)
+ OPENSSL_free(signature->data);
+ signature->data = buf_out;
+ buf_out = NULL;
+ signature->length = outl;
+ /*
+ * In the interests of compatibility, I'll make sure that the bit string
+ * has a 'not-used bits' value of 0
+ */
+ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+ EVP_MD_CTX_cleanup(ctx);
+ if (buf_in != NULL) {
+ OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+ }
+ if (buf_out != NULL) {
+ OPENSSL_cleanse((char *)buf_out, outll);
+ OPENSSL_free(buf_out);
+ }
+ return (outl);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_strex.c b/Cryptlib/OpenSSL/crypto/asn1/a_strex.c
new file mode 100644
index 00000000..9f39bff8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_strex.c
@@ -0,0 +1,651 @@
+/* a_strex.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+#include "charmap.h"
+
+/*
+ * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
+ * printing routines handling multibyte characters, RFC2253 and a host of
+ * other options.
+ */
+
+#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+
+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
+ ASN1_STRFLGS_ESC_QUOTE | \
+ ASN1_STRFLGS_ESC_CTRL | \
+ ASN1_STRFLGS_ESC_MSB)
+
+/*
+ * Three IO functions for sending data to memory, a BIO and and a FILE
+ * pointer.
+ */
+#if 0 /* never used */
+static int send_mem_chars(void *arg, const void *buf, int len)
+{
+ unsigned char **out = arg;
+ if (!out)
+ return 1;
+ memcpy(*out, buf, len);
+ *out += len;
+ return 1;
+}
+#endif
+
+static int send_bio_chars(void *arg, const void *buf, int len)
+{
+ if (!arg)
+ return 1;
+ if (BIO_write(arg, buf, len) != len)
+ return 0;
+ return 1;
+}
+
+#ifndef OPENSSL_NO_FP_API
+static int send_fp_chars(void *arg, const void *buf, int len)
+{
+ if (!arg)
+ return 1;
+ if (fwrite(buf, 1, len, arg) != (unsigned int)len)
+ return 0;
+ return 1;
+}
+#endif
+
+typedef int char_io (void *arg, const void *buf, int len);
+
+/*
+ * This function handles display of strings, one character at a time. It is
+ * passed an unsigned long for each character because it could come from 2 or
+ * even 4 byte forms.
+ */
+
+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
+ char_io *io_ch, void *arg)
+{
+ unsigned char chflgs, chtmp;
+ char tmphex[HEX_SIZE(long) + 3];
+
+ if (c > 0xffffffffL)
+ return -1;
+ if (c > 0xffff) {
+ BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+ if (!io_ch(arg, tmphex, 10))
+ return -1;
+ return 10;
+ }
+ if (c > 0xff) {
+ BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+ if (!io_ch(arg, tmphex, 6))
+ return -1;
+ return 6;
+ }
+ chtmp = (unsigned char)c;
+ if (chtmp > 0x7f)
+ chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+ else
+ chflgs = char_type[chtmp] & flags;
+ if (chflgs & CHARTYPE_BS_ESC) {
+ /* If we don't escape with quotes, signal we need quotes */
+ if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+ if (do_quotes)
+ *do_quotes = 1;
+ if (!io_ch(arg, &chtmp, 1))
+ return -1;
+ return 1;
+ }
+ if (!io_ch(arg, "\\", 1))
+ return -1;
+ if (!io_ch(arg, &chtmp, 1))
+ return -1;
+ return 2;
+ }
+ if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) {
+ BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+ if (!io_ch(arg, tmphex, 3))
+ return -1;
+ return 3;
+ }
+ /*
+ * If we get this far and do any escaping at all must escape the escape
+ * character itself: backslash.
+ */
+ if (chtmp == '\\' && flags & ESC_FLAGS) {
+ if (!io_ch(arg, "\\\\", 2))
+ return -1;
+ return 2;
+ }
+ if (!io_ch(arg, &chtmp, 1))
+ return -1;
+ return 1;
+}
+
+#define BUF_TYPE_WIDTH_MASK 0x7
+#define BUF_TYPE_CONVUTF8 0x8
+
+/*
+ * This function sends each character in a buffer to do_esc_char(). It
+ * interprets the content formats and converts to or from UTF8 as
+ * appropriate.
+ */
+
+static int do_buf(unsigned char *buf, int buflen,
+ int type, unsigned char flags, char *quotes, char_io *io_ch,
+ void *arg)
+{
+ int i, outlen, len;
+ unsigned char orflags, *p, *q;
+ unsigned long c;
+ p = buf;
+ q = buf + buflen;
+ outlen = 0;
+ while (p != q) {
+ if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
+ orflags = CHARTYPE_FIRST_ESC_2253;
+ else
+ orflags = 0;
+ switch (type & BUF_TYPE_WIDTH_MASK) {
+ case 4:
+ c = ((unsigned long)*p++) << 24;
+ c |= ((unsigned long)*p++) << 16;
+ c |= ((unsigned long)*p++) << 8;
+ c |= *p++;
+ break;
+
+ case 2:
+ c = ((unsigned long)*p++) << 8;
+ c |= *p++;
+ break;
+
+ case 1:
+ c = *p++;
+ break;
+
+ case 0:
+ i = UTF8_getc(p, buflen, &c);
+ if (i < 0)
+ return -1; /* Invalid UTF8String */
+ p += i;
+ break;
+ default:
+ return -1; /* invalid width */
+ }
+ if (p == q && flags & ASN1_STRFLGS_ESC_2253)
+ orflags = CHARTYPE_LAST_ESC_2253;
+ if (type & BUF_TYPE_CONVUTF8) {
+ unsigned char utfbuf[6];
+ int utflen;
+ utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+ for (i = 0; i < utflen; i++) {
+ /*
+ * We don't need to worry about setting orflags correctly
+ * because if utflen==1 its value will be correct anyway
+ * otherwise each character will be > 0x7f and so the
+ * character will never be escaped on first and last.
+ */
+ len =
+ do_esc_char(utfbuf[i], (unsigned char)(flags | orflags),
+ quotes, io_ch, arg);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ }
+ } else {
+ len =
+ do_esc_char(c, (unsigned char)(flags | orflags), quotes,
+ io_ch, arg);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ }
+ }
+ return outlen;
+}
+
+/* This function hex dumps a buffer of characters */
+
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
+ int buflen)
+{
+ static const char hexdig[] = "0123456789ABCDEF";
+ unsigned char *p, *q;
+ char hextmp[2];
+ if (arg) {
+ p = buf;
+ q = buf + buflen;
+ while (p != q) {
+ hextmp[0] = hexdig[*p >> 4];
+ hextmp[1] = hexdig[*p & 0xf];
+ if (!io_ch(arg, hextmp, 2))
+ return -1;
+ p++;
+ }
+ }
+ return buflen << 1;
+}
+
+/*
+ * "dump" a string. This is done when the type is unknown, or the flags
+ * request it. We can either dump the content octets or the entire DER
+ * encoding. This uses the RFC2253 #01234 format.
+ */
+
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
+ ASN1_STRING *str)
+{
+ /*
+ * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
+ * readily obtained
+ */
+ ASN1_TYPE t;
+ unsigned char *der_buf, *p;
+ int outlen, der_len;
+
+ if (!io_ch(arg, "#", 1))
+ return -1;
+ /* If we don't dump DER encoding just dump content octets */
+ if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+ outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+ if (outlen < 0)
+ return -1;
+ return outlen + 1;
+ }
+ t.type = str->type;
+ t.value.ptr = (char *)str;
+ der_len = i2d_ASN1_TYPE(&t, NULL);
+ der_buf = OPENSSL_malloc(der_len);
+ if (!der_buf)
+ return -1;
+ p = der_buf;
+ i2d_ASN1_TYPE(&t, &p);
+ outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+ OPENSSL_free(der_buf);
+ if (outlen < 0)
+ return -1;
+ return outlen + 1;
+}
+
+/*
+ * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is
+ * used for non string types otherwise it is the number of bytes per
+ * character
+ */
+
+static const signed char tag2nbyte[] = {
+ -1, -1, -1, -1, -1, /* 0-4 */
+ -1, -1, -1, -1, -1, /* 5-9 */
+ -1, -1, 0, -1, /* 10-13 */
+ -1, -1, -1, -1, /* 15-17 */
+ -1, 1, 1, /* 18-20 */
+ -1, 1, 1, 1, /* 21-24 */
+ -1, 1, -1, /* 25-27 */
+ 4, -1, 2 /* 28-30 */
+};
+
+/*
+ * This is the main function, print out an ASN1_STRING taking note of various
+ * escape and display options. Returns number of characters written or -1 if
+ * an error occurred.
+ */
+
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
+ ASN1_STRING *str)
+{
+ int outlen, len;
+ int type;
+ char quotes;
+ unsigned char flags;
+ quotes = 0;
+ /* Keep a copy of escape flags */
+ flags = (unsigned char)(lflags & ESC_FLAGS);
+
+ type = str->type;
+
+ outlen = 0;
+
+ if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
+ const char *tagname;
+ tagname = ASN1_tag2str(type);
+ outlen += strlen(tagname);
+ if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
+ return -1;
+ outlen++;
+ }
+
+ /* Decide what to do with type, either dump content or display it */
+
+ /* Dump everything */
+ if (lflags & ASN1_STRFLGS_DUMP_ALL)
+ type = -1;
+ /* Ignore the string type */
+ else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+ type = 1;
+ else {
+ /* Else determine width based on type */
+ if ((type > 0) && (type < 31))
+ type = tag2nbyte[type];
+ else
+ type = -1;
+ if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+ type = 1;
+ }
+
+ if (type == -1) {
+ len = do_dump(lflags, io_ch, arg, str);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ return outlen;
+ }
+
+ if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+ /*
+ * Note: if string is UTF8 and we want to convert to UTF8 then we
+ * just interpret it as 1 byte per character to avoid converting
+ * twice.
+ */
+ if (!type)
+ type = 1;
+ else
+ type |= BUF_TYPE_CONVUTF8;
+ }
+
+ len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ if (quotes)
+ outlen += 2;
+ if (!arg)
+ return outlen;
+ if (quotes && !io_ch(arg, "\"", 1))
+ return -1;
+ if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+ return -1;
+ if (quotes && !io_ch(arg, "\"", 1))
+ return -1;
+ return outlen;
+}
+
+/* Used for line indenting: print 'indent' spaces */
+
+static int do_indent(char_io *io_ch, void *arg, int indent)
+{
+ int i;
+ for (i = 0; i < indent; i++)
+ if (!io_ch(arg, " ", 1))
+ return 0;
+ return 1;
+}
+
+#define FN_WIDTH_LN 25
+#define FN_WIDTH_SN 10
+
+static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
+ int indent, unsigned long flags)
+{
+ int i, prev = -1, orflags, cnt;
+ int fn_opt, fn_nid;
+ ASN1_OBJECT *fn;
+ ASN1_STRING *val;
+ X509_NAME_ENTRY *ent;
+ char objtmp[80];
+ const char *objbuf;
+ int outlen, len;
+ char *sep_dn, *sep_mv, *sep_eq;
+ int sep_dn_len, sep_mv_len, sep_eq_len;
+ if (indent < 0)
+ indent = 0;
+ outlen = indent;
+ if (!do_indent(io_ch, arg, indent))
+ return -1;
+ switch (flags & XN_FLAG_SEP_MASK) {
+ case XN_FLAG_SEP_MULTILINE:
+ sep_dn = "\n";
+ sep_dn_len = 1;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ break;
+
+ case XN_FLAG_SEP_COMMA_PLUS:
+ sep_dn = ",";
+ sep_dn_len = 1;
+ sep_mv = "+";
+ sep_mv_len = 1;
+ indent = 0;
+ break;
+
+ case XN_FLAG_SEP_CPLUS_SPC:
+ sep_dn = ", ";
+ sep_dn_len = 2;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ indent = 0;
+ break;
+
+ case XN_FLAG_SEP_SPLUS_SPC:
+ sep_dn = "; ";
+ sep_dn_len = 2;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ indent = 0;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (flags & XN_FLAG_SPC_EQ) {
+ sep_eq = " = ";
+ sep_eq_len = 3;
+ } else {
+ sep_eq = "=";
+ sep_eq_len = 1;
+ }
+
+ fn_opt = flags & XN_FLAG_FN_MASK;
+
+ cnt = X509_NAME_entry_count(n);
+ for (i = 0; i < cnt; i++) {
+ if (flags & XN_FLAG_DN_REV)
+ ent = X509_NAME_get_entry(n, cnt - i - 1);
+ else
+ ent = X509_NAME_get_entry(n, i);
+ if (prev != -1) {
+ if (prev == ent->set) {
+ if (!io_ch(arg, sep_mv, sep_mv_len))
+ return -1;
+ outlen += sep_mv_len;
+ } else {
+ if (!io_ch(arg, sep_dn, sep_dn_len))
+ return -1;
+ outlen += sep_dn_len;
+ if (!do_indent(io_ch, arg, indent))
+ return -1;
+ outlen += indent;
+ }
+ }
+ prev = ent->set;
+ fn = X509_NAME_ENTRY_get_object(ent);
+ val = X509_NAME_ENTRY_get_data(ent);
+ fn_nid = OBJ_obj2nid(fn);
+ if (fn_opt != XN_FLAG_FN_NONE) {
+ int objlen, fld_len;
+ if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
+ OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+ fld_len = 0; /* XXX: what should this be? */
+ objbuf = objtmp;
+ } else {
+ if (fn_opt == XN_FLAG_FN_SN) {
+ fld_len = FN_WIDTH_SN;
+ objbuf = OBJ_nid2sn(fn_nid);
+ } else if (fn_opt == XN_FLAG_FN_LN) {
+ fld_len = FN_WIDTH_LN;
+ objbuf = OBJ_nid2ln(fn_nid);
+ } else {
+ fld_len = 0; /* XXX: what should this be? */
+ objbuf = "";
+ }
+ }
+ objlen = strlen(objbuf);
+ if (!io_ch(arg, objbuf, objlen))
+ return -1;
+ if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+ if (!do_indent(io_ch, arg, fld_len - objlen))
+ return -1;
+ outlen += fld_len - objlen;
+ }
+ if (!io_ch(arg, sep_eq, sep_eq_len))
+ return -1;
+ outlen += objlen + sep_eq_len;
+ }
+ /*
+ * If the field name is unknown then fix up the DER dump flag. We
+ * might want to limit this further so it will DER dump on anything
+ * other than a few 'standard' fields.
+ */
+ if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+ orflags = ASN1_STRFLGS_DUMP_ALL;
+ else
+ orflags = 0;
+
+ len = do_print_ex(io_ch, arg, flags | orflags, val);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ }
+ return outlen;
+}
+
+/* Wrappers round the main functions */
+
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
+ unsigned long flags)
+{
+ if (flags == XN_FLAG_COMPAT)
+ return X509_NAME_print(out, nm, indent);
+ return do_name_ex(send_bio_chars, out, nm, indent, flags);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
+ unsigned long flags)
+{
+ if (flags == XN_FLAG_COMPAT) {
+ BIO *btmp;
+ int ret;
+ btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+ if (!btmp)
+ return -1;
+ ret = X509_NAME_print(btmp, nm, indent);
+ BIO_free(btmp);
+ return ret;
+ }
+ return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+}
+#endif
+
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
+{
+ return do_print_ex(send_bio_chars, out, flags, str);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
+{
+ return do_print_ex(send_fp_chars, fp, flags, str);
+}
+#endif
+
+/*
+ * Utility function: convert any string type to UTF8, returns number of bytes
+ * in output string or a negative error code
+ */
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
+{
+ ASN1_STRING stmp, *str = &stmp;
+ int mbflag, type, ret;
+ if (!in)
+ return -1;
+ type = in->type;
+ if ((type < 0) || (type > 30))
+ return -1;
+ mbflag = tag2nbyte[type];
+ if (mbflag == -1)
+ return -1;
+ mbflag |= MBSTRING_FLAG;
+ stmp.data = NULL;
+ stmp.length = 0;
+ stmp.flags = 0;
+ ret =
+ ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
+ B_ASN1_UTF8STRING);
+ if (ret < 0)
+ return ret;
+ *out = stmp.data;
+ return stmp.length;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c b/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c
new file mode 100644
index 00000000..52243453
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c
@@ -0,0 +1,313 @@
+/* a_strnid.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+
+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);
+
+/*
+ * This is the global mask for the mbstring functions: this is use to mask
+ * out certain types (such as BMPString and UTF8String) because certain
+ * software (e.g. Netscape) has problems with them.
+ */
+
+static unsigned long global_mask = B_ASN1_UTF8STRING;
+
+void ASN1_STRING_set_default_mask(unsigned long mask)
+{
+ global_mask = mask;
+}
+
+unsigned long ASN1_STRING_get_default_mask(void)
+{
+ return global_mask;
+}
+
+/*-
+ * This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is:
+ * MASK:XXXX : a numerical mask value.
+ * nobmp : Don't use BMPStrings (just Printable, T61).
+ * pkix : PKIX recommendation in RFC2459.
+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
+ * default: the default value, Printable, T61, BMP.
+ */
+
+int ASN1_STRING_set_default_mask_asc(const char *p)
+{
+ unsigned long mask;
+ char *end;
+ if (!strncmp(p, "MASK:", 5)) {
+ if (!p[5])
+ return 0;
+ mask = strtoul(p + 5, &end, 0);
+ if (*end)
+ return 0;
+ } else if (!strcmp(p, "nombstr"))
+ mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
+ else if (!strcmp(p, "pkix"))
+ mask = ~((unsigned long)B_ASN1_T61STRING);
+ else if (!strcmp(p, "utf8only"))
+ mask = B_ASN1_UTF8STRING;
+ else if (!strcmp(p, "default"))
+ mask = 0xFFFFFFFFL;
+ else
+ return 0;
+ ASN1_STRING_set_default_mask(mask);
+ return 1;
+}
+
+/*
+ * The following function generates an ASN1_STRING based on limits in a
+ * table. Frequently the types and length of an ASN1_STRING are restricted by
+ * a corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+ const unsigned char *in, int inlen,
+ int inform, int nid)
+{
+ ASN1_STRING_TABLE *tbl;
+ ASN1_STRING *str = NULL;
+ unsigned long mask;
+ int ret;
+ if (!out)
+ out = &str;
+ tbl = ASN1_STRING_TABLE_get(nid);
+ if (tbl) {
+ mask = tbl->mask;
+ if (!(tbl->flags & STABLE_NO_MASK))
+ mask &= global_mask;
+ ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+ tbl->minsize, tbl->maxsize);
+ } else
+ ret =
+ ASN1_mbstring_copy(out, in, inlen, inform,
+ DIRSTRING_TYPE & global_mask);
+ if (ret <= 0)
+ return NULL;
+ return *out;
+}
+
+/*
+ * Now the tables and helper functions for the string table:
+ */
+
+/* size limits: this stuff is taken straight from RFC3280 */
+
+#define ub_name 32768
+#define ub_common_name 64
+#define ub_locality_name 128
+#define ub_state_name 128
+#define ub_organization_name 64
+#define ub_organization_unit_name 64
+#define ub_title 64
+#define ub_email_address 128
+#define ub_serial_number 64
+
+/* This table must be kept in NID order */
+
+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},
+ {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
+ {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
+ {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
+ 0},
+ {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
+ STABLE_NO_MASK},
+ {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
+ {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
+ {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
+ {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
+ STABLE_NO_MASK},
+ {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+ {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+ {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+ {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+};
+
+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
+ const ASN1_STRING_TABLE *const *b)
+{
+ return (*a)->nid - (*b)->nid;
+}
+
+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)
+{
+ 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 = 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);
+ if (idx < 0)
+ return NULL;
+ return sk_ASN1_STRING_TABLE_value(stable, idx);
+}
+
+int ASN1_STRING_TABLE_add(int nid,
+ long minsize, long maxsize, unsigned long mask,
+ unsigned long flags)
+{
+ ASN1_STRING_TABLE *tmp;
+ char new_nid = 0;
+ flags &= ~STABLE_FLAGS_MALLOC;
+ if (!stable)
+ stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+ if (!stable) {
+ ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
+ tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
+ if (!tmp) {
+ ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ tmp->flags = flags | STABLE_FLAGS_MALLOC;
+ tmp->nid = nid;
+ new_nid = 1;
+ } else
+ tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
+ if (minsize != -1)
+ tmp->minsize = minsize;
+ if (maxsize != -1)
+ tmp->maxsize = maxsize;
+ tmp->mask = mask;
+ if (new_nid)
+ sk_ASN1_STRING_TABLE_push(stable, tmp);
+ return 1;
+}
+
+void ASN1_STRING_TABLE_cleanup(void)
+{
+ STACK_OF(ASN1_STRING_TABLE) *tmp;
+ tmp = stable;
+ if (!tmp)
+ return;
+ stable = NULL;
+ sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void st_free(ASN1_STRING_TABLE *tbl)
+{
+ if (tbl->flags & STABLE_FLAGS_MALLOC)
+ OPENSSL_free(tbl);
+}
+
+
+IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
+
+#ifdef STRING_TABLE_TEST
+
+main()
+{
+ ASN1_STRING_TABLE *tmp;
+ int i, last_nid = -1;
+
+ for (tmp = tbl_standard, i = 0;
+ i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
+ if (tmp->nid < last_nid) {
+ last_nid = 0;
+ break;
+ }
+ last_nid = tmp->nid;
+ }
+
+ if (last_nid != 0) {
+ printf("Table order OK\n");
+ exit(0);
+ }
+
+ for (tmp = tbl_standard, i = 0;
+ i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
+ printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
+ OBJ_nid2ln(tmp->nid));
+
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_time.c b/Cryptlib/OpenSSL/crypto/asn1/a_time.c
new file mode 100644
index 00000000..fcb2d565
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_time.c
@@ -0,0 +1,228 @@
+/* crypto/asn1/a_time.c */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+/*-
+ * This is an implementation of the ASN1 Time structure which is:
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ * written by Steve Henson.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "o_time.h"
+#include <openssl/asn1t.h>
+#include "asn1_locl.h"
+
+IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
+
+#if 0
+int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
+{
+# ifdef CHARSET_EBCDIC
+ /* KLUDGE! We convert to ascii before writing DER */
+ char tmp[24];
+ ASN1_STRING tmpstr;
+
+ if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
+ int len;
+
+ tmpstr = *(ASN1_STRING *)a;
+ len = tmpstr.length;
+ ebcdic2ascii(tmp, tmpstr.data,
+ (len >= sizeof tmp) ? sizeof tmp : len);
+ tmpstr.data = tmp;
+ a = (ASN1_GENERALIZEDTIME *)&tmpstr;
+ }
+# endif
+ if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
+ return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
+ a->type, V_ASN1_UNIVERSAL));
+ ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME);
+ return -1;
+}
+#endif
+
+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_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_adj(s, t, offset_day, offset_sec);
+ return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+}
+
+int ASN1_TIME_check(ASN1_TIME *t)
+{
+ if (t->type == V_ASN1_GENERALIZEDTIME)
+ return ASN1_GENERALIZEDTIME_check(t);
+ else if (t->type == V_ASN1_UTCTIME)
+ return ASN1_UTCTIME_check(t);
+ return 0;
+}
+
+/* Convert an ASN1_TIME structure to GeneralizedTime */
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
+ ASN1_GENERALIZEDTIME **out)
+{
+ ASN1_GENERALIZEDTIME *ret;
+ char *str;
+ int newlen;
+
+ if (!ASN1_TIME_check(t))
+ return NULL;
+
+ if (!out || !*out) {
+ if (!(ret = ASN1_GENERALIZEDTIME_new()))
+ return NULL;
+ if (out)
+ *out = ret;
+ } else
+ ret = *out;
+
+ /* If already GeneralizedTime just copy across */
+ if (t->type == V_ASN1_GENERALIZEDTIME) {
+ if (!ASN1_STRING_set(ret, t->data, t->length))
+ return NULL;
+ return ret;
+ }
+
+ /* grow the string */
+ if (!ASN1_STRING_set(ret, NULL, t->length + 2))
+ return NULL;
+ /* ASN1_STRING_set() allocated 'len + 1' bytes. */
+ newlen = t->length + 2 + 1;
+ str = (char *)ret->data;
+ /* Work out the century and prepend */
+ if (t->data[0] >= '5')
+ BUF_strlcpy(str, "19", newlen);
+ else
+ BUF_strlcpy(str, "20", newlen);
+
+ BUF_strlcat(str, (char *)t->data, newlen);
+
+ 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;
+}
+
+static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
+{
+ if (t == NULL) {
+ time_t now_t;
+ time(&now_t);
+ if (OPENSSL_gmtime(&now_t, tm))
+ return 1;
+ return 0;
+ }
+
+ if (t->type == V_ASN1_UTCTIME)
+ return asn1_utctime_to_tm(tm, t);
+ else if (t->type == V_ASN1_GENERALIZEDTIME)
+ return asn1_generalizedtime_to_tm(tm, t);
+
+ return 0;
+}
+
+int ASN1_TIME_diff(int *pday, int *psec,
+ const ASN1_TIME *from, const ASN1_TIME *to)
+{
+ struct tm tm_from, tm_to;
+ if (!asn1_time_to_tm(&tm_from, from))
+ return 0;
+ if (!asn1_time_to_tm(&tm_to, to))
+ return 0;
+ return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_type.c b/Cryptlib/OpenSSL/crypto/asn1/a_type.c
new file mode 100644
index 00000000..bb166e85
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_type.c
@@ -0,0 +1,155 @@
+/* crypto/asn1/a_type.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+int ASN1_TYPE_get(ASN1_TYPE *a)
+{
+ if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+ return (a->type);
+ else
+ return (0);
+}
+
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
+{
+ if (a->value.ptr != NULL) {
+ ASN1_TYPE **tmp_a = &a;
+ ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
+ }
+ a->type = type;
+ 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)
+{
+ if (!value || (type == V_ASN1_BOOLEAN)) {
+ void *p = (void *)value;
+ ASN1_TYPE_set(a, type, p);
+ } else if (type == V_ASN1_OBJECT) {
+ ASN1_OBJECT *odup;
+ odup = OBJ_dup(value);
+ if (!odup)
+ return 0;
+ ASN1_TYPE_set(a, type, odup);
+ } else {
+ ASN1_STRING *sdup;
+ sdup = ASN1_STRING_dup(value);
+ if (!sdup)
+ return 0;
+ ASN1_TYPE_set(a, type, sdup);
+ }
+ return 1;
+}
+
+IMPLEMENT_STACK_OF(ASN1_TYPE)
+
+IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const 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_BOOLEAN:
+ result = a->value.boolean - b->value.boolean;
+ break;
+ case V_ASN1_NULL:
+ result = 0; /* They do not have content. */
+ break;
+ case V_ASN1_INTEGER:
+ case V_ASN1_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/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c b/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c
new file mode 100644
index 00000000..724a10be
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c
@@ -0,0 +1,352 @@
+/* crypto/asn1/a_utctm.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 <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "o_time.h"
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+#if 0
+int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
+{
+# ifndef CHARSET_EBCDIC
+ return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
+ V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
+# else
+ /* KLUDGE! We convert to ascii before writing DER */
+ int len;
+ char tmp[24];
+ ASN1_STRING x = *(ASN1_STRING *)a;
+
+ len = x.length;
+ ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
+ x.data = tmp;
+ return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
+# endif
+}
+
+ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
+ long length)
+{
+ ASN1_UTCTIME *ret = NULL;
+
+ ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
+ V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
+ if (ret == NULL) {
+ ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ERR_R_NESTED_ASN1_ERROR);
+ return (NULL);
+ }
+# ifdef CHARSET_EBCDIC
+ ascii2ebcdic(ret->data, ret->data, ret->length);
+# endif
+ if (!ASN1_UTCTIME_check(ret)) {
+ ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ASN1_R_INVALID_TIME_FORMAT);
+ goto err;
+ }
+
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_UTCTIME_free(ret);
+ return (NULL);
+}
+
+#endif
+
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
+{
+ 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;
+
+ if (d->type != V_ASN1_UTCTIME)
+ return (0);
+ l = d->length;
+ a = (char *)d->data;
+ o = 0;
+
+ if (l < 11)
+ goto err;
+ for (i = 0; i < 6; i++) {
+ if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+ i++;
+ if (tm)
+ tm->tm_sec = 0;
+ break;
+ }
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n < 50 ? n + 100 : n;
+ break;
+ case 1:
+ tm->tm_mon = n - 1;
+ break;
+ case 2:
+ tm->tm_mday = n;
+ break;
+ case 3:
+ tm->tm_hour = n;
+ break;
+ case 4:
+ tm->tm_min = n;
+ break;
+ case 5:
+ tm->tm_sec = n;
+ break;
+ }
+ }
+ }
+ if (a[o] == 'Z')
+ o++;
+ else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ o++;
+ if (o + 4 > l)
+ goto err;
+ for (i = 6; i < 8; i++) {
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ o++;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ if (i == 6)
+ offset = n * 3600;
+ else if (i == 7)
+ offset += n * 60;
+ }
+ o++;
+ }
+ if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+ return 0;
+ }
+ return o == l;
+ err:
+ return 0;
+}
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
+{
+ return asn1_utctime_to_tm(NULL, d);
+}
+
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
+{
+ ASN1_UTCTIME t;
+
+ t.type = V_ASN1_UTCTIME;
+ t.length = strlen(str);
+ t.data = (unsigned char *)str;
+ if (ASN1_UTCTIME_check(&t)) {
+ if (s != NULL) {
+ if (!ASN1_STRING_set((ASN1_STRING *)s,
+ (unsigned char *)str, t.length))
+ return 0;
+ s->type = V_ASN1_UTCTIME;
+ }
+ return (1);
+ } else
+ return (0);
+}
+
+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;
+ size_t len = 20;
+ int free_s = 0;
+
+ if (s == NULL) {
+ free_s = 1;
+ s = M_ASN1_UTCTIME_new();
+ }
+ if (s == NULL)
+ goto err;
+
+ ts = OPENSSL_gmtime(&t, &data);
+ if (ts == NULL)
+ goto err;
+
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ goto err;
+ }
+
+ if ((ts->tm_year < 50) || (ts->tm_year >= 150))
+ goto err;
+
+ p = (char *)s->data;
+ if ((p == NULL) || ((size_t)s->length < len)) {
+ p = OPENSSL_malloc(len);
+ if (p == NULL) {
+ ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (s->data != NULL)
+ OPENSSL_free(s->data);
+ s->data = (unsigned char *)p;
+ }
+
+ BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
+ ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+ ts->tm_sec);
+ s->length = strlen(p);
+ s->type = V_ASN1_UTCTIME;
+#ifdef CHARSET_EBCDIC_not
+ ebcdic2ascii(s->data, s->data, s->length);
+#endif
+ return (s);
+ err:
+ if (free_s && s)
+ M_ASN1_UTCTIME_free(s);
+ return NULL;
+}
+
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
+{
+ struct tm stm, ttm;
+ int day, sec;
+
+ if (!asn1_utctime_to_tm(&stm, s))
+ return -2;
+
+ if (!OPENSSL_gmtime(&t, &ttm))
+ return -2;
+
+ if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+ return -2;
+
+ if (day > 0)
+ return 1;
+ if (day < 0)
+ return -1;
+ if (sec > 0)
+ return 1;
+ if (sec < 0)
+ return -1;
+ return 0;
+}
+
+#if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
+{
+ struct tm tm;
+ int offset;
+
+ memset(&tm, '\0', sizeof tm);
+
+# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
+ tm.tm_year = g2(s->data);
+ if (tm.tm_year < 50)
+ tm.tm_year += 100;
+ tm.tm_mon = g2(s->data + 2) - 1;
+ tm.tm_mday = g2(s->data + 4);
+ tm.tm_hour = g2(s->data + 6);
+ tm.tm_min = g2(s->data + 8);
+ tm.tm_sec = g2(s->data + 10);
+ if (s->data[12] == 'Z')
+ offset = 0;
+ else {
+ offset = g2(s->data + 13) * 60 + g2(s->data + 15);
+ if (s->data[12] == '-')
+ offset = -offset;
+ }
+# undef g2
+
+ /*
+ * FIXME: mktime assumes the current timezone
+ * instead of UTC, and unless we rewrite OpenSSL
+ * in Lisp we cannot locally change the timezone
+ * without possibly interfering with other parts
+ * of the program. timegm, which uses UTC, is
+ * non-standard.
+ * Also time_t is inappropriate for general
+ * UTC times because it may a 32 bit type.
+ */
+ return mktime(&tm) - offset * 60;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_utf8.c b/Cryptlib/OpenSSL/crypto/asn1/a_utf8.c
new file mode 100644
index 00000000..23dc2e82
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_utf8.c
@@ -0,0 +1,237 @@
+/* crypto/asn1/a_utf8.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+/* UTF8 utilities */
+
+/*-
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value of
+ * the current character. It returns the number of characters read or a
+ * negative error code:
+ * -1 = string too short
+ * -2 = illegal character
+ * -3 = subsequent characters not of the form 10xxxxxx
+ * -4 = character encoded incorrectly (not minimal length).
+ */
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
+{
+ const unsigned char *p;
+ unsigned long value;
+ int ret;
+ if (len <= 0)
+ return 0;
+ p = str;
+
+ /* Check syntax and work out the encoded value (if correct) */
+ if ((*p & 0x80) == 0) {
+ value = *p++ & 0x7f;
+ ret = 1;
+ } else if ((*p & 0xe0) == 0xc0) {
+ if (len < 2)
+ return -1;
+ if ((p[1] & 0xc0) != 0x80)
+ return -3;
+ value = (*p++ & 0x1f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x80)
+ return -4;
+ ret = 2;
+ } else if ((*p & 0xf0) == 0xe0) {
+ if (len < 3)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80))
+ return -3;
+ value = (*p++ & 0xf) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x800)
+ return -4;
+ ret = 3;
+ } else if ((*p & 0xf8) == 0xf0) {
+ if (len < 4)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80)
+ || ((p[3] & 0xc0) != 0x80))
+ return -3;
+ value = ((unsigned long)(*p++ & 0x7)) << 18;
+ value |= (*p++ & 0x3f) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x10000)
+ return -4;
+ ret = 4;
+ } else if ((*p & 0xfc) == 0xf8) {
+ if (len < 5)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80)
+ || ((p[3] & 0xc0) != 0x80)
+ || ((p[4] & 0xc0) != 0x80))
+ return -3;
+ value = ((unsigned long)(*p++ & 0x3)) << 24;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x200000)
+ return -4;
+ ret = 5;
+ } else if ((*p & 0xfe) == 0xfc) {
+ if (len < 6)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80)
+ || ((p[3] & 0xc0) != 0x80)
+ || ((p[4] & 0xc0) != 0x80)
+ || ((p[5] & 0xc0) != 0x80))
+ return -3;
+ value = ((unsigned long)(*p++ & 0x1)) << 30;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x4000000)
+ return -4;
+ ret = 6;
+ } else
+ return -2;
+ *val = value;
+ return ret;
+}
+
+/*
+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
+ * where 'str' is a buffer containing 'len' characters. Returns the number of
+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
+ * in which case it just returns the number of characters. It will need at
+ * most 6 characters.
+ */
+
+int UTF8_putc(unsigned char *str, int len, unsigned long value)
+{
+ if (!str)
+ len = 6; /* Maximum we will need */
+ else if (len <= 0)
+ return -1;
+ if (value < 0x80) {
+ if (str)
+ *str = (unsigned char)value;
+ return 1;
+ }
+ if (value < 0x800) {
+ if (len < 2)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 2;
+ }
+ if (value < 0x10000) {
+ if (len < 3)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 3;
+ }
+ if (value < 0x200000) {
+ if (len < 4)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+ *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 4;
+ }
+ if (value < 0x4000000) {
+ if (len < 5)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+ *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 5;
+ }
+ if (len < 6)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+ *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 6;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_verify.c b/Cryptlib/OpenSSL/crypto/asn1/a_verify.c
new file mode 100644
index 00000000..3ffd934c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_verify.c
@@ -0,0 +1,231 @@
+/* crypto/asn1/a_verify.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 <stdio.h>
+#include <time.h>
+
+#include "cryptlib.h"
+#include "asn1_locl.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
+ char *data, EVP_PKEY *pkey)
+{
+ EVP_MD_CTX ctx;
+ const EVP_MD *type;
+ unsigned char *p, *buf_in = NULL;
+ int ret = -1, i, inl;
+
+ EVP_MD_CTX_init(&ctx);
+ i = OBJ_obj2nid(a->algorithm);
+ type = EVP_get_digestbyname(OBJ_nid2sn(i));
+ if (type == NULL) {
+ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
+
+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ goto err;
+ }
+
+ inl = i2d(data, NULL);
+ buf_in = OPENSSL_malloc((unsigned int)inl);
+ if (buf_in == NULL) {
+ ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = buf_in;
+
+ i2d(data, &p);
+ if (!EVP_VerifyInit_ex(&ctx, type, NULL)
+ || !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) {
+ ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+
+ OPENSSL_cleanse(buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+
+ if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data,
+ (unsigned int)signature->length, pkey) <= 0) {
+ ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+ /*
+ * we don't need to zero the 'ctx' because we just checked public
+ * information
+ */
+ /* memset(&ctx,0,sizeof(ctx)); */
+ ret = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return (ret);
+}
+
+#endif
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
+ ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+{
+ EVP_MD_CTX ctx;
+ unsigned char *buf_in = NULL;
+ int ret = -1, inl;
+
+ int mdnid, pknid;
+
+ if (!pkey) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+
+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ return -1;
+ }
+
+ EVP_MD_CTX_init(&ctx);
+
+ /* 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;
+ }
+ if (mdnid == NID_undef) {
+ if (!pkey->ameth || !pkey->ameth->item_verify) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+ ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ goto err;
+ }
+ ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey);
+ /*
+ * Return value of 2 means carry on, anything else means we exit
+ * straight away: either a fatal error of the underlying verification
+ * routine handles all verification.
+ */
+ if (ret != 2)
+ goto err;
+ ret = -1;
+ } else {
+ const EVP_MD *type;
+ 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_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+
+ }
+
+ inl = ASN1_item_i2d(asn, &buf_in, it);
+
+ if (buf_in == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+
+ OPENSSL_cleanse(buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+
+ if (EVP_DigestVerifyFinal(&ctx, signature->data,
+ (size_t)signature->length) <= 0) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+ /*
+ * we don't need to zero the 'ctx' because we just checked public
+ * information
+ */
+ /* memset(&ctx,0,sizeof(ctx)); */
+ ret = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c b/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c
new file mode 100644
index 00000000..5389c043
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c
@@ -0,0 +1,484 @@
+/*
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#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 dhx_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD cmac_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,
+ &cmac_asn1_meth,
+#ifndef OPENSSL_NO_DH
+ &dhx_asn1_meth
+#endif
+};
+
+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;
+
+ 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
+ ENGINE *e;
+ /* 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;
+ if (!EVP_PKEY_asn1_add0(ameth)) {
+ EVP_PKEY_asn1_free(ameth);
+ return 0;
+ }
+ return 1;
+}
+
+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;
+
+ memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
+
+ 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->item_verify = 0;
+ ameth->item_sign = 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;
+
+ dst->item_sign = src->item_sign;
+ dst->item_verify = src->item_verify;
+
+}
+
+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;
+}
+
+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*item_verify) (EVP_MD_CTX *ctx,
+ const ASN1_ITEM *it,
+ void *asn,
+ X509_ALGOR *a,
+ ASN1_BIT_STRING *sig,
+ EVP_PKEY *pkey),
+ int (*item_sign) (EVP_MD_CTX *ctx,
+ const ASN1_ITEM *it,
+ void *asn,
+ X509_ALGOR *alg1,
+ X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig))
+{
+ ameth->item_sign = item_sign;
+ ameth->item_verify = item_verify;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c
new file mode 100644
index 00000000..fd4ac8d9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c
@@ -0,0 +1,354 @@
+/* crypto/asn1/asn1_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2014 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
+
+static ERR_STRING_DATA ASN1_str_functs[] = {
+ {ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
+ {ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"},
+ {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
+ {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
+ {ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"},
+ {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
+ {ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"},
+ {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"},
+ {ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"},
+ {ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"},
+ {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"},
+ {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
+ {ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"},
+ {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
+ {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"},
+ {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
+ {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"},
+ {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_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"},
+ {ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
+ {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
+ {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_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"},
+ {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
+ {ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"},
+ {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
+ {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
+ {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
+ {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"},
+ {ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
+ {ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
+ {ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
+ {ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"},
+ {ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"},
+ {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_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"},
+ {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
+ {ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"},
+ {ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"},
+ {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"},
+ {ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
+ {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
+ {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
+ {ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"},
+ {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
+ {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_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_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
+ {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"},
+ {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
+ {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
+ {ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"},
+ {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"},
+ {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"},
+ {ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"},
+ {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA ASN1_str_reasons[] = {
+ {ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"},
+ {ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"},
+ {ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"},
+ {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"},
+ {ERR_REASON(ASN1_R_BAD_CLASS), "bad class"},
+ {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
+ {ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"},
+ {ERR_REASON(ASN1_R_BAD_TAG), "bad tag"},
+ {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
+ "bmpstring is wrong length"},
+ {ERR_REASON(ASN1_R_BN_LIB), "bn lib"},
+ {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
+ {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"},
+ {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
+ "cipher has no object identifier"},
+ {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
+ {ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"},
+ {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"},
+ {ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT),
+ "error parsing set element"},
+ {ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),
+ "error setting cipher params"},
+ {ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"},
+ {ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"},
+ {ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN), "expecting a boolean"},
+ {ERR_REASON(ASN1_R_EXPECTING_A_TIME), "expecting a time"},
+ {ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"},
+ {ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),
+ "explicit tag not constructed"},
+ {ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"},
+ {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"},
+ {ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"},
+ {ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"},
+ {ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"},
+ {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"},
+ {ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"},
+ {ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"},
+ {ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"},
+ {ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"},
+ {ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"},
+ {ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"},
+ {ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"},
+ {ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"},
+ {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"},
+ {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),
+ "illegal options on item template"},
+ {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"},
+ {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"},
+ {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"},
+ {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),
+ "integer too large for long"},
+ {ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),
+ "invalid bit string bits left"},
+ {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"},
+ {ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"},
+ {ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"},
+ {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"},
+ {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"},
+ {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"},
+ {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"},
+ {ERR_REASON(ASN1_R_INVALID_TIME_FORMAT), "invalid time format"},
+ {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),
+ "invalid universalstring length"},
+ {ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"},
+ {ERR_REASON(ASN1_R_IV_TOO_LARGE), "iv too large"},
+ {ERR_REASON(ASN1_R_LENGTH_ERROR), "length error"},
+ {ERR_REASON(ASN1_R_LIST_ERROR), "list error"},
+ {ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
+ {ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"},
+ {ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
+ {ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"},
+ {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"},
+ {ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"},
+ {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
+ {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
+ {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"},
+ {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"},
+ {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"},
+ {ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"},
+ {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"},
+ {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"},
+ {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"},
+ {ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),
+ "private key header missing"},
+ {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"},
+ {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"},
+ {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"},
+ {ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),
+ "sequence or set needs config"},
+ {ERR_REASON(ASN1_R_SHORT_LINE), "short line"},
+ {ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
+ {ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"},
+ {ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"},
+ {ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"},
+ {ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH), "tag value too high"},
+ {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
+ "the asn1 object identifier is not known for this md"},
+ {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"},
+ {ERR_REASON(ASN1_R_TOO_LONG), "too long"},
+ {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"},
+ {ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"},
+ {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"},
+ {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),
+ "unable to decode rsa private key"},
+ {ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"},
+ {ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),
+ "universalstring is wrong length"},
+ {ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"},
+ {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), "unknown format"},
+ {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),
+ "unsupported any defined by type"},
+ {ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
+ {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}
+};
+
+#endif
+
+void ERR_load_ASN1_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, ASN1_str_functs);
+ ERR_load_strings(0, ASN1_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c
new file mode 100644
index 00000000..65749239
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c
@@ -0,0 +1,831 @@
+/* asn1_gen.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ * 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"
+#include <openssl/asn1.h>
+#include <openssl/x509v3.h>
+
+#define ASN1_GEN_FLAG 0x10000
+#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
+
+#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
+
+#define ASN1_FLAG_EXP_MAX 20
+/* Maximum number of nested sequences */
+#define ASN1_GEN_SEQ_MAX_DEPTH 50
+
+/* Input formats */
+
+/* ASCII: default */
+#define ASN1_GEN_FORMAT_ASCII 1
+/* UTF8 */
+#define ASN1_GEN_FORMAT_UTF8 2
+/* Hex */
+#define ASN1_GEN_FORMAT_HEX 3
+/* List of bits */
+#define ASN1_GEN_FORMAT_BITLIST 4
+
+struct tag_name_st {
+ const char *strnam;
+ int len;
+ int tag;
+};
+
+typedef struct {
+ int exp_tag;
+ int exp_class;
+ int exp_constructed;
+ int exp_pad;
+ long exp_len;
+} tag_exp_type;
+
+typedef struct {
+ int imp_tag;
+ int imp_class;
+ int utype;
+ int format;
+ const char *str;
+ tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+ int exp_count;
+} tag_exp_arg;
+
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+ int *perr);
+static int bitstr_cb(const char *elem, int len, void *bitstr);
+static int asn1_cb(const char *elem, int len, void *bitstr);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+ int exp_constructed, int exp_pad, int imp_ok);
+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,
+ int depth, int *perr);
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
+static int asn1_str2tag(const char *tagstr, int len);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
+{
+ X509V3_CTX cnf;
+
+ if (!nconf)
+ return ASN1_generate_v3(str, NULL);
+
+ X509V3_set_nconf(&cnf, nconf);
+ return ASN1_generate_v3(str, &cnf);
+}
+
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
+{
+ int err = 0;
+ ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
+ if (err)
+ ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
+ return ret;
+}
+
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+ int *perr)
+{
+ ASN1_TYPE *ret;
+ tag_exp_arg asn1_tags;
+ tag_exp_type *etmp;
+
+ int i, len;
+
+ unsigned char *orig_der = NULL, *new_der = NULL;
+ const unsigned char *cpy_start;
+ unsigned char *p;
+ const unsigned char *cp;
+ int cpy_len;
+ long hdr_len;
+ int hdr_constructed = 0, hdr_tag, hdr_class;
+ int r;
+
+ asn1_tags.imp_tag = -1;
+ asn1_tags.imp_class = -1;
+ asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+ asn1_tags.exp_count = 0;
+ if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
+ *perr = ASN1_R_UNKNOWN_TAG;
+ return NULL;
+ }
+
+ if ((asn1_tags.utype == V_ASN1_SEQUENCE)
+ || (asn1_tags.utype == V_ASN1_SET)) {
+ if (!cnf) {
+ *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
+ return NULL;
+ }
+ if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
+ *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
+ return NULL;
+ }
+ ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
+ } else
+ ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
+
+ if (!ret)
+ return NULL;
+
+ /* If no tagging return base type */
+ if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+ return ret;
+
+ /* Generate the encoding */
+ cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+ ASN1_TYPE_free(ret);
+ ret = NULL;
+ /* Set point to start copying for modified encoding */
+ cpy_start = orig_der;
+
+ /* Do we need IMPLICIT tagging? */
+ if (asn1_tags.imp_tag != -1) {
+ /* If IMPLICIT we will replace the underlying tag */
+ /* Skip existing tag+len */
+ r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
+ cpy_len);
+ if (r & 0x80)
+ goto err;
+ /* Update copy length */
+ cpy_len -= cpy_start - orig_der;
+ /*
+ * For IMPLICIT tagging the length should match the original length
+ * and constructed flag should be consistent.
+ */
+ if (r & 0x1) {
+ /* Indefinite length constructed */
+ hdr_constructed = 2;
+ hdr_len = 0;
+ } else
+ /* Just retain constructed flag */
+ hdr_constructed = r & V_ASN1_CONSTRUCTED;
+ /*
+ * Work out new length with IMPLICIT tag: ignore constructed because
+ * it will mess up if indefinite length
+ */
+ len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+ } else
+ len = cpy_len;
+
+ /* Work out length in any EXPLICIT, starting from end */
+
+ for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
+ i < asn1_tags.exp_count; i++, etmp--) {
+ /* Content length: number of content octets + any padding */
+ len += etmp->exp_pad;
+ etmp->exp_len = len;
+ /* Total object length: length including new header */
+ len = ASN1_object_size(0, len, etmp->exp_tag);
+ }
+
+ /* Allocate buffer for new encoding */
+
+ new_der = OPENSSL_malloc(len);
+ if (!new_der)
+ goto err;
+
+ /* Generate tagged encoding */
+
+ p = new_der;
+
+ /* Output explicit tags first */
+
+ for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
+ i++, etmp++) {
+ ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+ etmp->exp_tag, etmp->exp_class);
+ if (etmp->exp_pad)
+ *p++ = 0;
+ }
+
+ /* 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);
+
+ cp = new_der;
+
+ /* Obtain new ASN1_TYPE structure */
+ ret = d2i_ASN1_TYPE(NULL, &cp, len);
+
+ err:
+ if (orig_der)
+ OPENSSL_free(orig_der);
+ if (new_der)
+ OPENSSL_free(new_der);
+
+ return ret;
+
+}
+
+static int asn1_cb(const char *elem, int len, void *bitstr)
+{
+ tag_exp_arg *arg = bitstr;
+ int i;
+ int utype;
+ int vlen = 0;
+ const char *p, *vstart = NULL;
+
+ int tmp_tag, tmp_class;
+
+ if (elem == NULL)
+ return -1;
+
+ for (i = 0, p = elem; i < len; p++, i++) {
+ /* Look for the ':' in name value pairs */
+ if (*p == ':') {
+ vstart = p + 1;
+ vlen = len - (vstart - elem);
+ len = p - elem;
+ break;
+ }
+ }
+
+ utype = asn1_str2tag(elem, len);
+
+ if (utype == -1) {
+ ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
+ ERR_add_error_data(2, "tag=", elem);
+ return -1;
+ }
+
+ /* If this is not a modifier mark end of string and exit */
+ if (!(utype & ASN1_GEN_FLAG)) {
+ arg->utype = utype;
+ arg->str = vstart;
+ /* If no value and not end of string, error */
+ if (!vstart && elem[len]) {
+ ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
+ return -1;
+ }
+ return 0;
+ }
+
+ switch (utype) {
+
+ case ASN1_GEN_FLAG_IMP:
+ /* Check for illegal multiple IMPLICIT tagging */
+ if (arg->imp_tag != -1) {
+ ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
+ return -1;
+ }
+ if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_EXP:
+
+ if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+ return -1;
+ if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_SEQWRAP:
+ if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_SETWRAP:
+ if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_BITWRAP:
+ if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_OCTWRAP:
+ if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_FORMAT:
+ if (!vstart) {
+ ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
+ return -1;
+ }
+ if (!strncmp(vstart, "ASCII", 5))
+ arg->format = ASN1_GEN_FORMAT_ASCII;
+ else if (!strncmp(vstart, "UTF8", 4))
+ arg->format = ASN1_GEN_FORMAT_UTF8;
+ else if (!strncmp(vstart, "HEX", 3))
+ arg->format = ASN1_GEN_FORMAT_HEX;
+ else if (!strncmp(vstart, "BITLIST", 7))
+ arg->format = ASN1_GEN_FORMAT_BITLIST;
+ else {
+ ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
+ return -1;
+ }
+ break;
+
+ }
+
+ return 1;
+
+}
+
+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
+{
+ char erch[2];
+ long tag_num;
+ char *eptr;
+ if (!vstart)
+ return 0;
+ tag_num = strtoul(vstart, &eptr, 10);
+ /* Check we haven't gone past max length: should be impossible */
+ if (eptr && *eptr && (eptr > vstart + vlen))
+ return 0;
+ if (tag_num < 0) {
+ ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
+ return 0;
+ }
+ *ptag = tag_num;
+ /* If we have non numeric characters, parse them */
+ if (eptr)
+ vlen -= eptr - vstart;
+ else
+ vlen = 0;
+ if (vlen) {
+ switch (*eptr) {
+
+ case 'U':
+ *pclass = V_ASN1_UNIVERSAL;
+ break;
+
+ case 'A':
+ *pclass = V_ASN1_APPLICATION;
+ break;
+
+ case 'P':
+ *pclass = V_ASN1_PRIVATE;
+ break;
+
+ case 'C':
+ *pclass = V_ASN1_CONTEXT_SPECIFIC;
+ break;
+
+ default:
+ erch[0] = *eptr;
+ erch[1] = 0;
+ ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
+ ERR_add_error_data(2, "Char=", erch);
+ return 0;
+ break;
+
+ }
+ } else
+ *pclass = V_ASN1_CONTEXT_SPECIFIC;
+
+ return 1;
+
+}
+
+/* Handle multiple types: SET and SEQUENCE */
+
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+ int depth, int *perr)
+{
+ ASN1_TYPE *ret = NULL;
+ STACK_OF(ASN1_TYPE) *sk = NULL;
+ STACK_OF(CONF_VALUE) *sect = NULL;
+ unsigned char *der = NULL;
+ int derlen;
+ int i;
+ sk = sk_ASN1_TYPE_new_null();
+ if (!sk)
+ goto bad;
+ if (section) {
+ if (!cnf)
+ goto bad;
+ sect = X509V3_get_section(cnf, (char *)section);
+ if (!sect)
+ goto bad;
+ for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
+ ASN1_TYPE *typ =
+ generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
+ depth + 1, perr);
+ if (!typ)
+ goto bad;
+ if (!sk_ASN1_TYPE_push(sk, typ))
+ goto bad;
+ }
+ }
+
+ /*
+ * Now we has a STACK of the components, convert to the correct form
+ */
+
+ if (utype == V_ASN1_SET)
+ derlen = i2d_ASN1_SET_ANY(sk, &der);
+ else
+ derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+
+ if (derlen < 0)
+ goto bad;
+
+ if (!(ret = ASN1_TYPE_new()))
+ goto bad;
+
+ if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
+ goto bad;
+
+ ret->type = utype;
+
+ ret->value.asn1_string->data = der;
+ ret->value.asn1_string->length = derlen;
+
+ der = NULL;
+
+ bad:
+
+ if (der)
+ OPENSSL_free(der);
+
+ if (sk)
+ sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+ if (sect)
+ X509V3_section_free(cnf, sect);
+
+ return ret;
+}
+
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+ int exp_constructed, int exp_pad, int imp_ok)
+{
+ tag_exp_type *exp_tmp;
+ /* Can only have IMPLICIT if permitted */
+ if ((arg->imp_tag != -1) && !imp_ok) {
+ ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+ return 0;
+ }
+
+ if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
+ ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
+ return 0;
+ }
+
+ exp_tmp = &arg->exp_list[arg->exp_count++];
+
+ /*
+ * If IMPLICIT set tag to implicit value then reset implicit tag since it
+ * has been used.
+ */
+ if (arg->imp_tag != -1) {
+ exp_tmp->exp_tag = arg->imp_tag;
+ exp_tmp->exp_class = arg->imp_class;
+ arg->imp_tag = -1;
+ arg->imp_class = -1;
+ } else {
+ exp_tmp->exp_tag = exp_tag;
+ exp_tmp->exp_class = exp_class;
+ }
+ exp_tmp->exp_constructed = exp_constructed;
+ exp_tmp->exp_pad = exp_pad;
+
+ return 1;
+}
+
+static int asn1_str2tag(const char *tagstr, int len)
+{
+ unsigned int i;
+ 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),
+ ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+ ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+ ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+ ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+ ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+ ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+ ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+ ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+ ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+ ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+ ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+ ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+ ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+ ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+ ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+ ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+ ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+ ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+ ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+ ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+ ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+ ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+ ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+ ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+ ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+ ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+ ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+ ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+ 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),
+ ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+ ASN1_GEN_STR("SET", V_ASN1_SET),
+ /* type modifiers */
+ /* Explicit tag */
+ ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+ ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+ /* Implicit tag */
+ ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+ ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+ /* OCTET STRING wrapper */
+ ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+ /* SEQUENCE wrapper */
+ ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+ /* SET wrapper */
+ ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+ /* BIT STRING wrapper */
+ ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+ ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+ ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+ };
+
+ if (len == -1)
+ len = strlen(tagstr);
+
+ tntmp = tnst;
+ for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) {
+ if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
+ return tntmp->tag;
+ }
+
+ return -1;
+}
+
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
+{
+ ASN1_TYPE *atmp = NULL;
+
+ CONF_VALUE vtmp;
+
+ unsigned char *rdata;
+ long rdlen;
+
+ int no_unused = 1;
+
+ if (!(atmp = ASN1_TYPE_new())) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (!str)
+ str = "";
+
+ switch (utype) {
+
+ case V_ASN1_NULL:
+ if (str && *str) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
+ goto bad_form;
+ }
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
+ goto bad_form;
+ }
+ vtmp.name = NULL;
+ vtmp.section = NULL;
+ vtmp.value = (char *)str;
+ if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
+ goto bad_str;
+ }
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_ENUMERATED:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+ goto bad_form;
+ }
+ if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
+ goto bad_str;
+ }
+ break;
+
+ case V_ASN1_OBJECT:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+ goto bad_form;
+ }
+ if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
+ goto bad_str;
+ }
+ break;
+
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
+ goto bad_form;
+ }
+ if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+ goto bad_str;
+ }
+ if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+ goto bad_str;
+ }
+ atmp->value.asn1_string->type = utype;
+ if (!ASN1_TIME_check(atmp->value.asn1_string)) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
+ goto bad_str;
+ }
+
+ break;
+
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_UTF8STRING:
+ 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;
+ else if (format == ASN1_GEN_FORMAT_UTF8)
+ format = MBSTRING_UTF8;
+ else {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
+ goto bad_form;
+ }
+
+ if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
+ -1, format, ASN1_tag2bit(utype)) <= 0) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+ goto bad_str;
+ }
+
+ break;
+
+ case V_ASN1_BIT_STRING:
+
+ case V_ASN1_OCTET_STRING:
+
+ if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+ goto bad_form;
+ }
+
+ if (format == ASN1_GEN_FORMAT_HEX) {
+
+ if (!(rdata = string_to_hex((char *)str, &rdlen))) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
+ goto bad_str;
+ }
+
+ atmp->value.asn1_string->data = rdata;
+ atmp->value.asn1_string->length = rdlen;
+ atmp->value.asn1_string->type = utype;
+
+ } else if (format == ASN1_GEN_FORMAT_ASCII)
+ ASN1_STRING_set(atmp->value.asn1_string, str, -1);
+ else if ((format == ASN1_GEN_FORMAT_BITLIST)
+ && (utype == V_ASN1_BIT_STRING)) {
+ if (!CONF_parse_list
+ (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
+ goto bad_str;
+ }
+ no_unused = 0;
+
+ } else {
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+ goto bad_form;
+ }
+
+ if ((utype == V_ASN1_BIT_STRING) && no_unused) {
+ atmp->value.asn1_string->flags
+ &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ }
+
+ break;
+
+ default:
+ ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
+ goto bad_str;
+ break;
+ }
+
+ atmp->type = utype;
+ return atmp;
+
+ bad_str:
+ ERR_add_error_data(2, "string=", str);
+ bad_form:
+
+ ASN1_TYPE_free(atmp);
+ return NULL;
+
+}
+
+static int bitstr_cb(const char *elem, int len, void *bitstr)
+{
+ long bitnum;
+ char *eptr;
+ if (!elem)
+ return 0;
+ bitnum = strtoul(elem, &eptr, 10);
+ if (eptr && *eptr && (eptr != elem + len))
+ return 0;
+ if (bitnum < 0) {
+ ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
+ return 0;
+ }
+ if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
+ ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
new file mode 100644
index 00000000..874b1af8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
@@ -0,0 +1,479 @@
+/* crypto/asn1/asn1_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 <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+ long max);
+static void asn1_put_length(unsigned char **pp, int length);
+const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT;
+
+static int _asn1_check_infinite_end(const unsigned char **p, long len)
+{
+ /*
+ * If there is 0 or 1 byte left, the length check should pick things up
+ */
+ if (len <= 0)
+ return (1);
+ else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
+ (*p) += 2;
+ return (1);
+ }
+ return (0);
+}
+
+int ASN1_check_infinite_end(unsigned char **p, long len)
+{
+ return _asn1_check_infinite_end((const unsigned char **)p, len);
+}
+
+int ASN1_const_check_infinite_end(const unsigned char **p, long len)
+{
+ return _asn1_check_infinite_end(p, len);
+}
+
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+ int *pclass, long omax)
+{
+ int i, ret;
+ long l;
+ const unsigned char *p = *pp;
+ int tag, xclass, inf;
+ long max = omax;
+
+ if (!max)
+ goto err;
+ ret = (*p & V_ASN1_CONSTRUCTED);
+ xclass = (*p & V_ASN1_PRIVATE);
+ i = *p & V_ASN1_PRIMITIVE_TAG;
+ if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
+ p++;
+ if (--max == 0)
+ goto err;
+ l = 0;
+ while (*p & 0x80) {
+ l <<= 7L;
+ l |= *(p++) & 0x7f;
+ if (--max == 0)
+ goto err;
+ if (l > (INT_MAX >> 7L))
+ goto err;
+ }
+ l <<= 7L;
+ l |= *(p++) & 0x7f;
+ tag = (int)l;
+ if (--max == 0)
+ goto err;
+ } else {
+ tag = i;
+ p++;
+ if (--max == 0)
+ goto err;
+ }
+ *ptag = tag;
+ *pclass = xclass;
+ if (!asn1_get_length(&p, &inf, plength, max))
+ goto err;
+
+ if (inf && !(ret & V_ASN1_CONSTRUCTED))
+ goto err;
+
+#if 0
+ fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
+ (int)p, *plength, omax, (int)*pp, (int)(p + *plength),
+ (int)(omax + *pp));
+
+#endif
+ if (*plength > (omax - (p - *pp))) {
+ ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
+ /*
+ * Set this so that even if things are not long enough the values are
+ * set correctly
+ */
+ ret |= 0x80;
+ }
+ *pp = p;
+ return (ret | inf);
+ err:
+ ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
+ return (0x80);
+}
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+ long max)
+{
+ const unsigned char *p = *pp;
+ unsigned long ret = 0;
+ unsigned long i;
+
+ if (max-- < 1)
+ return 0;
+ if (*p == 0x80) {
+ *inf = 1;
+ ret = 0;
+ p++;
+ } else {
+ *inf = 0;
+ i = *p & 0x7f;
+ if (*(p++) & 0x80) {
+ if (i > sizeof(ret) || max < (long)i)
+ return 0;
+ while (i-- > 0) {
+ ret <<= 8L;
+ ret |= *(p++);
+ }
+ } else
+ ret = i;
+ }
+ if (ret > LONG_MAX)
+ return 0;
+ *pp = p;
+ *rl = (long)ret;
+ return 1;
+}
+
+/*
+ * class 0 is constructed constructed == 2 for indefinite length constructed
+ */
+void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
+ int xclass)
+{
+ unsigned char *p = *pp;
+ int i, ttag;
+
+ i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
+ i |= (xclass & V_ASN1_PRIVATE);
+ if (tag < 31)
+ *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
+ else {
+ *(p++) = i | V_ASN1_PRIMITIVE_TAG;
+ for (i = 0, ttag = tag; ttag > 0; i++)
+ ttag >>= 7;
+ ttag = i;
+ while (i-- > 0) {
+ p[i] = tag & 0x7f;
+ if (i != (ttag - 1))
+ p[i] |= 0x80;
+ tag >>= 7;
+ }
+ p += ttag;
+ }
+ if (constructed == 2)
+ *(p++) = 0x80;
+ else
+ asn1_put_length(&p, length);
+ *pp = p;
+}
+
+int ASN1_put_eoc(unsigned char **pp)
+{
+ unsigned char *p = *pp;
+ *p++ = 0;
+ *p++ = 0;
+ *pp = p;
+ return 2;
+}
+
+static void asn1_put_length(unsigned char **pp, int length)
+{
+ unsigned char *p = *pp;
+ int i, l;
+ if (length <= 127)
+ *(p++) = (unsigned char)length;
+ else {
+ l = length;
+ for (i = 0; l > 0; i++)
+ l >>= 8;
+ *(p++) = i | 0x80;
+ l = i;
+ while (i-- > 0) {
+ p[i] = length & 0xff;
+ length >>= 8;
+ }
+ p += l;
+ }
+ *pp = p;
+}
+
+int ASN1_object_size(int constructed, int length, int tag)
+{
+ int ret;
+
+ ret = length;
+ ret++;
+ if (tag >= 31) {
+ while (tag > 0) {
+ tag >>= 7;
+ ret++;
+ }
+ }
+ if (constructed == 2)
+ return ret + 3;
+ ret++;
+ if (length > 127) {
+ while (length > 0) {
+ length >>= 8;
+ ret++;
+ }
+ }
+ return (ret);
+}
+
+static int _asn1_Finish(ASN1_const_CTX *c)
+{
+ if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
+ if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
+ c->error = ERR_R_MISSING_ASN1_EOS;
+ return (0);
+ }
+ }
+ if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
+ c->error = ERR_R_ASN1_LENGTH_MISMATCH;
+ return (0);
+ }
+ return (1);
+}
+
+int asn1_Finish(ASN1_CTX *c)
+{
+ return _asn1_Finish((ASN1_const_CTX *)c);
+}
+
+int asn1_const_Finish(ASN1_const_CTX *c)
+{
+ return _asn1_Finish(c);
+}
+
+int asn1_GetSequence(ASN1_const_CTX *c, long *length)
+{
+ const unsigned char *q;
+
+ q = c->p;
+ c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
+ *length);
+ if (c->inf & 0x80) {
+ c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL;
+ return (0);
+ }
+ if (c->tag != V_ASN1_SEQUENCE) {
+ c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
+ return (0);
+ }
+ (*length) -= (c->p - q);
+ if (c->max && (*length < 0)) {
+ c->error = ERR_R_ASN1_LENGTH_MISMATCH;
+ return (0);
+ }
+ if (c->inf == (1 | V_ASN1_CONSTRUCTED))
+ c->slen = *length + *(c->pp) - c->p;
+ c->eos = 0;
+ return (1);
+}
+
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
+{
+ 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;
+}
+
+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 ret;
+}
+
+int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
+{
+ unsigned char *c;
+ const char *data = _data;
+
+ if (len < 0) {
+ if (data == NULL)
+ return (0);
+ else
+ len = strlen(data);
+ }
+ if ((str->length < len) || (str->data == NULL)) {
+ c = str->data;
+ if (c == NULL)
+ str->data = OPENSSL_malloc(len + 1);
+ else
+ str->data = OPENSSL_realloc(c, len + 1);
+
+ if (str->data == NULL) {
+ ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
+ str->data = c;
+ return (0);
+ }
+ }
+ str->length = len;
+ if (data != NULL) {
+ memcpy(str->data, data, len);
+ /* an allowance for strings :-) */
+ str->data[len] = '\0';
+ }
+ return (1);
+}
+
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
+{
+ if (str->data)
+ OPENSSL_free(str->data);
+ str->data = data;
+ str->length = len;
+}
+
+ASN1_STRING *ASN1_STRING_new(void)
+{
+ return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
+}
+
+ASN1_STRING *ASN1_STRING_type_new(int type)
+{
+ ASN1_STRING *ret;
+
+ ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
+ if (ret == NULL) {
+ ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->length = 0;
+ ret->type = type;
+ ret->data = NULL;
+ ret->flags = 0;
+ return (ret);
+}
+
+void ASN1_STRING_free(ASN1_STRING *a)
+{
+ if (a == NULL)
+ return;
+ if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+ OPENSSL_free(a->data);
+ OPENSSL_free(a);
+}
+
+void ASN1_STRING_clear_free(ASN1_STRING *a)
+{
+ if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+ OPENSSL_cleanse(a->data, a->length);
+ ASN1_STRING_free(a);
+}
+
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
+{
+ int i;
+
+ i = (a->length - b->length);
+ if (i == 0) {
+ i = memcmp(a->data, b->data, a->length);
+ if (i == 0)
+ return (a->type - b->type);
+ else
+ return (i);
+ } else
+ return (i);
+}
+
+void asn1_add_error(const unsigned char *address, int offset)
+{
+ char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1];
+
+ BIO_snprintf(buf1, sizeof buf1, "%lu", (unsigned long)address);
+ BIO_snprintf(buf2, sizeof buf2, "%d", offset);
+ ERR_add_error_data(4, "address=", buf1, " offset=", buf2);
+}
+
+int ASN1_STRING_length(const ASN1_STRING *x)
+{
+ return M_ASN1_STRING_length(x);
+}
+
+void ASN1_STRING_length_set(ASN1_STRING *x, int len)
+{
+ M_ASN1_STRING_length_set(x, len);
+ return;
+}
+
+int ASN1_STRING_type(ASN1_STRING *x)
+{
+ return M_ASN1_STRING_type(x);
+}
+
+unsigned char *ASN1_STRING_data(ASN1_STRING *x)
+{
+ return M_ASN1_STRING_data(x);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h b/Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h
new file mode 100644
index 00000000..4c004fab
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h
@@ -0,0 +1,135 @@
+/* asn1t.h */
+/*
+ * 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).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st {
+ unsigned long flags;
+ unsigned long nm_flags;
+ unsigned long cert_flags;
+ unsigned long oid_flags;
+ unsigned long str_flags;
+} /* ASN1_PCTX */ ;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st {
+ 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);
+ int (*sig_print) (BIO *out,
+ const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+ 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);
+ /* Custom ASN1 signature verification */
+ int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
+ int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *alg1, X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig);
+} /* 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.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC 1
+
+struct x509_crl_method_st {
+ 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/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
new file mode 100644
index 00000000..e85e3398
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
@@ -0,0 +1,424 @@
+/* crypto/asn1/asn1_par.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+
+#ifndef ASN1_PARSE_MAXDEPTH
+#define ASN1_PARSE_MAXDEPTH 128
+#endif
+
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+ int indent);
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+ int offset, int depth, int indent, int dump);
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+ int indent)
+{
+ static const char fmt[] = "%-18s";
+ char str[128];
+ const char *p;
+
+ if (constructed & V_ASN1_CONSTRUCTED)
+ p = "cons: ";
+ else
+ p = "prim: ";
+ if (BIO_write(bp, p, 6) < 6)
+ goto err;
+ BIO_indent(bp, indent, 128);
+
+ p = str;
+ if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+ BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
+ else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+ BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
+ else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+ BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
+ else if (tag > 30)
+ BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
+ else
+ p = ASN1_tag2str(tag);
+
+ if (BIO_printf(bp, fmt, p) <= 0)
+ goto err;
+ return (1);
+ err:
+ return (0);
+}
+
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
+{
+ return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
+}
+
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+ int dump)
+{
+ return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
+}
+
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+ int offset, int depth, int indent, int dump)
+{
+ const unsigned char *p, *ep, *tot, *op, *opp;
+ long len;
+ int tag, xclass, ret = 0;
+ int nl, hl, j, r;
+ ASN1_OBJECT *o = NULL;
+ ASN1_OCTET_STRING *os = NULL;
+ /* ASN1_BMPSTRING *bmp=NULL; */
+ int dump_indent;
+
+#if 0
+ dump_indent = indent;
+#else
+ dump_indent = 6; /* Because we know BIO_dump_indent() */
+#endif
+
+ if (depth > ASN1_PARSE_MAXDEPTH) {
+ BIO_puts(bp, "BAD RECURSION DEPTH\n");
+ return 0;
+ }
+
+ p = *pp;
+ tot = p + length;
+ op = p - 1;
+ while ((p < tot) && (op < p)) {
+ op = p;
+ j = ASN1_get_object(&p, &len, &tag, &xclass, length);
+#ifdef LINT
+ j = j;
+#endif
+ if (j & 0x80) {
+ if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
+ goto end;
+ ret = 0;
+ goto end;
+ }
+ hl = (p - op);
+ length -= hl;
+ /*
+ * if j == 0x21 it is a constructed indefinite length object
+ */
+ if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
+ <= 0)
+ goto end;
+
+ if (j != (V_ASN1_CONSTRUCTED | 1)) {
+ if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
+ depth, (long)hl, len) <= 0)
+ goto end;
+ } else {
+ if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0)
+ goto end;
+ }
+ if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
+ goto end;
+ if (j & V_ASN1_CONSTRUCTED) {
+ const unsigned char *sp;
+
+ ep = p + len;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto end;
+ if (len > length) {
+ BIO_printf(bp, "length is greater than %ld\n", length);
+ ret = 0;
+ goto end;
+ }
+ if ((j == 0x21) && (len == 0)) {
+ sp = p;
+ for (;;) {
+ r = asn1_parse2(bp, &p, (long)(tot - p),
+ offset + (p - *pp), depth + 1,
+ indent, dump);
+ if (r == 0) {
+ ret = 0;
+ goto end;
+ }
+ if ((r == 2) || (p >= tot)) {
+ len = p - sp;
+ break;
+ }
+ }
+ } else {
+ long tmp = len;
+
+ while (p < ep) {
+ sp = p;
+ r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1,
+ indent, dump);
+ if (r == 0) {
+ ret = 0;
+ goto end;
+ }
+ tmp -= p - sp;
+ }
+ }
+ } else if (xclass != 0) {
+ p += len;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto end;
+ } else {
+ nl = 0;
+ if ((tag == V_ASN1_PRINTABLESTRING) ||
+ (tag == V_ASN1_T61STRING) ||
+ (tag == V_ASN1_IA5STRING) ||
+ (tag == V_ASN1_VISIBLESTRING) ||
+ (tag == V_ASN1_NUMERICSTRING) ||
+ (tag == V_ASN1_UTF8STRING) ||
+ (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
+ if (BIO_write(bp, ":", 1) <= 0)
+ goto end;
+ if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
+ != (int)len)
+ goto end;
+ } else if (tag == V_ASN1_OBJECT) {
+ opp = op;
+ if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
+ if (BIO_write(bp, ":", 1) <= 0)
+ goto end;
+ i2a_ASN1_OBJECT(bp, o);
+ } else {
+ if (BIO_write(bp, ":BAD OBJECT", 11) <= 0)
+ goto end;
+ }
+ } else if (tag == V_ASN1_BOOLEAN) {
+ int ii;
+
+ opp = op;
+ ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
+ if (ii < 0) {
+ if (BIO_write(bp, "Bad boolean\n", 12) <= 0)
+ goto end;
+ }
+ BIO_printf(bp, ":%d", ii);
+ } else if (tag == V_ASN1_BMPSTRING) {
+ /* do the BMP thang */
+ } else if (tag == V_ASN1_OCTET_STRING) {
+ int i, printable = 1;
+
+ opp = op;
+ os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
+ if (os != NULL && os->length > 0) {
+ opp = os->data;
+ /*
+ * testing whether the octet string is printable
+ */
+ for (i = 0; i < os->length; i++) {
+ if (((opp[i] < ' ') &&
+ (opp[i] != '\n') &&
+ (opp[i] != '\r') &&
+ (opp[i] != '\t')) || (opp[i] > '~')) {
+ printable = 0;
+ break;
+ }
+ }
+ if (printable)
+ /* printable string */
+ {
+ if (BIO_write(bp, ":", 1) <= 0)
+ goto end;
+ if (BIO_write(bp, (const char *)opp, os->length) <= 0)
+ goto end;
+ } else if (!dump)
+ /*
+ * not printable => print octet string as hex dump
+ */
+ {
+ if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
+ goto end;
+ for (i = 0; i < os->length; i++) {
+ if (BIO_printf(bp, "%02X", opp[i]) <= 0)
+ goto end;
+ }
+ } else
+ /* print the normal dump */
+ {
+ if (!nl) {
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto end;
+ }
+ if (BIO_dump_indent(bp,
+ (const char *)opp,
+ ((dump == -1 || dump >
+ os->
+ length) ? os->length : dump),
+ dump_indent) <= 0)
+ goto end;
+ nl = 1;
+ }
+ }
+ if (os != NULL) {
+ M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
+ }
+ } else if (tag == V_ASN1_INTEGER) {
+ ASN1_INTEGER *bs;
+ int i;
+
+ opp = op;
+ bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
+ if (bs != NULL) {
+ if (BIO_write(bp, ":", 1) <= 0)
+ goto end;
+ if (bs->type == V_ASN1_NEG_INTEGER)
+ if (BIO_write(bp, "-", 1) <= 0)
+ goto end;
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+ goto end;
+ }
+ if (bs->length == 0) {
+ if (BIO_write(bp, "00", 2) <= 0)
+ goto end;
+ }
+ } else {
+ if (BIO_write(bp, "BAD INTEGER", 11) <= 0)
+ goto end;
+ }
+ M_ASN1_INTEGER_free(bs);
+ } else if (tag == V_ASN1_ENUMERATED) {
+ ASN1_ENUMERATED *bs;
+ int i;
+
+ opp = op;
+ bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
+ if (bs != NULL) {
+ if (BIO_write(bp, ":", 1) <= 0)
+ goto end;
+ if (bs->type == V_ASN1_NEG_ENUMERATED)
+ if (BIO_write(bp, "-", 1) <= 0)
+ goto end;
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+ goto end;
+ }
+ if (bs->length == 0) {
+ if (BIO_write(bp, "00", 2) <= 0)
+ goto end;
+ }
+ } else {
+ if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0)
+ goto end;
+ }
+ M_ASN1_ENUMERATED_free(bs);
+ } else if (len > 0 && dump) {
+ if (!nl) {
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto end;
+ }
+ if (BIO_dump_indent(bp, (const char *)p,
+ ((dump == -1 || dump > len) ? len : dump),
+ dump_indent) <= 0)
+ goto end;
+ nl = 1;
+ }
+
+ if (!nl) {
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto end;
+ }
+ p += len;
+ if ((tag == V_ASN1_EOC) && (xclass == 0)) {
+ ret = 2; /* End of sequence */
+ goto end;
+ }
+ }
+ length -= len;
+ }
+ ret = 1;
+ end:
+ if (o != NULL)
+ ASN1_OBJECT_free(o);
+ if (os != NULL)
+ M_ASN1_OCTET_STRING_free(os);
+ *pp = p;
+ return (ret);
+}
+
+const char *ASN1_tag2str(int tag)
+{
+ static const char *const tag2str[] = {
+ /* 0-4 */
+ "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
+ /* 5-9 */
+ "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL",
+ /* 10-13 */
+ "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>",
+ /* 15-17 */
+ "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET",
+ /* 18-20 */
+ "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
+ /* 21-24 */
+ "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
+ /* 25-27 */
+ "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",
+ /* 28-30 */
+ "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"
+ };
+
+ if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+ tag &= ~0x100;
+
+ if (tag < 0 || tag > 30)
+ return "(unknown)";
+ return tag2str[tag];
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c b/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
new file mode 100644
index 00000000..96110c54
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
@@ -0,0 +1,974 @@
+/* asn_mime.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "asn1_locl.h"
+
+/*
+ * Generalised MIME like utilities for streaming ASN1. Although many have a
+ * PKCS7/CMS like flavour others are more general purpose.
+ */
+
+/*
+ * MIME format structures Note that all are translated to lower case apart
+ * from parameter values. Quotes are stripped off
+ */
+
+typedef struct {
+ char *param_name; /* Param name e.g. "micalg" */
+ char *param_value; /* Param value e.g. "sha1" */
+} MIME_PARAM;
+
+DECLARE_STACK_OF(MIME_PARAM)
+IMPLEMENT_STACK_OF(MIME_PARAM)
+
+typedef struct {
+ char *name; /* Name of line e.g. "content-type" */
+ char *value; /* Value of line e.g. "text/plain" */
+ STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
+} MIME_HEADER;
+
+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);
+static MIME_HEADER *mime_hdr_new(char *name, char *value);
+static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
+static int mime_hdr_cmp(const MIME_HEADER *const *a,
+ const MIME_HEADER *const *b);
+static int mime_param_cmp(const MIME_PARAM *const *a,
+ const MIME_PARAM *const *b);
+static void mime_param_free(MIME_PARAM *param);
+static int mime_bound_check(char *line, int linelen, char *bound, int blen);
+static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
+static int strip_eol(char *linebuf, int *plen);
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
+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,
+ const ASN1_ITEM *it)
+{
+ BIO *b64;
+ int r;
+ b64 = BIO_new(BIO_f_base64());
+ if (!b64) {
+ ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ /*
+ * prepend the b64 BIO so all data is base64 encoded.
+ */
+ out = BIO_push(b64, out);
+ 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;
+ ASN1_VALUE *val;
+ if (!(b64 = BIO_new(BIO_f_base64()))) {
+ ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ bio = BIO_push(b64, bio);
+ val = ASN1_item_d2i_bio(it, bio, NULL);
+ if (!val)
+ ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
+ (void)BIO_flush(bio);
+ bio = BIO_pop(bio);
+ BIO_free(b64);
+ return val;
+}
+
+/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
+
+static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
+{
+ 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++) {
+ if (write_comma)
+ 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:
+ BIO_puts(out, "sha1");
+ break;
+
+ case NID_md5:
+ BIO_puts(out, "md5");
+ break;
+
+ case NID_sha256:
+ BIO_puts(out, "sha-256");
+ break;
+
+ case NID_sha384:
+ BIO_puts(out, "sha-384");
+ break;
+
+ case NID_sha512:
+ 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;
+ else {
+ BIO_puts(out, "unknown");
+ have_unknown = 1;
+ }
+ break;
+
+ }
+ }
+
+ ret = 1;
+ err:
+
+ return ret;
+
+}
+
+/* SMIME sender */
+
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+ int ctype_nid, int econt_nid,
+ STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it)
+{
+ char bound[33], c;
+ int i;
+ const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
+ const char *msg_type = NULL;
+ if (flags & SMIME_OLDMIME)
+ mime_prefix = "application/x-pkcs7-";
+ else
+ mime_prefix = "application/pkcs7-";
+
+ if (flags & SMIME_CRLFEOL)
+ mime_eol = "\r\n";
+ else
+ mime_eol = "\n";
+ if ((flags & SMIME_DETACHED) && data) {
+ /* We want multipart/signed */
+ /* Generate a random boundary */
+ if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0)
+ return 0;
+ for (i = 0; i < 32; i++) {
+ c = bound[i] & 0xf;
+ if (c < 10)
+ c += '0';
+ else
+ c += 'A' - 10;
+ bound[i] = c;
+ }
+ bound[32] = 0;
+ BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+ BIO_printf(bio, "Content-Type: multipart/signed;");
+ BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
+ BIO_puts(bio, " micalg=\"");
+ asn1_write_micalg(bio, mdalgs);
+ BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
+ bound, mime_eol, mime_eol);
+ BIO_printf(bio, "This is an S/MIME signed message%s%s",
+ mime_eol, mime_eol);
+ /* Now write out the first part */
+ BIO_printf(bio, "------%s%s", bound, mime_eol);
+ if (!asn1_output_data(bio, data, val, flags, it))
+ return 0;
+ BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
+
+ /* Headers for signature */
+
+ BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
+ BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
+ BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol);
+ BIO_printf(bio, "Content-Disposition: attachment;");
+ BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol);
+ B64_write_ASN1(bio, val, NULL, 0, it);
+ BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound,
+ mime_eol, mime_eol);
+ return 1;
+ }
+
+ /* Determine smime-type header */
+
+ if (ctype_nid == NID_pkcs7_enveloped)
+ msg_type = "enveloped-data";
+ else if (ctype_nid == NID_pkcs7_signed) {
+ if (econt_nid == NID_id_smime_ct_receipt)
+ msg_type = "signed-receipt";
+ else if (sk_X509_ALGOR_num(mdalgs) >= 0)
+ msg_type = "signed-data";
+ else
+ msg_type = "certs-only";
+ } else if (ctype_nid == NID_id_smime_ct_compressedData) {
+ msg_type = "compressed-data";
+ cname = "smime.p7z";
+ }
+ /* MIME headers */
+ BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+ BIO_printf(bio, "Content-Disposition: attachment;");
+ BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
+ BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
+ if (msg_type)
+ BIO_printf(bio, " smime-type=%s;", msg_type);
+ BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
+ BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
+ mime_eol, mime_eol);
+ if (!B64_write_ASN1(bio, val, data, flags, it))
+ return 0;
+ BIO_printf(bio, "%s", mime_eol);
+ return 1;
+}
+
+/* Handle output of ASN1 data */
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+ const ASN1_ITEM *it)
+{
+ BIO *tmpbio;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_STREAM_ARG sarg;
+ int rv = 1;
+
+ /*
+ * If data is not deteched or resigning then the output BIO is already
+ * set up to finalise when it is written through.
+ */
+ if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
+ SMIME_crlf_copy(data, out, flags);
+ return 1;
+ }
+
+ if (!aux || !aux->asn1_cb) {
+ ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED);
+ return 0;
+ }
+
+ sarg.out = out;
+ sarg.ndef_bio = NULL;
+ sarg.boundary = NULL;
+
+ /* Let ASN1 code prepend any needed BIOs */
+
+ if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
+ return 0;
+
+ /* Copy data across, passing through filter BIOs for processing */
+ SMIME_crlf_copy(data, sarg.ndef_bio, flags);
+
+ /* Finalize structure */
+ if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
+ rv = 0;
+
+ /* Now remove any digests prepended to the BIO */
+
+ while (sarg.ndef_bio != out) {
+ tmpbio = BIO_pop(sarg.ndef_bio);
+ BIO_free(sarg.ndef_bio);
+ sarg.ndef_bio = tmpbio;
+ }
+
+ return rv;
+
+}
+
+/*
+ * 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
+ */
+
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
+{
+ BIO *asnin;
+ STACK_OF(MIME_HEADER) *headers = NULL;
+ STACK_OF(BIO) *parts = NULL;
+ MIME_HEADER *hdr;
+ MIME_PARAM *prm;
+ ASN1_VALUE *val;
+ int ret;
+
+ if (bcont)
+ *bcont = NULL;
+
+ if (!(headers = mime_parse_hdr(bio))) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
+ return NULL;
+ }
+
+ if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
+ return NULL;
+ }
+
+ /* Handle multipart/signed */
+
+ if (!strcmp(hdr->value, "multipart/signed")) {
+ /* Split into two parts */
+ prm = mime_param_find(hdr, "boundary");
+ if (!prm || !prm->param_value) {
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
+ return NULL;
+ }
+ ret = multi_split(bio, prm->param_value, &parts);
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ if (!ret || (sk_BIO_num(parts) != 2)) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
+ sk_BIO_pop_free(parts, BIO_vfree);
+ return NULL;
+ }
+
+ /* Parse the signature piece */
+ asnin = sk_BIO_value(parts, 1);
+
+ if (!(headers = mime_parse_hdr(asnin))) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR);
+ sk_BIO_pop_free(parts, BIO_vfree);
+ return NULL;
+ }
+
+ /* Get content type */
+
+ if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
+ return NULL;
+ }
+
+ if (strcmp(hdr->value, "application/x-pkcs7-signature") &&
+ strcmp(hdr->value, "application/pkcs7-signature")) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE);
+ ERR_add_error_data(2, "type: ", hdr->value);
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ sk_BIO_pop_free(parts, BIO_vfree);
+ return NULL;
+ }
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ /* Read in ASN1 */
+ if (!(val = b64_read_asn1(asnin, it))) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR);
+ sk_BIO_pop_free(parts, BIO_vfree);
+ return NULL;
+ }
+
+ if (bcont) {
+ *bcont = sk_BIO_value(parts, 0);
+ BIO_free(asnin);
+ sk_BIO_free(parts);
+ } else
+ sk_BIO_pop_free(parts, BIO_vfree);
+ return val;
+ }
+
+ /* OK, if not multipart/signed try opaque signature */
+
+ if (strcmp(hdr->value, "application/x-pkcs7-mime") &&
+ strcmp(hdr->value, "application/pkcs7-mime")) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE);
+ ERR_add_error_data(2, "type: ", hdr->value);
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ return NULL;
+ }
+
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+
+ if (!(val = b64_read_asn1(bio, it))) {
+ ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
+ return NULL;
+ }
+ return val;
+
+}
+
+/* Copy text from one BIO to another making the output CRLF at EOL */
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
+{
+ BIO *bf;
+ char eol;
+ int len;
+ char linebuf[MAX_SMLEN];
+ /*
+ * Buffer output so we don't write one line at a time. This is useful
+ * when streaming as we don't end up with one OCTET STRING per line.
+ */
+ bf = BIO_new(BIO_f_buffer());
+ if (!bf)
+ return 0;
+ out = BIO_push(bf, out);
+ if (flags & SMIME_BINARY) {
+ while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
+ BIO_write(out, linebuf, len);
+ } else {
+ if (flags & SMIME_TEXT)
+ BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
+ while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
+ eol = strip_eol(linebuf, &len);
+ if (len)
+ BIO_write(out, linebuf, len);
+ if (eol)
+ BIO_write(out, "\r\n", 2);
+ }
+ }
+ (void)BIO_flush(out);
+ BIO_pop(out);
+ BIO_free(bf);
+ return 1;
+}
+
+/* Strip off headers if they are text/plain */
+int SMIME_text(BIO *in, BIO *out)
+{
+ char iobuf[4096];
+ int len;
+ STACK_OF(MIME_HEADER) *headers;
+ MIME_HEADER *hdr;
+
+ if (!(headers = mime_parse_hdr(in))) {
+ ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
+ return 0;
+ }
+ if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+ ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ return 0;
+ }
+ if (strcmp(hdr->value, "text/plain")) {
+ ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);
+ ERR_add_error_data(2, "type: ", hdr->value);
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ return 0;
+ }
+ sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+ while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
+ BIO_write(out, iobuf, len);
+ if (len < 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Split a multipart/XXX message body into component parts: result is
+ * canonical parts in a STACK of bios
+ */
+
+static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
+{
+ char linebuf[MAX_SMLEN];
+ int len, blen;
+ int eol = 0, next_eol = 0;
+ BIO *bpart = NULL;
+ STACK_OF(BIO) *parts;
+ char state, part, first;
+
+ blen = strlen(bound);
+ part = 0;
+ state = 0;
+ first = 1;
+ parts = sk_BIO_new_null();
+ *ret = parts;
+ while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+ state = mime_bound_check(linebuf, len, bound, blen);
+ if (state == 1) {
+ first = 1;
+ part++;
+ } else if (state == 2) {
+ sk_BIO_push(parts, bpart);
+ return 1;
+ } else if (part) {
+ /* Strip CR+LF from linebuf */
+ next_eol = strip_eol(linebuf, &len);
+ if (first) {
+ first = 0;
+ if (bpart)
+ sk_BIO_push(parts, bpart);
+ bpart = BIO_new(BIO_s_mem());
+ BIO_set_mem_eof_return(bpart, 0);
+ } else if (eol)
+ BIO_write(bpart, "\r\n", 2);
+ eol = next_eol;
+ if (len)
+ BIO_write(bpart, linebuf, len);
+ }
+ }
+ return 0;
+}
+
+/* This is the big one: parse MIME header lines up to message body */
+
+#define MIME_INVALID 0
+#define MIME_START 1
+#define MIME_TYPE 2
+#define MIME_NAME 3
+#define MIME_VALUE 4
+#define MIME_QUOTE 5
+#define MIME_COMMENT 6
+
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
+{
+ char *p, *q, c;
+ char *ntmp;
+ char linebuf[MAX_SMLEN];
+ MIME_HEADER *mhdr = NULL;
+ STACK_OF(MIME_HEADER) *headers;
+ int len, state, save_state = 0;
+
+ headers = sk_MIME_HEADER_new(mime_hdr_cmp);
+ if (!headers)
+ return NULL;
+ while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+ /* If whitespace at line start then continuation line */
+ if (mhdr && isspace((unsigned char)linebuf[0]))
+ state = MIME_NAME;
+ else
+ state = MIME_START;
+ ntmp = NULL;
+ /* Go through all characters */
+ for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+ p++) {
+
+ /*
+ * State machine to handle MIME headers if this looks horrible
+ * that's because it *is*
+ */
+
+ switch (state) {
+ case MIME_START:
+ if (c == ':') {
+ state = MIME_TYPE;
+ *p = 0;
+ ntmp = strip_ends(q);
+ q = p + 1;
+ }
+ break;
+
+ case MIME_TYPE:
+ if (c == ';') {
+ mime_debug("Found End Value\n");
+ *p = 0;
+ mhdr = mime_hdr_new(ntmp, strip_ends(q));
+ sk_MIME_HEADER_push(headers, mhdr);
+ ntmp = NULL;
+ q = p + 1;
+ state = MIME_NAME;
+ } else if (c == '(') {
+ save_state = state;
+ state = MIME_COMMENT;
+ }
+ break;
+
+ case MIME_COMMENT:
+ if (c == ')') {
+ state = save_state;
+ }
+ break;
+
+ case MIME_NAME:
+ if (c == '=') {
+ state = MIME_VALUE;
+ *p = 0;
+ ntmp = strip_ends(q);
+ q = p + 1;
+ }
+ break;
+
+ case MIME_VALUE:
+ if (c == ';') {
+ state = MIME_NAME;
+ *p = 0;
+ mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+ ntmp = NULL;
+ q = p + 1;
+ } else if (c == '"') {
+ mime_debug("Found Quote\n");
+ state = MIME_QUOTE;
+ } else if (c == '(') {
+ save_state = state;
+ state = MIME_COMMENT;
+ }
+ break;
+
+ case MIME_QUOTE:
+ if (c == '"') {
+ mime_debug("Found Match Quote\n");
+ state = MIME_VALUE;
+ }
+ break;
+ }
+ }
+
+ if (state == MIME_TYPE) {
+ mhdr = mime_hdr_new(ntmp, strip_ends(q));
+ sk_MIME_HEADER_push(headers, mhdr);
+ } else if (state == MIME_VALUE)
+ mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+ if (p == linebuf)
+ break; /* Blank line means end of headers */
+ }
+
+ return headers;
+
+}
+
+static char *strip_ends(char *name)
+{
+ return strip_end(strip_start(name));
+}
+
+/* Strip a parameter of whitespace from start of param */
+static char *strip_start(char *name)
+{
+ char *p, c;
+ /* Look for first non white space or quote */
+ for (p = name; (c = *p); p++) {
+ if (c == '"') {
+ /* Next char is start of string if non null */
+ if (p[1])
+ return p + 1;
+ /* Else null string */
+ return NULL;
+ }
+ if (!isspace((unsigned char)c))
+ return p;
+ }
+ return NULL;
+}
+
+/* As above but strip from end of string : maybe should handle brackets? */
+static char *strip_end(char *name)
+{
+ char *p, c;
+ if (!name)
+ return NULL;
+ /* Look for first non white space or quote */
+ for (p = name + strlen(name) - 1; p >= name; p--) {
+ c = *p;
+ if (c == '"') {
+ if (p - 1 == name)
+ return NULL;
+ *p = 0;
+ return name;
+ }
+ if (isspace((unsigned char)c))
+ *p = 0;
+ else
+ return name;
+ }
+ return NULL;
+}
+
+static MIME_HEADER *mime_hdr_new(char *name, char *value)
+{
+ MIME_HEADER *mhdr;
+ char *tmpname, *tmpval, *p;
+ int c;
+ if (name) {
+ if (!(tmpname = BUF_strdup(name)))
+ return NULL;
+ for (p = tmpname; *p; p++) {
+ c = (unsigned char)*p;
+ if (isupper(c)) {
+ c = tolower(c);
+ *p = c;
+ }
+ }
+ } else
+ tmpname = NULL;
+ if (value) {
+ if (!(tmpval = BUF_strdup(value)))
+ return NULL;
+ for (p = tmpval; *p; p++) {
+ c = (unsigned char)*p;
+ if (isupper(c)) {
+ c = tolower(c);
+ *p = c;
+ }
+ }
+ } else
+ tmpval = NULL;
+ mhdr = (MIME_HEADER *)OPENSSL_malloc(sizeof(MIME_HEADER));
+ if (!mhdr)
+ return NULL;
+ mhdr->name = tmpname;
+ mhdr->value = tmpval;
+ if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)))
+ return NULL;
+ return mhdr;
+}
+
+static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
+{
+ char *tmpname, *tmpval, *p;
+ int c;
+ MIME_PARAM *mparam;
+ if (name) {
+ tmpname = BUF_strdup(name);
+ if (!tmpname)
+ return 0;
+ for (p = tmpname; *p; p++) {
+ c = (unsigned char)*p;
+ if (isupper(c)) {
+ c = tolower(c);
+ *p = c;
+ }
+ }
+ } else
+ tmpname = NULL;
+ if (value) {
+ tmpval = BUF_strdup(value);
+ if (!tmpval)
+ return 0;
+ } else
+ tmpval = NULL;
+ /* Parameter values are case sensitive so leave as is */
+ mparam = (MIME_PARAM *)OPENSSL_malloc(sizeof(MIME_PARAM));
+ if (!mparam)
+ return 0;
+ mparam->param_name = tmpname;
+ mparam->param_value = tmpval;
+ sk_MIME_PARAM_push(mhdr->params, mparam);
+ return 1;
+}
+
+static int mime_hdr_cmp(const MIME_HEADER *const *a,
+ const MIME_HEADER *const *b)
+{
+ if (!(*a)->name || !(*b)->name)
+ return ! !(*a)->name - ! !(*b)->name;
+
+ return (strcmp((*a)->name, (*b)->name));
+}
+
+static int mime_param_cmp(const MIME_PARAM *const *a,
+ const MIME_PARAM *const *b)
+{
+ if (!(*a)->param_name || !(*b)->param_name)
+ return ! !(*a)->param_name - ! !(*b)->param_name;
+ return (strcmp((*a)->param_name, (*b)->param_name));
+}
+
+/* Find a header with a given name (if possible) */
+
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
+{
+ MIME_HEADER htmp;
+ int idx;
+ htmp.name = name;
+ idx = sk_MIME_HEADER_find(hdrs, &htmp);
+ if (idx < 0)
+ return NULL;
+ return sk_MIME_HEADER_value(hdrs, idx);
+}
+
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
+{
+ MIME_PARAM param;
+ int idx;
+ param.param_name = name;
+ idx = sk_MIME_PARAM_find(hdr->params, &param);
+ if (idx < 0)
+ return NULL;
+ return sk_MIME_PARAM_value(hdr->params, idx);
+}
+
+static void mime_hdr_free(MIME_HEADER *hdr)
+{
+ if (hdr->name)
+ OPENSSL_free(hdr->name);
+ if (hdr->value)
+ OPENSSL_free(hdr->value);
+ if (hdr->params)
+ sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
+ OPENSSL_free(hdr);
+}
+
+static void mime_param_free(MIME_PARAM *param)
+{
+ if (param->param_name)
+ OPENSSL_free(param->param_name);
+ if (param->param_value)
+ OPENSSL_free(param->param_value);
+ OPENSSL_free(param);
+}
+
+/*-
+ * Check for a multipart boundary. Returns:
+ * 0 : no boundary
+ * 1 : part boundary
+ * 2 : final boundary
+ */
+static int mime_bound_check(char *line, int linelen, char *bound, int blen)
+{
+ if (linelen == -1)
+ linelen = strlen(line);
+ if (blen == -1)
+ blen = strlen(bound);
+ /* Quickly eliminate if line length too short */
+ if (blen + 2 > linelen)
+ return 0;
+ /* Check for part boundary */
+ if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
+ if (!strncmp(line + blen + 2, "--", 2))
+ return 2;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static int strip_eol(char *linebuf, int *plen)
+{
+ int len = *plen;
+ char *p, c;
+ int is_eol = 0;
+ p = linebuf + len - 1;
+ for (p = linebuf + len - 1; len > 0; len--, p--) {
+ c = *p;
+ if (c == '\n')
+ is_eol = 1;
+ else if (c != '\r')
+ break;
+ }
+ *plen = len;
+ return is_eol;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn_moid.c b/Cryptlib/OpenSSL/crypto/asn1/asn_moid.c
new file mode 100644
index 00000000..fab2dd92
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn_moid.c
@@ -0,0 +1,153 @@
+/* asn_moid.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001-2004 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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+
+/* Simple ASN1 OID module: add all objects in a given section */
+
+static int do_create(char *value, char *name);
+
+static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+ 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))) {
+ ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+ return 0;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+ oval = sk_CONF_VALUE_value(sktmp, i);
+ if (!do_create(oval->value, oval->name)) {
+ ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void oid_module_finish(CONF_IMODULE *md)
+{
+ OBJ_cleanup();
+}
+
+void ASN1_add_oid_module(void)
+{
+ CONF_module_add("oid_section", oid_module_init, oid_module_finish);
+}
+
+/*-
+ * Create an OID based on a name value pair. Accept two formats.
+ * shortname = 1.2.3.4
+ * shortname = some long name, 1.2.3.4
+ */
+
+static int do_create(char *value, char *name)
+{
+ int nid;
+ ASN1_OBJECT *oid;
+ char *ln, *ostr, *p, *lntmp;
+ p = strrchr(value, ',');
+ if (!p) {
+ ln = name;
+ ostr = value;
+ } else {
+ ln = NULL;
+ ostr = p + 1;
+ if (!*ostr)
+ return 0;
+ while (isspace((unsigned char)*ostr))
+ ostr++;
+ }
+
+ nid = OBJ_create(ostr, name, ln);
+
+ if (nid == NID_undef)
+ return 0;
+
+ if (p) {
+ ln = value;
+ while (isspace((unsigned char)*ln))
+ ln++;
+ p--;
+ while (isspace((unsigned char)*p)) {
+ if (p == ln)
+ return 0;
+ p--;
+ }
+ p++;
+ lntmp = OPENSSL_malloc((p - ln) + 1);
+ if (lntmp == NULL)
+ return 0;
+ memcpy(lntmp, ln, p - ln);
+ lntmp[p - ln] = 0;
+ oid = OBJ_nid2obj(nid);
+ oid->ln = lntmp;
+ }
+
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c b/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c
new file mode 100644
index 00000000..366caf01
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c
@@ -0,0 +1,207 @@
+/* asn_pack.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+#ifndef NO_ASN1_OLD
+
+/* ASN1 packing and unpacking functions */
+
+/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
+
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+ d2i_of_void *d2i,
+ void (*free_func) (OPENSSL_BLOCK))
+{
+ STACK_OF(OPENSSL_BLOCK) *sk;
+ const unsigned char *pbuf;
+ pbuf = buf;
+ if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
+ V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
+ ASN1err(ASN1_F_ASN1_SEQ_UNPACK, ASN1_R_DECODE_ERROR);
+ return sk;
+}
+
+/*
+ * Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
+ * OPENSSL_malloc'ed buffer
+ */
+
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+ unsigned char **buf, int *len)
+{
+ int safelen;
+ unsigned char *safe, *p;
+ if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
+ V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
+ ASN1err(ASN1_F_ASN1_SEQ_PACK, ASN1_R_ENCODE_ERROR);
+ return NULL;
+ }
+ if (!(safe = OPENSSL_malloc(safelen))) {
+ ASN1err(ASN1_F_ASN1_SEQ_PACK, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ p = safe;
+ i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
+ IS_SEQUENCE);
+ if (len)
+ *len = safelen;
+ if (buf)
+ *buf = safe;
+ return safe;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
+{
+ const unsigned char *p;
+ char *ret;
+
+ p = oct->data;
+ if (!(ret = d2i(NULL, &p, oct->length)))
+ ASN1err(ASN1_F_ASN1_UNPACK_STRING, ASN1_R_DECODE_ERROR);
+ return ret;
+}
+
+/* Pack an ASN1 object into an ASN1_STRING */
+
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
+{
+ unsigned char *p;
+ ASN1_STRING *octmp;
+
+ if (!oct || !*oct) {
+ if (!(octmp = ASN1_STRING_new())) {
+ ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (oct)
+ *oct = octmp;
+ } else
+ octmp = *oct;
+
+ if (!(octmp->length = i2d(obj, NULL))) {
+ ASN1err(ASN1_F_ASN1_PACK_STRING, ASN1_R_ENCODE_ERROR);
+ goto err;
+ }
+ if (!(p = OPENSSL_malloc(octmp->length))) {
+ ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ octmp->data = p;
+ i2d(obj, &p);
+ return octmp;
+ err:
+ if (!oct || !*oct) {
+ ASN1_STRING_free(octmp);
+ if (oct)
+ *oct = NULL;
+ }
+ return NULL;
+}
+
+#endif
+
+/* ASN1_ITEM versions of the above */
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
+{
+ ASN1_STRING *octmp;
+
+ if (!oct || !*oct) {
+ if (!(octmp = ASN1_STRING_new())) {
+ ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (oct)
+ *oct = octmp;
+ } else
+ octmp = *oct;
+
+ if (octmp->data) {
+ OPENSSL_free(octmp->data);
+ octmp->data = NULL;
+ }
+
+ if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
+ ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR);
+ return NULL;
+ }
+ if (!octmp->data) {
+ ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ return octmp;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
+{
+ const unsigned char *p;
+ void *ret;
+
+ p = oct->data;
+ if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
+ ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c b/Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c
new file mode 100644
index 00000000..60189b3b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c
@@ -0,0 +1,482 @@
+/* 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 <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+/* 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)) {
+ OPENSSL_free(ctx);
+ 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/Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c b/Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c
new file mode 100644
index 00000000..31949b87
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c
@@ -0,0 +1,248 @@
+/* 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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#include <stdio.h>
+
+/* 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);
+ if (!p)
+ return 0;
+
+ 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);
+ if (!p)
+ return 0;
+
+ 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/Cryptlib/OpenSSL/crypto/asn1/charmap.h b/Cryptlib/OpenSSL/crypto/asn1/charmap.h
new file mode 100644
index 00000000..3305ad14
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/charmap.h
@@ -0,0 +1,15 @@
+/*
+ * Auto generated with chartype.pl script. Mask of various character
+ * properties
+ */
+
+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,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
+};
diff --git a/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c b/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c
new file mode 100644
index 00000000..d21829af
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c
@@ -0,0 +1,175 @@
+/* crypto/asn1/d2i_pr.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+ long length)
+{
+ EVP_PKEY *ret;
+ const unsigned char *p = *pp;
+
+ if ((a == NULL) || (*a == NULL)) {
+ if ((ret = EVP_PKEY_new()) == NULL) {
+ ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
+ return (NULL);
+ }
+ } else {
+ ret = *a;
+#ifndef OPENSSL_NO_ENGINE
+ if (ret->engine) {
+ ENGINE_finish(ret->engine);
+ ret->engine = NULL;
+ }
+#endif
+ }
+
+ 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, &p, length)) {
+ if (ret->ameth->priv_decode) {
+ PKCS8_PRIV_KEY_INFO *p8 = NULL;
+ p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+ if (!p8)
+ goto err;
+ EVP_PKEY_free(ret);
+ ret = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (ret == NULL)
+ goto err;
+ } else {
+ ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ }
+ *pp = p;
+ if (a != NULL)
+ (*a) = ret;
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ EVP_PKEY_free(ret);
+ return (NULL);
+}
+
+/*
+ * This works like d2i_PrivateKey() except it automatically works out the
+ * type
+ */
+
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+ long length)
+{
+ STACK_OF(ASN1_TYPE) *inkey;
+ const unsigned char *p;
+ int keytype;
+ p = *pp;
+ /*
+ * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
+ * analyzing it we can determine the passed structure: this assumes the
+ * input is surrounded by an ASN1 SEQUENCE.
+ */
+ inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
+ p = *pp;
+ /*
+ * Since we only need to discern "traditional format" RSA and DSA keys we
+ * can just count the elements.
+ */
+ if (sk_ASN1_TYPE_num(inkey) == 6)
+ 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, &p, 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 (ret == NULL)
+ return NULL;
+ *pp = p;
+ 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/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c b/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c
new file mode 100644
index 00000000..33542dd1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c
@@ -0,0 +1,136 @@
+/* crypto/asn1/d2i_pu.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_EC
+# include <openssl/ec.h>
+#endif
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+ long length)
+{
+ EVP_PKEY *ret;
+
+ if ((a == NULL) || (*a == NULL)) {
+ if ((ret = EVP_PKEY_new()) == NULL) {
+ ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+ return (NULL);
+ }
+ } else
+ ret = *a;
+
+ 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:
+ /* TMP UGLY CAST */
+ if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL,
+ (const unsigned char **)pp,
+ length)) == NULL) {
+ ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ break;
+#endif
+#ifndef OPENSSL_NO_DSA
+ case EVP_PKEY_DSA:
+ /* TMP UGLY CAST */
+ if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
+ (const unsigned char **)pp, length)) {
+ ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ break;
+#endif
+#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_EC:
+ if (!o2i_ECPublicKey(&(ret->pkey.ec),
+ (const unsigned char **)pp, length)) {
+ ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ break;
+#endif
+ default:
+ ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+ goto err;
+ /* break; */
+ }
+ if (a != NULL)
+ (*a) = ret;
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ EVP_PKEY_free(ret);
+ return (NULL);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/evp_asn1.c b/Cryptlib/OpenSSL/crypto/asn1/evp_asn1.c
new file mode 100644
index 00000000..5876afa5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/evp_asn1.c
@@ -0,0 +1,195 @@
+/* crypto/asn1/evp_asn1.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
+{
+ ASN1_STRING *os;
+
+ if ((os = M_ASN1_OCTET_STRING_new()) == NULL)
+ return (0);
+ if (!M_ASN1_OCTET_STRING_set(os, data, len)) {
+ M_ASN1_OCTET_STRING_free(os);
+ return 0;
+ }
+ ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
+ return (1);
+}
+
+/* int max_len: for returned value */
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len)
+{
+ int ret, num;
+ unsigned char *p;
+
+ if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
+ ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+ return (-1);
+ }
+ p = M_ASN1_STRING_data(a->value.octet_string);
+ ret = M_ASN1_STRING_length(a->value.octet_string);
+ if (ret < max_len)
+ num = ret;
+ else
+ num = max_len;
+ memcpy(data, p, num);
+ return (ret);
+}
+
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
+ int len)
+{
+ int n, size;
+ ASN1_OCTET_STRING os, *osp;
+ ASN1_INTEGER in;
+ unsigned char *p;
+ unsigned char buf[32]; /* when they have 256bit longs, I'll be in
+ * trouble */
+ in.data = buf;
+ in.length = 32;
+ os.data = data;
+ os.type = V_ASN1_OCTET_STRING;
+ os.length = len;
+ ASN1_INTEGER_set(&in, num);
+ n = i2d_ASN1_INTEGER(&in, NULL);
+ n += M_i2d_ASN1_OCTET_STRING(&os, NULL);
+
+ size = ASN1_object_size(1, n, V_ASN1_SEQUENCE);
+
+ if ((osp = ASN1_STRING_new()) == NULL)
+ return (0);
+ /* Grow the 'string' */
+ if (!ASN1_STRING_set(osp, NULL, size)) {
+ ASN1_STRING_free(osp);
+ return (0);
+ }
+
+ M_ASN1_STRING_length_set(osp, size);
+ p = M_ASN1_STRING_data(osp);
+
+ ASN1_put_object(&p, 1, n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+ i2d_ASN1_INTEGER(&in, &p);
+ M_i2d_ASN1_OCTET_STRING(&os, &p);
+
+ ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp);
+ return (1);
+}
+
+/*
+ * we return the actual length..., num may be missing, in which case, set it
+ * to zero
+ */
+/* int max_len: for returned value */
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num,
+ unsigned char *data, int max_len)
+{
+ int ret = -1, n;
+ ASN1_INTEGER *ai = NULL;
+ ASN1_OCTET_STRING *os = NULL;
+ const unsigned char *p;
+ long length;
+ ASN1_const_CTX c;
+
+ if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
+ goto err;
+ }
+ p = M_ASN1_STRING_data(a->value.sequence);
+ length = M_ASN1_STRING_length(a->value.sequence);
+
+ c.pp = &p;
+ c.p = p;
+ c.max = p + length;
+ c.error = ASN1_R_DATA_IS_WRONG;
+
+ M_ASN1_D2I_start_sequence();
+ c.q = c.p;
+ if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
+ goto err;
+ c.slen -= (c.p - c.q);
+ c.q = c.p;
+ if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
+ goto err;
+ c.slen -= (c.p - c.q);
+ if (!M_ASN1_D2I_end_sequence())
+ goto err;
+
+ if (num != NULL)
+ *num = ASN1_INTEGER_get(ai);
+
+ ret = M_ASN1_STRING_length(os);
+ if (max_len > ret)
+ n = ret;
+ else
+ n = max_len;
+
+ if (data != NULL)
+ memcpy(data, M_ASN1_STRING_data(os), n);
+ if (0) {
+ err:
+ ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+ }
+ if (os != NULL)
+ M_ASN1_OCTET_STRING_free(os);
+ if (ai != NULL)
+ M_ASN1_INTEGER_free(ai);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/f_enum.c b/Cryptlib/OpenSSL/crypto/asn1/f_enum.c
new file mode 100644
index 00000000..591c3b57
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/f_enum.c
@@ -0,0 +1,203 @@
+/* crypto/asn1/f_enum.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+/* Based on a_int.c: equivalent ENUMERATED functions */
+
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
+{
+ int i, n = 0;
+ static const char *h = "0123456789ABCDEF";
+ char buf[2];
+
+ if (a == NULL)
+ return (0);
+
+ if (a->length == 0) {
+ if (BIO_write(bp, "00", 2) != 2)
+ goto err;
+ n = 2;
+ } else {
+ for (i = 0; i < a->length; i++) {
+ if ((i != 0) && (i % 35 == 0)) {
+ if (BIO_write(bp, "\\\n", 2) != 2)
+ goto err;
+ n += 2;
+ }
+ buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+ buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+ if (BIO_write(bp, buf, 2) != 2)
+ goto err;
+ n += 2;
+ }
+ }
+ return (n);
+ err:
+ return (-1);
+}
+
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
+{
+ int ret = 0;
+ int i, j, k, m, n, again, bufsize;
+ unsigned char *s = NULL, *sp;
+ unsigned char *bufp;
+ int num = 0, slen = 0, first = 1;
+
+ bs->type = V_ASN1_ENUMERATED;
+
+ bufsize = BIO_gets(bp, buf, size);
+ for (;;) {
+ if (bufsize < 1)
+ goto err_sl;
+ i = bufsize;
+ if (buf[i - 1] == '\n')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ if (buf[i - 1] == '\r')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ again = (buf[i - 1] == '\\');
+
+ for (j = 0; j < i; j++) {
+ if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+ ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+ ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+ i = j;
+ break;
+ }
+ }
+ buf[i] = '\0';
+ /*
+ * We have now cleared all the crap off the end of the line
+ */
+ if (i < 2)
+ goto err_sl;
+
+ bufp = (unsigned char *)buf;
+ if (first) {
+ first = 0;
+ if ((bufp[0] == '0') && (buf[1] == '0')) {
+ bufp += 2;
+ i -= 2;
+ }
+ }
+ k = 0;
+ i -= again;
+ if (i % 2 != 0) {
+ ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
+ goto err;
+ }
+ i /= 2;
+ if (num + i > slen) {
+ if (s == NULL)
+ sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+ i * 2);
+ else
+ sp = (unsigned char *)OPENSSL_realloc(s,
+ (unsigned int)num +
+ i * 2);
+ if (sp == NULL) {
+ ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ if (s != NULL)
+ OPENSSL_free(s);
+ goto err;
+ }
+ s = sp;
+ slen = num + i * 2;
+ }
+ for (j = 0; j < i; j++, k += 2) {
+ for (n = 0; n < 2; n++) {
+ m = bufp[k + n];
+ if ((m >= '0') && (m <= '9'))
+ m -= '0';
+ else if ((m >= 'a') && (m <= 'f'))
+ m = m - 'a' + 10;
+ else if ((m >= 'A') && (m <= 'F'))
+ m = m - 'A' + 10;
+ else {
+ ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
+ ASN1_R_NON_HEX_CHARACTERS);
+ goto err;
+ }
+ s[num + j] <<= 4;
+ s[num + j] |= m;
+ }
+ }
+ num += i;
+ if (again)
+ bufsize = BIO_gets(bp, buf, size);
+ else
+ break;
+ }
+ bs->length = num;
+ bs->data = s;
+ ret = 1;
+ err:
+ if (0) {
+ err_sl:
+ ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
+ }
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/f_int.c b/Cryptlib/OpenSSL/crypto/asn1/f_int.c
new file mode 100644
index 00000000..4a81f81c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/f_int.c
@@ -0,0 +1,215 @@
+/* crypto/asn1/f_int.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
+{
+ int i, n = 0;
+ static const char *h = "0123456789ABCDEF";
+ char buf[2];
+
+ if (a == NULL)
+ return (0);
+
+ if (a->type & V_ASN1_NEG) {
+ if (BIO_write(bp, "-", 1) != 1)
+ goto err;
+ n = 1;
+ }
+
+ if (a->length == 0) {
+ if (BIO_write(bp, "00", 2) != 2)
+ goto err;
+ n += 2;
+ } else {
+ for (i = 0; i < a->length; i++) {
+ if ((i != 0) && (i % 35 == 0)) {
+ if (BIO_write(bp, "\\\n", 2) != 2)
+ goto err;
+ n += 2;
+ }
+ buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+ buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+ if (BIO_write(bp, buf, 2) != 2)
+ goto err;
+ n += 2;
+ }
+ }
+ return (n);
+ err:
+ return (-1);
+}
+
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
+{
+ int ret = 0;
+ int i, j, k, m, n, again, bufsize;
+ unsigned char *s = NULL, *sp;
+ unsigned char *bufp;
+ int num = 0, slen = 0, first = 1;
+
+ bs->type = V_ASN1_INTEGER;
+
+ bufsize = BIO_gets(bp, buf, size);
+ for (;;) {
+ if (bufsize < 1)
+ goto err_sl;
+ i = bufsize;
+ if (buf[i - 1] == '\n')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ if (buf[i - 1] == '\r')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ again = (buf[i - 1] == '\\');
+
+ for (j = 0; j < i; j++) {
+#ifndef CHARSET_EBCDIC
+ if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+ ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+ ((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+ /*
+ * This #ifdef is not strictly necessary, since the characters
+ * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
+ * not the whole alphabet). Nevertheless, isxdigit() is faster.
+ */
+ if (!isxdigit(buf[j]))
+#endif
+ {
+ i = j;
+ break;
+ }
+ }
+ buf[i] = '\0';
+ /*
+ * We have now cleared all the crap off the end of the line
+ */
+ if (i < 2)
+ goto err_sl;
+
+ bufp = (unsigned char *)buf;
+ if (first) {
+ first = 0;
+ if ((bufp[0] == '0') && (buf[1] == '0')) {
+ bufp += 2;
+ i -= 2;
+ }
+ }
+ k = 0;
+ i -= again;
+ if (i % 2 != 0) {
+ ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
+ goto err;
+ }
+ i /= 2;
+ if (num + i > slen) {
+ if (s == NULL)
+ sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+ i * 2);
+ else
+ sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
+ if (sp == NULL) {
+ ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ if (s != NULL)
+ OPENSSL_free(s);
+ goto err;
+ }
+ s = sp;
+ slen = num + i * 2;
+ }
+ for (j = 0; j < i; j++, k += 2) {
+ for (n = 0; n < 2; n++) {
+ m = bufp[k + n];
+ if ((m >= '0') && (m <= '9'))
+ m -= '0';
+ else if ((m >= 'a') && (m <= 'f'))
+ m = m - 'a' + 10;
+ else if ((m >= 'A') && (m <= 'F'))
+ m = m - 'A' + 10;
+ else {
+ ASN1err(ASN1_F_A2I_ASN1_INTEGER,
+ ASN1_R_NON_HEX_CHARACTERS);
+ goto err;
+ }
+ s[num + j] <<= 4;
+ s[num + j] |= m;
+ }
+ }
+ num += i;
+ if (again)
+ bufsize = BIO_gets(bp, buf, size);
+ else
+ break;
+ }
+ bs->length = num;
+ bs->data = s;
+ ret = 1;
+ err:
+ if (0) {
+ err_sl:
+ ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+ }
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/f_string.c b/Cryptlib/OpenSSL/crypto/asn1/f_string.c
new file mode 100644
index 00000000..6a6cf347
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/f_string.c
@@ -0,0 +1,209 @@
+/* crypto/asn1/f_string.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
+{
+ int i, n = 0;
+ static const char *h = "0123456789ABCDEF";
+ char buf[2];
+
+ if (a == NULL)
+ return (0);
+
+ if (a->length == 0) {
+ if (BIO_write(bp, "0", 1) != 1)
+ goto err;
+ n = 1;
+ } else {
+ for (i = 0; i < a->length; i++) {
+ if ((i != 0) && (i % 35 == 0)) {
+ if (BIO_write(bp, "\\\n", 2) != 2)
+ goto err;
+ n += 2;
+ }
+ buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+ buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+ if (BIO_write(bp, buf, 2) != 2)
+ goto err;
+ n += 2;
+ }
+ }
+ return (n);
+ err:
+ return (-1);
+}
+
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
+{
+ int ret = 0;
+ int i, j, k, m, n, again, bufsize;
+ unsigned char *s = NULL, *sp;
+ unsigned char *bufp;
+ int num = 0, slen = 0, first = 1;
+
+ bufsize = BIO_gets(bp, buf, size);
+ for (;;) {
+ if (bufsize < 1) {
+ if (first)
+ break;
+ else
+ goto err_sl;
+ }
+ first = 0;
+
+ i = bufsize;
+ if (buf[i - 1] == '\n')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ if (buf[i - 1] == '\r')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ again = (buf[i - 1] == '\\');
+
+ for (j = i - 1; j > 0; j--) {
+#ifndef CHARSET_EBCDIC
+ if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+ ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+ ((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+ /*
+ * This #ifdef is not strictly necessary, since the characters
+ * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
+ * not the whole alphabet). Nevertheless, isxdigit() is faster.
+ */
+ if (!isxdigit(buf[j]))
+#endif
+ {
+ i = j;
+ break;
+ }
+ }
+ buf[i] = '\0';
+ /*
+ * We have now cleared all the crap off the end of the line
+ */
+ if (i < 2)
+ goto err_sl;
+
+ bufp = (unsigned char *)buf;
+
+ k = 0;
+ i -= again;
+ if (i % 2 != 0) {
+ ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
+ goto err;
+ }
+ i /= 2;
+ if (num + i > slen) {
+ if (s == NULL)
+ sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+ i * 2);
+ else
+ sp = (unsigned char *)OPENSSL_realloc(s,
+ (unsigned int)num +
+ i * 2);
+ if (sp == NULL) {
+ ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+ if (s != NULL)
+ OPENSSL_free(s);
+ goto err;
+ }
+ s = sp;
+ slen = num + i * 2;
+ }
+ for (j = 0; j < i; j++, k += 2) {
+ for (n = 0; n < 2; n++) {
+ m = bufp[k + n];
+ if ((m >= '0') && (m <= '9'))
+ m -= '0';
+ else if ((m >= 'a') && (m <= 'f'))
+ m = m - 'a' + 10;
+ else if ((m >= 'A') && (m <= 'F'))
+ m = m - 'A' + 10;
+ else {
+ ASN1err(ASN1_F_A2I_ASN1_STRING,
+ ASN1_R_NON_HEX_CHARACTERS);
+ goto err;
+ }
+ s[num + j] <<= 4;
+ s[num + j] |= m;
+ }
+ }
+ num += i;
+ if (again)
+ bufsize = BIO_gets(bp, buf, size);
+ else
+ break;
+ }
+ bs->length = num;
+ bs->data = s;
+ ret = 1;
+ err:
+ if (0) {
+ err_sl:
+ ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
+ }
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c b/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c
new file mode 100644
index 00000000..4d338ac5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c
@@ -0,0 +1,78 @@
+/* crypto/asn1/i2d_pr.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
+{
+ if (a->ameth && a->ameth->old_priv_encode) {
+ return a->ameth->old_priv_encode(a, pp);
+ }
+ 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/Cryptlib/OpenSSL/crypto/asn1/i2d_pu.c b/Cryptlib/OpenSSL/crypto/asn1/i2d_pu.c
new file mode 100644
index 00000000..b8ed3554
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/i2d_pu.c
@@ -0,0 +1,93 @@
+/* crypto/asn1/i2d_pu.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_EC
+# include <openssl/ec.h>
+#endif
+
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
+{
+ switch (a->type) {
+#ifndef OPENSSL_NO_RSA
+ case EVP_PKEY_RSA:
+ return (i2d_RSAPublicKey(a->pkey.rsa, pp));
+#endif
+#ifndef OPENSSL_NO_DSA
+ case EVP_PKEY_DSA:
+ return (i2d_DSAPublicKey(a->pkey.dsa, pp));
+#endif
+#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_EC:
+ return (i2o_ECPublicKey(a->pkey.ec, pp));
+#endif
+ default:
+ ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ return (-1);
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c
new file mode 100644
index 00000000..bede55c8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c
@@ -0,0 +1,354 @@
+/* crypto/asn1/n_pkey.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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# include <openssl/objects.h>
+# include <openssl/asn1t.h>
+# include <openssl/asn1_mac.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+
+# ifndef OPENSSL_NO_RC4
+
+typedef struct netscape_pkey_st {
+ long version;
+ X509_ALGOR *algor;
+ ASN1_OCTET_STRING *private_key;
+} NETSCAPE_PKEY;
+
+typedef struct netscape_encrypted_pkey_st {
+ ASN1_OCTET_STRING *os;
+ /*
+ * This is the same structure as DigestInfo so use it: although this
+ * isn't really anything to do with digests.
+ */
+ X509_SIG *enckey;
+} NETSCAPE_ENCRYPTED_PKEY;
+
+
+ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
+ ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
+} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+
+ASN1_SEQUENCE(NETSCAPE_PKEY) = {
+ ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
+ ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+
+static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
+ int (*cb) (char *buf, int len, const char *prompt,
+ int verify), int sgckey);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+ int (*cb) (char *buf, int len, const char *prompt,
+ int verify))
+{
+ return i2d_RSA_NET(a, pp, cb, 0);
+}
+
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+ int (*cb) (char *buf, int len, const char *prompt,
+ int verify), int sgckey)
+{
+ int i, j, ret = 0;
+ int rsalen, pkeylen, olen;
+ NETSCAPE_PKEY *pkey = NULL;
+ NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
+ unsigned char buf[256], *zz;
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ if (a == NULL)
+ return (0);
+
+ if ((pkey = NETSCAPE_PKEY_new()) == NULL)
+ goto err;
+ if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL)
+ goto err;
+ pkey->version = 0;
+
+ pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
+ if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL)
+ goto err;
+ pkey->algor->parameter->type = V_ASN1_NULL;
+
+ rsalen = i2d_RSAPrivateKey(a, NULL);
+
+ /*
+ * Fake some octet strings just for the initial length calculation.
+ */
+
+ pkey->private_key->length = rsalen;
+
+ pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL);
+
+ enckey->enckey->digest->length = pkeylen;
+
+ enckey->os->length = 11; /* "private-key" */
+
+ enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4);
+ if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL)
+ goto err;
+ enckey->enckey->algor->parameter->type = V_ASN1_NULL;
+
+ if (pp == NULL) {
+ olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
+ NETSCAPE_PKEY_free(pkey);
+ NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+ return olen;
+ }
+
+ /* Since its RC4 encrypted length is actual length */
+ if ((zz = (unsigned char *)OPENSSL_malloc(rsalen)) == NULL) {
+ ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pkey->private_key->data = zz;
+ /* Write out private key encoding */
+ i2d_RSAPrivateKey(a, &zz);
+
+ if ((zz = OPENSSL_malloc(pkeylen)) == NULL) {
+ ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!ASN1_STRING_set(enckey->os, "private-key", -1)) {
+ ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ enckey->enckey->digest->data = zz;
+ i2d_NETSCAPE_PKEY(pkey, &zz);
+
+ /* Wipe the private key encoding */
+ OPENSSL_cleanse(pkey->private_key->data, rsalen);
+
+ if (cb == NULL)
+#ifndef OPENSSL_NO_UI
+ cb = EVP_read_pw_string;
+#else
+ i = 1;
+ else
+#endif
+ i = cb((char *)buf, 256, "Enter Private Key password:", 1);
+ if (i != 0) {
+ ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ);
+ goto err;
+ }
+ i = strlen((char *)buf);
+ /* If the key is used for SGC the algorithm is modified a little. */
+ if (sgckey) {
+ if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+ goto err;
+ memcpy(buf + 16, "SGCKEYSALT", 10);
+ i = 26;
+ }
+
+ if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
+ goto err;
+ OPENSSL_cleanse(buf, 256);
+
+ /* Encrypt private key in place */
+ zz = enckey->enckey->digest->data;
+ if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
+ goto err;
+ if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
+ goto err;
+ if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
+ goto err;
+
+ ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+ NETSCAPE_PKEY_free(pkey);
+ return (ret);
+}
+
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+ int (*cb) (char *buf, int len, const char *prompt,
+ int verify))
+{
+ return d2i_RSA_NET(a, pp, length, cb, 0);
+}
+
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+ int (*cb) (char *buf, int len, const char *prompt,
+ int verify), int sgckey)
+{
+ RSA *ret = NULL;
+ const unsigned char *p;
+ NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
+
+ p = *pp;
+
+ enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
+ if (!enckey) {
+ ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR);
+ return NULL;
+ }
+
+ if ((enckey->os->length != 11) || (strncmp("private-key",
+ (char *)enckey->os->data,
+ 11) != 0)) {
+ ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING);
+ NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+ return NULL;
+ }
+ if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
+ ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
+ goto err;
+ }
+ if (cb == NULL)
+#ifndef OPENSSL_NO_UI
+ cb = EVP_read_pw_string;
+#else
+ goto err;
+#endif
+ if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL)
+ goto err;
+
+ *pp = p;
+
+ err:
+ NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+ return ret;
+
+}
+
+static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
+ int (*cb) (char *buf, int len, const char *prompt,
+ int verify), int sgckey)
+{
+ NETSCAPE_PKEY *pkey = NULL;
+ RSA *ret = NULL;
+ int i, j;
+ unsigned char buf[256];
+ const unsigned char *zz;
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ i = cb((char *)buf, 256, "Enter Private Key password:", 0);
+ if (i != 0) {
+ ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ);
+ goto err;
+ }
+
+ i = strlen((char *)buf);
+ if (sgckey) {
+ if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+ goto err;
+ memcpy(buf + 16, "SGCKEYSALT", 10);
+ i = 26;
+ }
+
+ if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
+ goto err;
+ OPENSSL_cleanse(buf, 256);
+
+ if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
+ goto err;
+ if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
+ goto err;
+ os->length = i + j;
+
+ zz = os->data;
+
+ if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) {
+ ASN1err(ASN1_F_D2I_RSA_NET_2,
+ ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
+ goto err;
+ }
+
+ zz = pkey->private_key->data;
+ if ((ret = d2i_RSAPrivateKey(a, &zz, pkey->private_key->length)) == NULL) {
+ ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
+ goto err;
+ }
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ NETSCAPE_PKEY_free(pkey);
+ return (ret);
+}
+
+# endif /* OPENSSL_NO_RC4 */
+
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy = &dummy;
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/asn1/nsseq.c b/Cryptlib/OpenSSL/crypto/asn1/nsseq.c
new file mode 100644
index 00000000..f2f7cba4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/nsseq.c
@@ -0,0 +1,84 @@
+/* nsseq.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+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;
+ nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
+ nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
+ }
+ return 1;
+}
+
+/* Netscape certificate sequence structure */
+
+ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
+ ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
+ ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
+} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c b/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c
new file mode 100644
index 00000000..bdbfdcd6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c
@@ -0,0 +1,143 @@
+/* p5_pbe.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 password based encryption structure */
+
+ASN1_SEQUENCE(PBEPARAM) = {
+ ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PBEPARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
+
+/* 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_STRING *pbe_str = NULL;
+ unsigned char *sstr;
+
+ 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_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ 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;
+ }
+ sstr = ASN1_STRING_data(pbe->salt);
+ if (salt)
+ memcpy(sstr, salt, saltlen);
+ else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
+ goto err;
+
+ if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
+ ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ PBEPARAM_free(pbe);
+ pbe = NULL;
+
+ if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+ return 1;
+
+ err:
+ 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/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c b/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c
new file mode 100644
index 00000000..73ba4a3d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c
@@ -0,0 +1,280 @@
+/* p5_pbev2.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999-2004.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 v2.0 password based encryption structures */
+
+ASN1_SEQUENCE(PBE2PARAM) = {
+ ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
+ ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBE2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
+
+ASN1_SEQUENCE(PBKDF2PARAM) = {
+ ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
+ ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
+ ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
+ ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBKDF2PARAM)
+
+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_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, keylen;
+ EVP_CIPHER_CTX ctx;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ PBE2PARAM *pbe2 = NULL;
+ ASN1_OBJECT *obj;
+
+ alg_nid = EVP_CIPHER_type(cipher);
+ if (alg_nid == NID_undef) {
+ ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+ ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+ goto err;
+ }
+ obj = OBJ_nid2obj(alg_nid);
+
+ if (!(pbe2 = PBE2PARAM_new()))
+ goto merr;
+
+ /* Setup the AlgorithmIdentifier for the encryption scheme */
+ scheme = pbe2->encryption;
+
+ scheme->algorithm = obj;
+ if (!(scheme->parameter = ASN1_TYPE_new()))
+ goto merr;
+
+ /* Create random IV */
+ 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, and PRF */
+ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
+ goto err;
+ if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
+ 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 its RC2 then we'd better setup the key length */
+
+ if (alg_nid == NID_rc2_cbc)
+ keylen = EVP_CIPHER_key_length(cipher);
+ else
+ keylen = -1;
+
+ /* Setup keyfunc */
+
+ X509_ALGOR_free(pbe2->keyfunc);
+
+ pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
+
+ if (!pbe2->keyfunc)
+ goto merr;
+
+ /* Now set up top level AlgorithmIdentifier */
+
+ if (!(ret = X509_ALGOR_new()))
+ goto merr;
+ if (!(ret->parameter = ASN1_TYPE_new()))
+ goto merr;
+
+ ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+ /* Encode PBE2PARAM into parameter */
+
+ if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
+ &ret->parameter->value.sequence))
+ goto merr;
+ ret->parameter->type = V_ASN1_SEQUENCE;
+
+ PBE2PARAM_free(pbe2);
+ pbe2 = NULL;
+
+ return ret;
+
+ merr:
+ ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
+
+ err:
+ PBE2PARAM_free(pbe2);
+ /* Note 'scheme' is freed as part of pbe2 */
+ X509_ALGOR_free(kalg);
+ X509_ALGOR_free(ret);
+
+ 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);
+}
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+ int prf_nid, int keylen)
+{
+ X509_ALGOR *keyfunc = NULL;
+ PBKDF2PARAM *kdf = NULL;
+ ASN1_OCTET_STRING *osalt = NULL;
+
+ if (!(kdf = PBKDF2PARAM_new()))
+ goto merr;
+ if (!(osalt = M_ASN1_OCTET_STRING_new()))
+ goto merr;
+
+ kdf->salt->value.octet_string = osalt;
+ kdf->salt->type = V_ASN1_OCTET_STRING;
+
+ if (!saltlen)
+ saltlen = PKCS5_SALT_LEN;
+ if (!(osalt->data = OPENSSL_malloc(saltlen)))
+ goto merr;
+
+ osalt->length = saltlen;
+
+ if (salt)
+ memcpy(osalt->data, salt, saltlen);
+ else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
+ goto merr;
+
+ if (iter <= 0)
+ iter = PKCS5_DEFAULT_ITER;
+
+ if (!ASN1_INTEGER_set(kdf->iter, iter))
+ goto merr;
+
+ /* If have a key len set it up */
+
+ if (keylen > 0) {
+ if (!(kdf->keylength = M_ASN1_INTEGER_new()))
+ goto merr;
+ if (!ASN1_INTEGER_set(kdf->keylength, keylen))
+ goto merr;
+ }
+
+ /* prf can stay NULL if we are using hmacWithSHA1 */
+ if (prf_nid > 0 && 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);
+ }
+
+ /* Finally setup the keyfunc structure */
+
+ keyfunc = X509_ALGOR_new();
+ if (!keyfunc)
+ goto merr;
+
+ keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+
+ /* Encode PBKDF2PARAM into parameter of pbe2 */
+
+ if (!(keyfunc->parameter = ASN1_TYPE_new()))
+ goto merr;
+
+ if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
+ &keyfunc->parameter->value.sequence))
+ goto merr;
+ keyfunc->parameter->type = V_ASN1_SEQUENCE;
+
+ PBKDF2PARAM_free(kdf);
+ return keyfunc;
+
+ merr:
+ ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
+ PBKDF2PARAM_free(kdf);
+ X509_ALGOR_free(keyfunc);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c
new file mode 100644
index 00000000..0a425cd2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c
@@ -0,0 +1,145 @@
+/* p8_pkey.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/* Minor tweak to operation: zero private key data */
+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) {
+ PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
+ if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING
+ && key->pkey->value.octet_string != NULL)
+ OPENSSL_cleanse(key->pkey->value.octet_string->data,
+ key->pkey->value.octet_string->length);
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
+ ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
+ ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
+ ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
+} 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/Cryptlib/OpenSSL/crypto/asn1/t_bitst.c b/Cryptlib/OpenSSL/crypto/asn1/t_bitst.c
new file mode 100644
index 00000000..d5cf3c77
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_bitst.c
@@ -0,0 +1,105 @@
+/* t_bitst.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+ BIT_STRING_BITNAME *tbl, int indent)
+{
+ BIT_STRING_BITNAME *bnam;
+ char first = 1;
+ BIO_printf(out, "%*s", indent, "");
+ for (bnam = tbl; bnam->lname; bnam++) {
+ if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+ if (!first)
+ BIO_puts(out, ", ");
+ BIO_puts(out, bnam->lname);
+ first = 0;
+ }
+ }
+ BIO_puts(out, "\n");
+ return 1;
+}
+
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+ BIT_STRING_BITNAME *tbl)
+{
+ int bitnum;
+ bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+ if (bitnum < 0)
+ return 0;
+ if (bs) {
+ if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+ return 0;
+ }
+ return 1;
+}
+
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
+{
+ BIT_STRING_BITNAME *bnam;
+ for (bnam = tbl; bnam->lname; bnam++) {
+ if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name))
+ return bnam->bitnum;
+ }
+ return -1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_crl.c b/Cryptlib/OpenSSL/crypto/asn1/t_crl.c
new file mode 100644
index 00000000..0dfaf0ba
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_crl.c
@@ -0,0 +1,133 @@
+/* t_crl.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_FP_API
+int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_CRL_print(b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int X509_CRL_print(BIO *out, X509_CRL *x)
+{
+ STACK_OF(X509_REVOKED) *rev;
+ X509_REVOKED *r;
+ long l;
+ int i;
+ char *p;
+
+ BIO_printf(out, "Certificate Revocation List (CRL):\n");
+ l = X509_CRL_get_version(x);
+ BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
+ i = OBJ_obj2nid(x->sig_alg->algorithm);
+ X509_signature_print(out, x->sig_alg, NULL);
+ p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
+ BIO_printf(out, "%8sIssuer: %s\n", "", p);
+ OPENSSL_free(p);
+ BIO_printf(out, "%8sLast Update: ", "");
+ ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
+ BIO_printf(out, "\n%8sNext Update: ", "");
+ if (X509_CRL_get_nextUpdate(x))
+ ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
+ else
+ BIO_printf(out, "NONE");
+ BIO_printf(out, "\n");
+
+ X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8);
+
+ rev = X509_CRL_get_REVOKED(x);
+
+ if (sk_X509_REVOKED_num(rev) > 0)
+ BIO_printf(out, "Revoked Certificates:\n");
+ else
+ BIO_printf(out, "No Revoked Certificates.\n");
+
+ for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+ r = sk_X509_REVOKED_value(rev, i);
+ BIO_printf(out, " Serial Number: ");
+ i2a_ASN1_INTEGER(out, r->serialNumber);
+ BIO_printf(out, "\n Revocation Date: ");
+ ASN1_TIME_print(out, r->revocationDate);
+ BIO_printf(out, "\n");
+ X509V3_extensions_print(out, "CRL entry extensions",
+ r->extensions, 0, 8);
+ }
+ X509_signature_print(out, x->sig_alg, x->signature);
+
+ return 1;
+
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c
new file mode 100644
index 00000000..735c3426
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c
@@ -0,0 +1,113 @@
+/* crypto/asn1/t_pkey.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+ unsigned char *buf, int off)
+{
+ int n, i;
+ const char *neg;
+
+ if (num == NULL)
+ return (1);
+ neg = (BN_is_negative(num)) ? "-" : "";
+ if (!BIO_indent(bp, off, 128))
+ return 0;
+ if (BN_is_zero(num)) {
+ if (BIO_printf(bp, "%s 0\n", number) <= 0)
+ return 0;
+ return 1;
+ }
+
+ if (BN_num_bytes(num) <= BN_BYTES) {
+ if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
+ (unsigned long)num->d[0], neg,
+ (unsigned long)num->d[0])
+ <= 0)
+ return (0);
+ } else {
+ buf[0] = 0;
+ if (BIO_printf(bp, "%s%s", number,
+ (neg[0] == '-') ? " (Negative)" : "") <= 0)
+ return (0);
+ n = BN_bn2bin(num, &buf[1]);
+
+ if (buf[1] & 0x80)
+ n++;
+ else
+ buf++;
+
+ for (i = 0; i < n; i++) {
+ if ((i % 15) == 0) {
+ if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128))
+ return 0;
+ }
+ if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":")
+ <= 0)
+ return (0);
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return (0);
+ }
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_req.c b/Cryptlib/OpenSSL/crypto/asn1/t_req.c
new file mode 100644
index 00000000..024553ab
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_req.c
@@ -0,0 +1,254 @@
+/* crypto/asn1/t_req.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_REQ_print(b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ unsigned long l;
+ int i;
+ const char *neg;
+ X509_REQ_INFO *ri;
+ EVP_PKEY *pkey;
+ STACK_OF(X509_ATTRIBUTE) *sk;
+ STACK_OF(X509_EXTENSION) *exts;
+ char mlch = ' ';
+ int nmindent = 0;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ ri = x->req_info;
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : "";
+ l = 0;
+ for (i = 0; i < ri->version->length; i++) {
+ l <<= 8;
+ l += ri->version->data[i];
+ }
+ if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg,
+ l) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_REQ_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bp);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+ /* may not be */
+ if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
+ goto err;
+
+ sk = x->req_info->attributes;
+ if (sk_X509_ATTRIBUTE_num(sk) == 0) {
+ if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
+ goto err;
+ } else {
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+ ASN1_TYPE *at;
+ X509_ATTRIBUTE *a;
+ ASN1_BIT_STRING *bs = NULL;
+ ASN1_TYPE *t;
+ int j, type = 0, count = 1, ii = 0;
+
+ a = sk_X509_ATTRIBUTE_value(sk, i);
+ if (X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
+ continue;
+ if (BIO_printf(bp, "%12s", "") <= 0)
+ goto err;
+ if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) {
+ if (a->single) {
+ t = a->value.single;
+ type = t->type;
+ bs = t->value.bit_string;
+ } else {
+ ii = 0;
+ count = sk_ASN1_TYPE_num(a->value.set);
+ get_next:
+ at = sk_ASN1_TYPE_value(a->value.set, ii);
+ type = at->type;
+ bs = at->value.asn1_string;
+ }
+ }
+ for (j = 25 - j; j > 0; j--)
+ if (BIO_write(bp, " ", 1) != 1)
+ goto err;
+ if (BIO_puts(bp, ":") <= 0)
+ goto err;
+ if ((type == V_ASN1_PRINTABLESTRING) ||
+ (type == V_ASN1_T61STRING) ||
+ (type == V_ASN1_IA5STRING)) {
+ if (BIO_write(bp, (char *)bs->data, bs->length)
+ != bs->length)
+ goto err;
+ BIO_puts(bp, "\n");
+ } else {
+ BIO_puts(bp, "unable to print attribute\n");
+ }
+ if (++ii < count)
+ goto get_next;
+ }
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+ exts = X509_REQ_get_extensions(x);
+ if (exts) {
+ BIO_printf(bp, "%8sRequested Extensions:\n", "");
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ex;
+ int j;
+ ex = sk_X509_EXTENSION_value(exts, i);
+ if (BIO_printf(bp, "%12s", "") <= 0)
+ goto err;
+ obj = X509_EXTENSION_get_object(ex);
+ i2a_ASN1_OBJECT(bp, obj);
+ j = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
+ goto err;
+ if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
+ BIO_printf(bp, "%16s", "");
+ M_ASN1_OCTET_STRING_print(bp, ex->value);
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ if (!X509_signature_print(bp, x->sig_alg, x->signature))
+ goto err;
+ }
+
+ return (1);
+ err:
+ X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
+ return (0);
+}
+
+int X509_REQ_print(BIO *bp, X509_REQ *x)
+{
+ return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_spki.c b/Cryptlib/OpenSSL/crypto/asn1/t_spki.c
new file mode 100644
index 00000000..3bf48db5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_spki.c
@@ -0,0 +1,108 @@
+/* t_spki.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#include <openssl/bn.h>
+
+/* Print out an SPKI */
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
+{
+ EVP_PKEY *pkey;
+ ASN1_IA5STRING *chal;
+ int i, n;
+ char *s;
+ BIO_printf(out, "Netscape SPKI:\n");
+ i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
+ BIO_printf(out, " Public Key Algorithm: %s\n",
+ (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 {
+ 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);
+ i = OBJ_obj2nid(spki->sig_algor->algorithm);
+ BIO_printf(out, " Signature Algorithm: %s",
+ (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+
+ n = spki->signature->length;
+ s = (char *)spki->signature->data;
+ for (i = 0; i < n; i++) {
+ if ((i % 18) == 0)
+ BIO_write(out, "\n ", 7);
+ BIO_printf(out, "%02x%s", (unsigned char)s[i],
+ ((i + 1) == n) ? "" : ":");
+ }
+ BIO_write(out, "\n", 1);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_x509.c b/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
new file mode 100644
index 00000000..8888396f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
@@ -0,0 +1,556 @@
+/* crypto/asn1/t_x509.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_EC
+# include <openssl/ec.h>
+#endif
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "asn1_locl.h"
+
+#ifndef OPENSSL_NO_FP_API
+int X509_print_fp(FILE *fp, X509 *x)
+{
+ return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
+ unsigned long cflag)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_print_ex(b, x, nmflag, cflag);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int X509_print(BIO *bp, X509 *x)
+{
+ return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ long l;
+ int ret = 0, i;
+ char *m = NULL, mlch = ' ';
+ int nmindent = 0;
+ X509_CINF *ci;
+ ASN1_INTEGER *bs;
+ EVP_PKEY *pkey = NULL;
+ const char *neg;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ ci = x->cert_info;
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_get_version(x);
+ if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SERIAL)) {
+
+ if (BIO_write(bp, " Serial Number:", 22) <= 0)
+ goto err;
+
+ bs = X509_get_serialNumber(x);
+ if (bs->length < (int)sizeof(long)
+ || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) {
+ l = ASN1_INTEGER_get(bs);
+ if (bs->type == V_ASN1_NEG_INTEGER) {
+ l = -l;
+ neg = "-";
+ } else
+ neg = "";
+ if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
+ goto err;
+ } else {
+ neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
+ if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+ goto err;
+
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02x%c", bs->data[i],
+ ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+ goto err;
+ }
+ }
+
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+ if (X509_signature_print(bp, ci->signature, NULL) <= 0)
+ goto err;
+#if 0
+ if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+#endif
+ }
+
+ if (!(cflag & X509_FLAG_NO_ISSUER)) {
+ if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
+ < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+ if (BIO_write(bp, " Validity\n", 17) <= 0)
+ goto err;
+ if (BIO_write(bp, " Not Before: ", 24) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
+ goto err;
+ if (BIO_write(bp, "\n Not After : ", 25) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex
+ (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bp);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_IDS)) {
+ if (ci->issuerUID) {
+ if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, ci->issuerUID, 12))
+ goto err;
+ }
+ if (ci->subjectUID) {
+ if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, ci->subjectUID, 12))
+ goto err;
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+ X509V3_extensions_print(bp, "X509v3 extensions",
+ ci->extensions, cflag, 8);
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_AUX)) {
+ if (!X509_CERT_AUX_print(bp, x->aux, 0))
+ goto err;
+ }
+ ret = 1;
+ err:
+ if (m != NULL)
+ OPENSSL_free(m);
+ return (ret);
+}
+
+int X509_ocspid_print(BIO *bp, X509 *x)
+{
+ unsigned char *der = NULL;
+ unsigned char *dertmp;
+ int derlen;
+ int i;
+ unsigned char SHA1md[SHA_DIGEST_LENGTH];
+
+ /*
+ * display the hash of the subject as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
+ goto err;
+ derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
+ if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL)
+ goto err;
+ i2d_X509_NAME(x->cert_info->subject, &dertmp);
+
+ if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+ goto err;
+ }
+ OPENSSL_free(der);
+ der = NULL;
+
+ /*
+ * display the hash of the public key as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
+ goto err;
+
+ if (!EVP_Digest(x->cert_info->key->public_key->data,
+ x->cert_info->key->public_key->length,
+ SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+ goto err;
+ }
+ BIO_printf(bp, "\n");
+
+ return (1);
+ err:
+ if (der != NULL)
+ OPENSSL_free(der);
+ return (0);
+}
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
+{
+ const unsigned char *s;
+ int i, n;
+
+ n = sig->length;
+ s = sig->data;
+ for (i = 0; i < n; i++) {
+ if ((i % 18) == 0) {
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return 0;
+ if (BIO_indent(bp, indent, indent) <= 0)
+ return 0;
+ }
+ if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
+ return 0;
+ }
+ if (BIO_write(bp, "\n", 1) != 1)
+ return 0;
+
+ return 1;
+}
+
+int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+ int sig_nid;
+ if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
+ return 0;
+ if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+ return 0;
+
+ sig_nid = OBJ_obj2nid(sigalg->algorithm);
+ if (sig_nid != NID_undef) {
+ int pkey_nid, dig_nid;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
+ ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+ if (ameth && ameth->sig_print)
+ return ameth->sig_print(bp, sigalg, sig, 9, 0);
+ }
+ }
+ if (sig)
+ return X509_signature_dump(bp, sig, 9);
+ else if (BIO_puts(bp, "\n") <= 0)
+ return 0;
+ return 1;
+}
+
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
+{
+ int i, n;
+ char buf[80];
+ const char *p;
+
+ if (v == NULL)
+ return (0);
+ n = 0;
+ p = (const char *)v->data;
+ for (i = 0; i < v->length; i++) {
+ if ((p[i] > '~') || ((p[i] < ' ') &&
+ (p[i] != '\n') && (p[i] != '\r')))
+ buf[n] = '.';
+ else
+ buf[n] = p[i];
+ n++;
+ if (n >= 80) {
+ if (BIO_write(bp, buf, n) <= 0)
+ return (0);
+ n = 0;
+ }
+ }
+ if (n > 0)
+ if (BIO_write(bp, buf, n) <= 0)
+ return (0);
+ return (1);
+}
+
+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)
+ return ASN1_GENERALIZEDTIME_print(bp, tm);
+ BIO_write(bp, "Bad time value", 14);
+ return (0);
+}
+
+static const char *mon[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
+{
+ char *v;
+ int gmt = 0;
+ int i;
+ int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+ char *f = NULL;
+ int f_len = 0;
+
+ i = tm->length;
+ v = (char *)tm->data;
+
+ if (i < 12)
+ goto err;
+ if (v[i - 1] == 'Z')
+ gmt = 1;
+ for (i = 0; i < 12; i++)
+ if ((v[i] > '9') || (v[i] < '0'))
+ goto err;
+ y = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+ + (v[2] - '0') * 10 + (v[3] - '0');
+ M = (v[4] - '0') * 10 + (v[5] - '0');
+ if ((M > 12) || (M < 1))
+ goto err;
+ d = (v[6] - '0') * 10 + (v[7] - '0');
+ h = (v[8] - '0') * 10 + (v[9] - '0');
+ m = (v[10] - '0') * 10 + (v[11] - '0');
+ if (tm->length >= 14 &&
+ (v[12] >= '0') && (v[12] <= '9') &&
+ (v[13] >= '0') && (v[13] <= '9')) {
+ s = (v[12] - '0') * 10 + (v[13] - '0');
+ /* Check for fractions of seconds. */
+ if (tm->length >= 15 && v[14] == '.') {
+ int l = tm->length;
+ f = &v[14]; /* The decimal point. */
+ f_len = 1;
+ while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
+ ++f_len;
+ }
+ }
+
+ if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+ mon[M - 1], d, h, m, s, f_len, f, y,
+ (gmt) ? " GMT" : "") <= 0)
+ return (0);
+ else
+ return (1);
+ err:
+ BIO_write(bp, "Bad time value", 14);
+ return (0);
+}
+
+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
+{
+ 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 = (const char *)tm->data;
+
+ if (i < 10)
+ goto err;
+ if (v[i - 1] == 'Z')
+ gmt = 1;
+ for (i = 0; i < 10; i++)
+ if ((v[i] > '9') || (v[i] < '0'))
+ goto err;
+ y = (v[0] - '0') * 10 + (v[1] - '0');
+ if (y < 50)
+ y += 100;
+ M = (v[2] - '0') * 10 + (v[3] - '0');
+ if ((M > 12) || (M < 1))
+ goto err;
+ d = (v[4] - '0') * 10 + (v[5] - '0');
+ h = (v[6] - '0') * 10 + (v[7] - '0');
+ m = (v[8] - '0') * 10 + (v[9] - '0');
+ if (tm->length >= 12 &&
+ (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
+ s = (v[10] - '0') * 10 + (v[11] - '0');
+
+ if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+ mon[M - 1], d, h, m, s, y + 1900,
+ (gmt) ? " GMT" : "") <= 0)
+ return (0);
+ else
+ return (1);
+ err:
+ BIO_write(bp, "Bad time value", 14);
+ return (0);
+}
+
+int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
+{
+ char *s, *c, *b;
+ int ret = 0, l, i;
+
+ l = 80 - 2 - obase;
+
+ b = X509_NAME_oneline(name, NULL, 0);
+ if (!b)
+ return 0;
+ if (!*b) {
+ OPENSSL_free(b);
+ return 1;
+ }
+ s = b + 1; /* skip the first slash */
+
+ c = s;
+ for (;;) {
+#ifndef CHARSET_EBCDIC
+ if (((*s == '/') &&
+ ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
+ ((s[2] >= 'A')
+ && (s[2] <= 'Z')
+ && (s[3] == '='))
+ ))) || (*s == '\0'))
+#else
+ if (((*s == '/') &&
+ (isupper(s[1]) && ((s[2] == '=') ||
+ (isupper(s[2]) && (s[3] == '='))
+ ))) || (*s == '\0'))
+#endif
+ {
+ i = s - c;
+ if (BIO_write(bp, c, i) != i)
+ goto err;
+ c = s + 1; /* skip following slash */
+ if (*s != '\0') {
+ if (BIO_write(bp, ", ", 2) != 2)
+ goto err;
+ }
+ l--;
+ }
+ if (*s == '\0')
+ break;
+ s++;
+ l--;
+ }
+
+ ret = 1;
+ if (0) {
+ err:
+ X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
+ }
+ OPENSSL_free(b);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_x509a.c b/Cryptlib/OpenSSL/crypto/asn1/t_x509a.c
new file mode 100644
index 00000000..f4b8f94c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_x509a.c
@@ -0,0 +1,115 @@
+/* t_x509a.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+/*
+ * X509_CERT_AUX and string set routines
+ */
+
+int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
+{
+ char oidstr[80], first;
+ int i;
+ if (!aux)
+ return 1;
+ if (aux->trust) {
+ first = 1;
+ BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof oidstr,
+ sk_ASN1_OBJECT_value(aux->trust, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+ if (aux->reject) {
+ first = 1;
+ BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof oidstr,
+ sk_ASN1_OBJECT_value(aux->reject, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+ if (aux->alias)
+ BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data);
+ if (aux->keyid) {
+ BIO_printf(out, "%*sKey Id: ", indent, "");
+ for (i = 0; i < aux->keyid->length; i++)
+ BIO_printf(out, "%s%02X", i ? ":" : "", aux->keyid->data[i]);
+ BIO_write(out, "\n", 1);
+ }
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
new file mode 100644
index 00000000..6bdcd5c5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
@@ -0,0 +1,1227 @@
+/* tasn_dec.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 <stddef.h>
+#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static int asn1_check_eoc(const unsigned char **in, long len);
+static int asn1_find_end(const unsigned char **in, long len, char inf);
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+ char inf, int tag, int aclass, int depth);
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+ char *inf, char *cst,
+ const unsigned char **in, long len,
+ int exptag, int expclass, char opt, ASN1_TLC *ctx);
+
+static int asn1_template_ex_d2i(ASN1_VALUE **pval,
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx);
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx);
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt,
+ ASN1_TLC *ctx);
+
+/* Table to convert tags to bit values, used for MSTRING type */
+static const unsigned long tag2bit[32] = {
+ /* tags 0 - 3 */
+ 0, 0, 0, B_ASN1_BIT_STRING,
+ /* tags 4- 7 */
+ B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
+ /* tags 8-11 */
+ B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
+ /* tags 12-15 */
+ B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
+ /* tags 16-19 */
+ B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
+ /* tags 20-22 */
+ B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
+ /* tags 23-24 */
+ B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
+ /* tags 25-27 */
+ B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
+ /* tags 28-31 */
+ B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
+};
+
+unsigned long ASN1_tag2bit(int tag)
+{
+ if ((tag < 0) || (tag > 30))
+ return 0;
+ return tag2bit[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 a buffer to read the data from, in future we
+ * will have more advanced versions that can input data a piece at a time and
+ * this will simply be a special case.
+ */
+
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it)
+{
+ ASN1_TLC c;
+ ASN1_VALUE *ptmpval = NULL;
+ if (!pval)
+ pval = &ptmpval;
+ asn1_tlc_clear_nc(&c);
+ if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+ return *pval;
+ return NULL;
+}
+
+int ASN1_template_d2i(ASN1_VALUE **pval,
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt)
+{
+ ASN1_TLC c;
+ asn1_tlc_clear_nc(&c);
+ return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+}
+
+/*
+ * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
+ * tag mismatch return -1 to handle OPTIONAL
+ */
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ const ASN1_TEMPLATE *tt, *errtt = NULL;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ const unsigned char *p = NULL, *q;
+ unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */
+ unsigned char imphack = 0, oclass;
+ char seq_eoc, seq_nolen, cst, isopt;
+ long tmplen;
+ int i;
+ int otag;
+ int ret = 0;
+ ASN1_VALUE **pchptr, *ptmpval;
+ int combine = aclass & ASN1_TFLG_COMBINE;
+ aclass &= ~ASN1_TFLG_COMBINE;
+ if (!pval)
+ return 0;
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+ else
+ asn1_cb = 0;
+
+ switch (it->itype) {
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates) {
+ /*
+ * tagging or OPTIONAL is currently illegal on an item template
+ * because the flags can't get passed down. In practice this
+ * isn't a problem: we include the relevant flags from the item
+ * template in the template itself.
+ */
+ if ((tag != -1) || opt) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+ ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+ goto err;
+ }
+ return asn1_template_ex_d2i(pval, in, len,
+ it->templates, opt, ctx);
+ }
+ return asn1_d2i_ex_primitive(pval, in, len, it,
+ tag, aclass, opt, ctx);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ p = *in;
+ /* Just read in tag and class */
+ ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+ &p, len, -1, 0, 1, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+
+ /* Must be UNIVERSAL class */
+ if (oclass != V_ASN1_UNIVERSAL) {
+ /* If OPTIONAL, assume this is OK */
+ if (opt)
+ return -1;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
+ goto err;
+ }
+ /* Check tag matches bit map */
+ if (!(ASN1_tag2bit(otag) & it->utype)) {
+ /* If OPTIONAL, assume this is OK */
+ if (opt)
+ return -1;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG);
+ goto err;
+ }
+ return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
+
+ case ASN1_ITYPE_EXTERN:
+ /* Use new style d2i */
+ ef = it->funcs;
+ return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+
+ case ASN1_ITYPE_COMPAT:
+ /* we must resort to old style evil hackery */
+ cf = it->funcs;
+
+ /* If OPTIONAL see if it is there */
+ if (opt) {
+ int exptag;
+ p = *in;
+ if (tag == -1)
+ exptag = it->utype;
+ else
+ exptag = tag;
+ /*
+ * Don't care about anything other than presence of expected tag
+ */
+
+ ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
+ &p, len, exptag, aclass, 1, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if (ret == -1)
+ return -1;
+ }
+
+ /*
+ * This is the old style evil hack IMPLICIT handling: since the
+ * underlying code is expecting a tag and class other than the one
+ * present we change the buffer temporarily then change it back
+ * afterwards. This doesn't and never did work for tags > 30. Yes
+ * this is *horrible* but it is only needed for old style d2i which
+ * will hopefully not be around for much longer. FIXME: should copy
+ * the buffer then modify it so the input buffer can be const: we
+ * should *always* copy because the old style d2i might modify the
+ * buffer.
+ */
+
+ if (tag != -1) {
+ wp = *(unsigned char **)in;
+ imphack = *wp;
+ if (p == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
+ | it->utype);
+ }
+
+ ptmpval = cf->asn1_d2i(pval, in, len);
+
+ if (tag != -1)
+ *wp = imphack;
+
+ if (ptmpval)
+ return 1;
+
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+ goto auxerr;
+ if (*pval) {
+ /* Free up and zero CHOICE value if initialised */
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ tt = it->templates + i;
+ pchptr = asn1_get_field_ptr(pval, tt);
+ ASN1_template_free(pchptr, tt);
+ asn1_set_choice_selector(pval, -1, it);
+ }
+ } else if (!ASN1_item_ex_new(pval, it)) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ /* CHOICE type, try each possibility in turn */
+ p = *in;
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ pchptr = asn1_get_field_ptr(pval, tt);
+ /*
+ * We mark field as OPTIONAL so its absence can be recognised.
+ */
+ ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+ /* If field not present, try the next one */
+ if (ret == -1)
+ continue;
+ /* If positive return, read OK, break loop */
+ if (ret > 0)
+ break;
+ /* Otherwise must be an ASN1 parsing error */
+ errtt = tt;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+
+ /* Did we fall off the end without reading anything? */
+ if (i == it->tcount) {
+ /* If OPTIONAL, this is OK */
+ if (opt) {
+ /* Free and zero it */
+ ASN1_item_ex_free(pval, it);
+ return -1;
+ }
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+ goto err;
+ }
+
+ asn1_set_choice_selector(pval, i, it);
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+ goto auxerr;
+ *in = p;
+ return 1;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ case ASN1_ITYPE_SEQUENCE:
+ p = *in;
+ tmplen = len;
+
+ /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+ if (tag == -1) {
+ tag = V_ASN1_SEQUENCE;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ /* Get SEQUENCE length and update len, p */
+ ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+ &p, len, tag, aclass, opt, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if (ret == -1)
+ return -1;
+ if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
+ len = tmplen - (p - *in);
+ seq_nolen = 1;
+ }
+ /* If indefinite we don't do a length check */
+ else
+ seq_nolen = seq_eoc;
+ if (!cst) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+ goto err;
+ }
+
+ if (!*pval && !ASN1_item_ex_new(pval, it)) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+ goto auxerr;
+
+ /* Free up and zero any ADB found */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ if (tt->flags & ASN1_TFLG_ADB_MASK) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ }
+ }
+
+ /* Get each field entry */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ goto err;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* Have we ran out of data? */
+ if (!len)
+ break;
+ q = p;
+ if (asn1_check_eoc(&p, len)) {
+ if (!seq_eoc) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC);
+ goto err;
+ }
+ len -= p - q;
+ seq_eoc = 0;
+ q = p;
+ break;
+ }
+ /*
+ * This determines the OPTIONAL flag value. The field cannot be
+ * omitted if it is the last of a SEQUENCE and there is still
+ * data to be read. This isn't strictly necessary but it
+ * increases efficiency in some cases.
+ */
+ if (i == (it->tcount - 1))
+ isopt = 0;
+ else
+ isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+ /*
+ * attempt to read in field, allowing each to be OPTIONAL
+ */
+
+ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
+ if (!ret) {
+ errtt = seqtt;
+ goto err;
+ } else if (ret == -1) {
+ /*
+ * OPTIONAL component absent. Free and zero the field.
+ */
+ ASN1_template_free(pseqval, seqtt);
+ continue;
+ }
+ /* Update length */
+ len -= p - q;
+ }
+
+ /* Check for EOC if expecting one */
+ if (seq_eoc && !asn1_check_eoc(&p, len)) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ /* Check all data read */
+ if (!seq_nolen && len) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ /*
+ * If we get here we've got no more data in the SEQUENCE, however we
+ * may not have read all fields so check all remaining are OPTIONAL
+ * and clear any that are.
+ */
+ for (; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ goto err;
+ if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
+ ASN1_VALUE **pseqval;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ } else {
+ errtt = seqtt;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
+ goto err;
+ }
+ }
+ /* Save encoding */
+ if (!asn1_enc_save(pval, *in, p - *in, it))
+ goto auxerr;
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+ goto auxerr;
+ *in = p;
+ return 1;
+
+ default:
+ return 0;
+ }
+ auxerr:
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
+ err:
+ if (combine == 0)
+ ASN1_item_ex_free(pval, it);
+ if (errtt)
+ ERR_add_error_data(4, "Field=", errtt->field_name,
+ ", Type=", it->sname);
+ else
+ ERR_add_error_data(2, "Type=", it->sname);
+ return 0;
+}
+
+/*
+ * Templates are handled with two separate functions. One handles any
+ * EXPLICIT tag and the other handles the rest.
+ */
+
+static int asn1_template_ex_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long inlen,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx)
+{
+ int flags, aclass;
+ int ret;
+ long len;
+ const unsigned char *p, *q;
+ char exp_eoc;
+ if (!val)
+ return 0;
+ flags = tt->flags;
+ aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+ p = *in;
+
+ /* Check if EXPLICIT tag expected */
+ if (flags & ASN1_TFLG_EXPTAG) {
+ char cst;
+ /*
+ * Need to work out amount of data available to the inner content and
+ * where it starts: so read in EXPLICIT header to get the info.
+ */
+ ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+ &p, inlen, tt->tag, aclass, opt, ctx);
+ q = p;
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if (ret == -1)
+ return -1;
+ if (!cst) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+ ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+ return 0;
+ }
+ /* We've found the field so it can't be OPTIONAL now */
+ ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ /* We read the field in OK so update length */
+ len -= p - q;
+ if (exp_eoc) {
+ /* If NDEF we must have an EOC here */
+ if (!asn1_check_eoc(&p, len)) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ } else {
+ /*
+ * Otherwise we must hit the EXPLICIT tag end or its an error
+ */
+ if (len) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+ ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+ goto err;
+ }
+ }
+ } else
+ return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
+
+ *in = p;
+ return 1;
+
+ err:
+ ASN1_template_free(val, tt);
+ return 0;
+}
+
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx)
+{
+ int flags, aclass;
+ int ret;
+ const unsigned char *p, *q;
+ if (!val)
+ return 0;
+ flags = tt->flags;
+ aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+ p = *in;
+ q = p;
+
+ if (flags & ASN1_TFLG_SK_MASK) {
+ /* SET OF, SEQUENCE OF */
+ int sktag, skaclass;
+ char sk_eoc;
+ /* First work out expected inner tag value */
+ if (flags & ASN1_TFLG_IMPTAG) {
+ sktag = tt->tag;
+ skaclass = aclass;
+ } else {
+ skaclass = V_ASN1_UNIVERSAL;
+ if (flags & ASN1_TFLG_SET_OF)
+ sktag = V_ASN1_SET;
+ else
+ sktag = V_ASN1_SEQUENCE;
+ }
+ /* Get the tag */
+ ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+ &p, len, sktag, skaclass, opt, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if (ret == -1)
+ return -1;
+ if (!*val)
+ *val = (ASN1_VALUE *)sk_new_null();
+ else {
+ /*
+ * We've got a valid STACK: free up any items present
+ */
+ STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
+ ASN1_VALUE *vtmp;
+ while (sk_ASN1_VALUE_num(sktmp) > 0) {
+ vtmp = sk_ASN1_VALUE_pop(sktmp);
+ ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
+ }
+ }
+
+ if (!*val) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* Read as many items as we can */
+ while (len > 0) {
+ ASN1_VALUE *skfield;
+ q = p;
+ /* See if EOC found */
+ if (asn1_check_eoc(&p, len)) {
+ if (!sk_eoc) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+ ASN1_R_UNEXPECTED_EOC);
+ goto err;
+ }
+ len -= p - q;
+ sk_eoc = 0;
+ break;
+ }
+ skfield = NULL;
+ if (!ASN1_item_ex_d2i(&skfield, &p, len,
+ ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+ ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ len -= p - q;
+ if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ if (sk_eoc) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ } else if (flags & ASN1_TFLG_IMPTAG) {
+ /* IMPLICIT tagging */
+ ret = ASN1_item_ex_d2i(val, &p, len,
+ ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
+ ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if (ret == -1)
+ return -1;
+ } else {
+ /* Nothing special */
+ ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if (ret == -1)
+ return -1;
+ }
+
+ *in = p;
+ return 1;
+
+ err:
+ ASN1_template_free(val, tt);
+ return 0;
+}
+
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+ const unsigned char **in, long inlen,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ int ret = 0, utype;
+ long plen;
+ char cst, inf, free_cont = 0;
+ const unsigned char *p;
+ BUF_MEM buf = { 0, NULL, 0 };
+ const unsigned char *cont = NULL;
+ long len;
+ if (!pval) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
+ return 0; /* Should never happen */
+ }
+
+ if (it->itype == ASN1_ITYPE_MSTRING) {
+ utype = tag;
+ tag = -1;
+ } else
+ utype = it->utype;
+
+ if (utype == V_ASN1_ANY) {
+ /* If type is ANY need to figure out type from tag */
+ unsigned char oclass;
+ if (tag >= 0) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
+ return 0;
+ }
+ if (opt) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+ ASN1_R_ILLEGAL_OPTIONAL_ANY);
+ return 0;
+ }
+ p = *in;
+ ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+ &p, inlen, -1, 0, 0, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ if (oclass != V_ASN1_UNIVERSAL)
+ utype = V_ASN1_OTHER;
+ }
+ if (tag == -1) {
+ tag = utype;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ p = *in;
+ /* Check header */
+ ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+ &p, inlen, tag, aclass, opt, ctx);
+ if (!ret) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if (ret == -1)
+ return -1;
+ ret = 0;
+ /* SEQUENCE, SET and "OTHER" are left in encoded form */
+ if ((utype == V_ASN1_SEQUENCE)
+ || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
+ /*
+ * Clear context cache for type OTHER because the auto clear when we
+ * have a exact match wont work
+ */
+ if (utype == V_ASN1_OTHER) {
+ asn1_tlc_clear(ctx);
+ }
+ /* SEQUENCE and SET must be constructed */
+ else if (!cst) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+ ASN1_R_TYPE_NOT_CONSTRUCTED);
+ return 0;
+ }
+
+ cont = *in;
+ /* If indefinite length constructed find the real end */
+ if (inf) {
+ if (!asn1_find_end(&p, plen, inf))
+ goto err;
+ len = p - cont;
+ } else {
+ len = p - cont + plen;
+ p += plen;
+ }
+ } else if (cst) {
+ if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+ || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+ || utype == V_ASN1_ENUMERATED) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE);
+ return 0;
+ }
+
+ /* Free any returned 'buf' content */
+ free_cont = 1;
+ /*
+ * Should really check the internal tags are correct but some things
+ * may get this wrong. The relevant specs say that constructed string
+ * types should be OCTET STRINGs internally irrespective of the type.
+ * So instead just check for UNIVERSAL class and ignore the tag.
+ */
+ if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
+ goto err;
+ }
+ len = buf.length;
+ /* Append a final null to string */
+ if (!BUF_MEM_grow_clean(&buf, len + 1)) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ buf.data[len] = 0;
+ cont = (const unsigned char *)buf.data;
+ } else {
+ cont = p;
+ len = plen;
+ p += plen;
+ }
+
+ /* We now have content length and type: translate into a structure */
+ /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */
+ if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+ goto err;
+
+ *in = p;
+ ret = 1;
+ err:
+ if (free_cont && buf.data)
+ OPENSSL_free(buf.data);
+ return ret;
+}
+
+/* Translate ASN1 content octets into a structure */
+
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it)
+{
+ ASN1_VALUE **opval = NULL;
+ ASN1_STRING *stmp;
+ ASN1_TYPE *typ = NULL;
+ int ret = 0;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ ASN1_INTEGER **tint;
+ pf = it->funcs;
+
+ if (pf && pf->prim_c2i)
+ return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+ /* If ANY type clear type and set pointer to internal value */
+ if (it->utype == V_ASN1_ANY) {
+ if (!*pval) {
+ typ = ASN1_TYPE_new();
+ if (typ == NULL)
+ goto err;
+ *pval = (ASN1_VALUE *)typ;
+ } else
+ typ = (ASN1_TYPE *)*pval;
+
+ if (utype != typ->type)
+ ASN1_TYPE_set(typ, utype, NULL);
+ opval = pval;
+ pval = &typ->value.asn1_value;
+ }
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+ goto err;
+ break;
+
+ case V_ASN1_NULL:
+ if (len) {
+ ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)1;
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if (len != 1) {
+ ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+ goto err;
+ } else {
+ ASN1_BOOLEAN *tbool;
+ tbool = (ASN1_BOOLEAN *)pval;
+ *tbool = *cont;
+ }
+ break;
+
+ case V_ASN1_BIT_STRING:
+ if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+ goto err;
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_ENUMERATED:
+ tint = (ASN1_INTEGER **)pval;
+ if (!c2i_ASN1_INTEGER(tint, &cont, len))
+ goto err;
+ /* Fixup type to match the expected form */
+ (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ 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:
+ case V_ASN1_SET:
+ case V_ASN1_SEQUENCE:
+ default:
+ if (utype == V_ASN1_BMPSTRING && (len & 1)) {
+ ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+ goto err;
+ }
+ if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
+ ASN1err(ASN1_F_ASN1_EX_C2I,
+ ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+ goto err;
+ }
+ /* All based on ASN1_STRING and handled the same */
+ if (!*pval) {
+ stmp = ASN1_STRING_type_new(utype);
+ if (!stmp) {
+ ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)stmp;
+ } else {
+ stmp = (ASN1_STRING *)*pval;
+ stmp->type = utype;
+ }
+ /* If we've already allocated a buffer use it */
+ if (*free_cont) {
+ if (stmp->data)
+ OPENSSL_free(stmp->data);
+ stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+ stmp->length = len;
+ *free_cont = 0;
+ } else {
+ if (!ASN1_STRING_set(stmp, cont, len)) {
+ ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(stmp);
+ *pval = NULL;
+ goto err;
+ }
+ }
+ break;
+ }
+ /* If ASN1_ANY and NULL type fix up value */
+ if (typ && (utype == V_ASN1_NULL))
+ typ->value.ptr = NULL;
+
+ ret = 1;
+ err:
+ if (!ret) {
+ ASN1_TYPE_free(typ);
+ if (opval)
+ *opval = NULL;
+ }
+ return ret;
+}
+
+/*
+ * This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content. This
+ * is more efficient than calling asn1_collect because it does not recurse on
+ * each indefinite length header.
+ */
+
+static int asn1_find_end(const unsigned char **in, long len, char inf)
+{
+ int expected_eoc;
+ long plen;
+ const unsigned char *p = *in, *q;
+ /* If not indefinite length constructed just add length */
+ if (inf == 0) {
+ *in += len;
+ return 1;
+ }
+ expected_eoc = 1;
+ /*
+ * Indefinite length constructed form. Find the end when enough EOCs are
+ * found. If more indefinite length constructed headers are encountered
+ * increment the expected eoc count otherwise just skip to the end of the
+ * data.
+ */
+ while (len > 0) {
+ if (asn1_check_eoc(&p, len)) {
+ expected_eoc--;
+ if (expected_eoc == 0)
+ break;
+ len -= 2;
+ continue;
+ }
+ q = p;
+ /* Just read in a header: only care about the length */
+ if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+ -1, 0, 0, NULL)) {
+ ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ if (inf)
+ expected_eoc++;
+ else
+ p += plen;
+ len -= p - q;
+ }
+ if (expected_eoc) {
+ ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
+ return 0;
+ }
+ *in = p;
+ return 1;
+}
+
+/*
+ * This function collects the asn1 data from a constructred string type into
+ * a buffer. The values of 'in' and 'len' should refer to the contents of the
+ * constructed type and 'inf' should be set if it is indefinite length.
+ */
+
+#ifndef ASN1_MAX_STRING_NEST
+/*
+ * This determines how many levels of recursion are permitted in ASN1 string
+ * types. If it is not limited stack overflows can occur. If set to zero no
+ * recursion is allowed at all. Although zero should be adequate examples
+ * exist that require a value of 1. So 5 should be more than enough.
+ */
+# define ASN1_MAX_STRING_NEST 5
+#endif
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+ char inf, int tag, int aclass, int depth)
+{
+ const unsigned char *p, *q;
+ long plen;
+ char cst, ininf;
+ p = *in;
+ inf &= 1;
+ /*
+ * If no buffer and not indefinite length constructed just pass over the
+ * encoded data
+ */
+ if (!buf && !inf) {
+ *in += len;
+ return 1;
+ }
+ while (len > 0) {
+ q = p;
+ /* Check for EOC */
+ if (asn1_check_eoc(&p, len)) {
+ /*
+ * EOC is illegal outside indefinite length constructed form
+ */
+ if (!inf) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
+ return 0;
+ }
+ inf = 0;
+ break;
+ }
+
+ if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+ len, tag, aclass, 0, NULL)) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+
+ /* If indefinite length constructed update max length */
+ if (cst) {
+ if (depth >= ASN1_MAX_STRING_NEST) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
+ return 0;
+ }
+ if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
+ return 0;
+ } else if (plen && !collect_data(buf, &p, plen))
+ return 0;
+ len -= p - q;
+ }
+ if (inf) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
+ return 0;
+ }
+ *in = p;
+ return 1;
+}
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
+{
+ int len;
+ if (buf) {
+ len = buf->length;
+ if (!BUF_MEM_grow_clean(buf, len + plen)) {
+ ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(buf->data + len, *p, plen);
+ }
+ *p += plen;
+ return 1;
+}
+
+/* Check for ASN1 EOC and swallow it if found */
+
+static int asn1_check_eoc(const unsigned char **in, long len)
+{
+ const unsigned char *p;
+ if (len < 2)
+ return 0;
+ p = *in;
+ if (!p[0] && !p[1]) {
+ *in += 2;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
+ * length for indefinite length constructed form, we don't know the exact
+ * length but we can set an upper bound to the amount of data available minus
+ * the header length just read.
+ */
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+ char *inf, char *cst,
+ const unsigned char **in, long len,
+ int exptag, int expclass, char opt, ASN1_TLC *ctx)
+{
+ int i;
+ int ptag, pclass;
+ long plen;
+ const unsigned char *p, *q;
+ p = *in;
+ q = p;
+
+ if (ctx && ctx->valid) {
+ i = ctx->ret;
+ plen = ctx->plen;
+ pclass = ctx->pclass;
+ ptag = ctx->ptag;
+ p += ctx->hdrlen;
+ } else {
+ i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+ if (ctx) {
+ ctx->ret = i;
+ ctx->plen = plen;
+ ctx->pclass = pclass;
+ ctx->ptag = ptag;
+ ctx->hdrlen = p - q;
+ ctx->valid = 1;
+ /*
+ * If definite length, and no error, length + header can't exceed
+ * total amount of data available.
+ */
+ if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+ ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
+ asn1_tlc_clear(ctx);
+ return 0;
+ }
+ }
+ }
+
+ if (i & 0x80) {
+ ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
+ asn1_tlc_clear(ctx);
+ return 0;
+ }
+ if (exptag >= 0) {
+ if ((exptag != ptag) || (expclass != pclass)) {
+ /*
+ * If type is OPTIONAL, not an error: indicate missing type.
+ */
+ if (opt)
+ return -1;
+ asn1_tlc_clear(ctx);
+ ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
+ return 0;
+ }
+ /*
+ * We have a tag and class match: assume we are going to do something
+ * with it
+ */
+ asn1_tlc_clear(ctx);
+ }
+
+ if (i & 1)
+ plen = len - (p - q);
+
+ if (inf)
+ *inf = i & 1;
+
+ if (cst)
+ *cst = i & V_ASN1_CONSTRUCTED;
+
+ if (olen)
+ *olen = plen;
+
+ if (oclass)
+ *oclass = pclass;
+
+ if (otag)
+ *otag = ptag;
+
+ *in = p;
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
new file mode 100644
index 00000000..f7f83e56
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
@@ -0,0 +1,659 @@
+/* tasn_enc.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 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 <stddef.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass);
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+ int skcontlen, const ASN1_ITEM *item,
+ int do_sort, int iclass);
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_TEMPLATE *tt, int tag, int aclass);
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+ const ASN1_ITEM *it, int flags);
+
+/*
+ * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
+ * indefinite length constructed encoding, where appropriate
+ */
+
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+ const ASN1_ITEM *it)
+{
+ return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+}
+
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+{
+ return asn1_item_flags_i2d(val, out, it, 0);
+}
+
+/*
+ * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
+ * points to a buffer to output the data to. The new i2d has one additional
+ * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
+ * allocated and populated with the encoding.
+ */
+
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+ const ASN1_ITEM *it, int flags)
+{
+ if (out && !*out) {
+ unsigned char *p, *buf;
+ int len;
+ len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+ if (len <= 0)
+ return len;
+ buf = OPENSSL_malloc(len);
+ if (!buf)
+ return -1;
+ p = buf;
+ ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+ *out = buf;
+ return len;
+ }
+
+ return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+}
+
+/*
+ * Encode an item, taking care of IMPLICIT tagging (if any). This function
+ * performs the normal item handling: it can be used in external types.
+ */
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass)
+{
+ const ASN1_TEMPLATE *tt = NULL;
+ unsigned char *p = NULL;
+ int i, seqcontlen, seqlen, ndef = 1;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb = 0;
+
+ if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+ return 0;
+
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates)
+ return asn1_template_ex_i2d(pval, out, it->templates,
+ tag, aclass);
+ return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ 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, NULL))
+ return 0;
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ ASN1_VALUE **pchval;
+ const ASN1_TEMPLATE *chtt;
+ chtt = it->templates + i;
+ pchval = asn1_get_field_ptr(pval, chtt);
+ return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
+ }
+ /* Fixme: error condition if selector out of range */
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+ return 0;
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ /* If new style i2d it does all the work */
+ ef = it->funcs;
+ return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+
+ case ASN1_ITYPE_COMPAT:
+ /* old style hackery... */
+ cf = it->funcs;
+ if (out)
+ p = *out;
+ i = cf->asn1_i2d(*pval, out);
+ /*
+ * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so
+ * did the old code. Tags > 30 are very rare anyway.
+ */
+ if (out && (tag != -1))
+ *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
+ return i;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ /* Use indefinite length constructed if requested */
+ if (aclass & ASN1_TFLG_NDEF)
+ ndef = 2;
+ /* fall through */
+
+ case ASN1_ITYPE_SEQUENCE:
+ i = asn1_enc_restore(&seqcontlen, out, pval, it);
+ /* An error occurred */
+ if (i < 0)
+ return 0;
+ /* We have a valid cached encoding... */
+ if (i > 0)
+ return seqcontlen;
+ /* Otherwise carry on */
+ seqcontlen = 0;
+ /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+ if (tag == -1) {
+ tag = V_ASN1_SEQUENCE;
+ /* Retain any other flags in aclass */
+ aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
+ | V_ASN1_UNIVERSAL;
+ }
+ 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++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ return 0;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* FIXME: check for errors in enhanced version */
+ seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
+ -1, aclass);
+ }
+
+ seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+ if (!out)
+ return seqlen;
+ /* Output SEQUENCE header */
+ ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ return 0;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* FIXME: check for errors in enhanced version */
+ asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+ }
+ if (ndef == 2)
+ ASN1_put_eoc(out);
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+ return 0;
+ return seqlen;
+
+ default:
+ return 0;
+
+ }
+ return 0;
+}
+
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_TEMPLATE *tt)
+{
+ return asn1_template_ex_i2d(pval, out, tt, -1, 0);
+}
+
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_TEMPLATE *tt, int tag, int iclass)
+{
+ int i, ret, flags, ttag, tclass, ndef;
+ flags = tt->flags;
+ /*
+ * Work out tag and class to use: tagging may come either from the
+ * template or the arguments, not both because this would create
+ * ambiguity. Additionally the iclass argument may contain some
+ * additional flags which should be noted and passed down to other
+ * levels.
+ */
+ if (flags & ASN1_TFLG_TAG_MASK) {
+ /* Error if argument and template tagging */
+ if (tag != -1)
+ /* FIXME: error code here */
+ return -1;
+ /* Get tagging from template */
+ ttag = tt->tag;
+ tclass = flags & ASN1_TFLG_TAG_CLASS;
+ } else if (tag != -1) {
+ /* No template tagging, get from arguments */
+ ttag = tag;
+ tclass = iclass & ASN1_TFLG_TAG_CLASS;
+ } else {
+ ttag = -1;
+ tclass = 0;
+ }
+ /*
+ * Remove any class mask from iflag.
+ */
+ iclass &= ~ASN1_TFLG_TAG_CLASS;
+
+ /*
+ * At this point 'ttag' contains the outer tag to use, 'tclass' is the
+ * class and iclass is any flags passed to this function.
+ */
+
+ /* if template and arguments require ndef, use it */
+ if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+ ndef = 2;
+ else
+ ndef = 1;
+
+ if (flags & ASN1_TFLG_SK_MASK) {
+ /* SET OF, SEQUENCE OF */
+ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+ int isset, sktag, skaclass;
+ int skcontlen, sklen;
+ ASN1_VALUE *skitem;
+
+ if (!*pval)
+ return 0;
+
+ if (flags & ASN1_TFLG_SET_OF) {
+ isset = 1;
+ /* 2 means we reorder */
+ if (flags & ASN1_TFLG_SEQUENCE_OF)
+ isset = 2;
+ } else
+ isset = 0;
+
+ /*
+ * Work out inner tag value: if EXPLICIT or no tagging use underlying
+ * type.
+ */
+ if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
+ sktag = ttag;
+ skaclass = tclass;
+ } else {
+ skaclass = V_ASN1_UNIVERSAL;
+ if (isset)
+ sktag = V_ASN1_SET;
+ else
+ sktag = V_ASN1_SEQUENCE;
+ }
+
+ /* Determine total length of items */
+ skcontlen = 0;
+ for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ skitem = sk_ASN1_VALUE_value(sk, i);
+ skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
+ ASN1_ITEM_ptr(tt->item),
+ -1, iclass);
+ }
+ sklen = ASN1_object_size(ndef, skcontlen, sktag);
+ /* If EXPLICIT need length of surrounding tag */
+ if (flags & ASN1_TFLG_EXPTAG)
+ ret = ASN1_object_size(ndef, sklen, ttag);
+ else
+ ret = sklen;
+
+ if (!out)
+ return ret;
+
+ /* Now encode this lot... */
+ /* EXPLICIT tag */
+ if (flags & ASN1_TFLG_EXPTAG)
+ ASN1_put_object(out, ndef, sklen, ttag, tclass);
+ /* SET or SEQUENCE and IMPLICIT tag */
+ ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+ /* And the stuff itself */
+ asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+ isset, iclass);
+ if (ndef == 2) {
+ ASN1_put_eoc(out);
+ if (flags & ASN1_TFLG_EXPTAG)
+ ASN1_put_eoc(out);
+ }
+
+ return ret;
+ }
+
+ if (flags & ASN1_TFLG_EXPTAG) {
+ /* EXPLICIT tagging */
+ /* Find length of tagged item */
+ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
+ if (!i)
+ return 0;
+ /* Find length of EXPLICIT tag */
+ ret = ASN1_object_size(ndef, i, ttag);
+ if (out) {
+ /* Output tag and item */
+ ASN1_put_object(out, ndef, i, ttag, tclass);
+ ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
+ if (ndef == 2)
+ ASN1_put_eoc(out);
+ }
+ return ret;
+ }
+
+ /* Either normal or IMPLICIT tagging: combine class and flags */
+ return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+ ttag, tclass | iclass);
+
+}
+
+/* Temporary structure used to hold DER encoding of items for SET OF */
+
+typedef struct {
+ unsigned char *data;
+ int length;
+ ASN1_VALUE *field;
+} DER_ENC;
+
+static int der_cmp(const void *a, const void *b)
+{
+ const DER_ENC *d1 = a, *d2 = b;
+ int cmplen, i;
+ cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+ i = memcmp(d1->data, d2->data, cmplen);
+ if (i)
+ return i;
+ return d1->length - d2->length;
+}
+
+/* Output the content octets of SET OF or SEQUENCE OF */
+
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+ int skcontlen, const ASN1_ITEM *item,
+ int do_sort, int iclass)
+{
+ int i;
+ ASN1_VALUE *skitem;
+ unsigned char *tmpdat = NULL, *p = NULL;
+ DER_ENC *derlst = NULL, *tder;
+ if (do_sort) {
+ /* Don't need to sort less than 2 items */
+ if (sk_ASN1_VALUE_num(sk) < 2)
+ do_sort = 0;
+ else {
+ derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+ * sizeof(*derlst));
+ if (!derlst)
+ return 0;
+ tmpdat = OPENSSL_malloc(skcontlen);
+ if (!tmpdat) {
+ OPENSSL_free(derlst);
+ return 0;
+ }
+ }
+ }
+ /* If not sorting just output each item */
+ if (!do_sort) {
+ for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ skitem = sk_ASN1_VALUE_value(sk, i);
+ ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+ }
+ return 1;
+ }
+ p = tmpdat;
+
+ /* Doing sort: build up a list of each member's DER encoding */
+ for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+ skitem = sk_ASN1_VALUE_value(sk, i);
+ tder->data = p;
+ tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+ tder->field = skitem;
+ }
+
+ /* Now sort them */
+ qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+ /* Output sorted DER encoding */
+ p = *out;
+ for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+ memcpy(p, tder->data, tder->length);
+ p += tder->length;
+ }
+ *out = p;
+ /* If do_sort is 2 then reorder the STACK */
+ if (do_sort == 2) {
+ for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+ (void)sk_ASN1_VALUE_set(sk, i, tder->field);
+ }
+ OPENSSL_free(derlst);
+ OPENSSL_free(tmpdat);
+ return 1;
+}
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass)
+{
+ int len;
+ int utype;
+ int usetag;
+ int ndef = 0;
+
+ utype = it->utype;
+
+ /*
+ * Get length of content octets and maybe find out the underlying type.
+ */
+
+ len = asn1_ex_i2c(pval, NULL, &utype, it);
+
+ /*
+ * If SEQUENCE, SET or OTHER then header is included in pseudo content
+ * octets so don't include tag+length. We need to check here because the
+ * call to asn1_ex_i2c() could change utype.
+ */
+ if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+ (utype == V_ASN1_OTHER))
+ usetag = 0;
+ else
+ usetag = 1;
+
+ /* -1 means omit type */
+
+ if (len == -1)
+ return 0;
+
+ /* -2 return is special meaning use ndef */
+ if (len == -2) {
+ ndef = 2;
+ len = 0;
+ }
+
+ /* If not implicitly tagged get tag from underlying type */
+ if (tag == -1)
+ tag = utype;
+
+ /* Output tag+length followed by content octets */
+ if (out) {
+ if (usetag)
+ ASN1_put_object(out, ndef, len, tag, aclass);
+ asn1_ex_i2c(pval, *out, &utype, it);
+ if (ndef)
+ ASN1_put_eoc(out);
+ else
+ *out += len;
+ }
+
+ if (usetag)
+ return ASN1_object_size(ndef, len, tag);
+ return len;
+}
+
+/* Produce content octets from a structure */
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+ const ASN1_ITEM *it)
+{
+ ASN1_BOOLEAN *tbool = NULL;
+ ASN1_STRING *strtmp;
+ ASN1_OBJECT *otmp;
+ int utype;
+ const unsigned char *cont;
+ unsigned char c;
+ int len;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if (pf && pf->prim_i2c)
+ return pf->prim_i2c(pval, cout, putype, it);
+
+ /* Should type be omitted? */
+ if ((it->itype != ASN1_ITYPE_PRIMITIVE)
+ || (it->utype != V_ASN1_BOOLEAN)) {
+ if (!*pval)
+ return -1;
+ }
+
+ if (it->itype == ASN1_ITYPE_MSTRING) {
+ /* If MSTRING type set the underlying type */
+ strtmp = (ASN1_STRING *)*pval;
+ utype = strtmp->type;
+ *putype = utype;
+ } else if (it->utype == V_ASN1_ANY) {
+ /* If ANY set type and pointer to value */
+ ASN1_TYPE *typ;
+ typ = (ASN1_TYPE *)*pval;
+ utype = typ->type;
+ *putype = utype;
+ pval = &typ->value.asn1_value;
+ } else
+ utype = *putype;
+
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ otmp = (ASN1_OBJECT *)*pval;
+ cont = otmp->data;
+ len = otmp->length;
+ break;
+
+ case V_ASN1_NULL:
+ cont = NULL;
+ len = 0;
+ break;
+
+ case V_ASN1_BOOLEAN:
+ tbool = (ASN1_BOOLEAN *)pval;
+ if (*tbool == -1)
+ return -1;
+ if (it->utype != V_ASN1_ANY) {
+ /*
+ * Default handling if value == size field then omit
+ */
+ if (*tbool && (it->size > 0))
+ return -1;
+ if (!*tbool && !it->size)
+ return -1;
+ }
+ c = (unsigned char)*tbool;
+ cont = &c;
+ len = 1;
+ break;
+
+ case V_ASN1_BIT_STRING:
+ return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+ cout ? &cout : NULL);
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_ENUMERATED:
+ /*
+ * These are all have the same content format as ASN1_INTEGER
+ */
+ return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ 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_SEQUENCE:
+ case V_ASN1_SET:
+ default:
+ /* All based on ASN1_STRING and handled the same */
+ strtmp = (ASN1_STRING *)*pval;
+ /* Special handling for NDEF */
+ if ((it->size == ASN1_TFLG_NDEF)
+ && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
+ if (cout) {
+ strtmp->data = cout;
+ strtmp->length = 0;
+ }
+ /* Special return code */
+ return -2;
+ }
+ cont = strtmp->data;
+ len = strtmp->length;
+
+ break;
+
+ }
+ if (cout && len)
+ memcpy(cout, cont, len);
+ return len;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c
new file mode 100644
index 00000000..aeea4eff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c
@@ -0,0 +1,249 @@
+/* tasn_fre.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int combine);
+
+/* Free up an ASN1 structure */
+
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+ asn1_item_combine_free(&val, it, 0);
+}
+
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ asn1_item_combine_free(pval, it, 0);
+}
+
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int combine)
+{
+ const ASN1_TEMPLATE *tt = NULL, *seqtt;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ int i;
+ if (!pval)
+ return;
+ if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+ return;
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+ else
+ asn1_cb = 0;
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates)
+ ASN1_template_free(pval, it->templates);
+ else
+ ASN1_primitive_free(pval, it);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ ASN1_primitive_free(pval, it);
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+ if (i == 2)
+ return;
+ }
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ ASN1_VALUE **pchval;
+ tt = it->templates + i;
+ pchval = asn1_get_field_ptr(pval, tt);
+ ASN1_template_free(pchval, tt);
+ }
+ if (asn1_cb)
+ asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+ if (!combine) {
+ OPENSSL_free(*pval);
+ *pval = NULL;
+ }
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ cf = it->funcs;
+ if (cf && cf->asn1_free)
+ cf->asn1_free(*pval);
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_free)
+ ef->asn1_ex_free(pval, it);
+ break;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ case ASN1_ITYPE_SEQUENCE:
+ if (asn1_do_lock(pval, -1, it) > 0)
+ return;
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+ if (i == 2)
+ return;
+ }
+ asn1_enc_free(pval, it);
+ /*
+ * If we free up as normal we will invalidate any ANY DEFINED BY
+ * field and we wont be able to determine the type of the field it
+ * defines. So free up in reverse order.
+ */
+ tt = it->templates + it->tcount - 1;
+ for (i = 0; i < it->tcount; tt--, i++) {
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 0);
+ if (!seqtt)
+ continue;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ }
+ if (asn1_cb)
+ asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+ if (!combine) {
+ OPENSSL_free(*pval);
+ *pval = NULL;
+ }
+ break;
+ }
+}
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ int i;
+ if (tt->flags & ASN1_TFLG_SK_MASK) {
+ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+ for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ ASN1_VALUE *vtmp;
+ vtmp = sk_ASN1_VALUE_value(sk, i);
+ asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0);
+ }
+ sk_ASN1_VALUE_free(sk);
+ *pval = NULL;
+ } else
+ asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
+ tt->flags & ASN1_TFLG_COMBINE);
+}
+
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ int utype;
+ if (it) {
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if (pf && pf->prim_free) {
+ pf->prim_free(pval, it);
+ return;
+ }
+ }
+ /* Special case: if 'it' is NULL free contents of ASN1_TYPE */
+ if (!it) {
+ ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+ utype = typ->type;
+ pval = &typ->value.asn1_value;
+ if (!*pval)
+ return;
+ } else if (it->itype == ASN1_ITYPE_MSTRING) {
+ utype = -1;
+ if (!*pval)
+ return;
+ } else {
+ utype = it->utype;
+ if ((utype != V_ASN1_BOOLEAN) && !*pval)
+ return;
+ }
+
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if (it)
+ *(ASN1_BOOLEAN *)pval = it->size;
+ else
+ *(ASN1_BOOLEAN *)pval = -1;
+ return;
+
+ case V_ASN1_NULL:
+ break;
+
+ case V_ASN1_ANY:
+ ASN1_primitive_free(pval, NULL);
+ OPENSSL_free(*pval);
+ break;
+
+ default:
+ ASN1_STRING_free((ASN1_STRING *)*pval);
+ *pval = NULL;
+ break;
+ }
+ *pval = NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c
new file mode 100644
index 00000000..b0c73bee
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c
@@ -0,0 +1,381 @@
+/* tasn_new.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 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 <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <string.h>
+
+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);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
+{
+ ASN1_VALUE *ret = NULL;
+ if (ASN1_item_ex_new(&ret, it) > 0)
+ return ret;
+ return NULL;
+}
+
+/* Allocate an ASN1 structure */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ return asn1_item_ex_combine_new(pval, it, 0);
+}
+
+static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int combine)
+{
+ const ASN1_TEMPLATE *tt = NULL;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ ASN1_VALUE **pseqval;
+ int i;
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+ else
+ asn1_cb = 0;
+
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_push_info(it->sname);
+#endif
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_new) {
+ if (!ef->asn1_ex_new(pval, it))
+ goto memerr;
+ }
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ cf = it->funcs;
+ if (cf && cf->asn1_new) {
+ *pval = cf->asn1_new();
+ if (!*pval)
+ goto memerr;
+ }
+ break;
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates) {
+ if (!ASN1_template_new(pval, it->templates))
+ goto memerr;
+ } else if (!ASN1_primitive_new(pval, it))
+ goto memerr;
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ if (!ASN1_primitive_new(pval, it))
+ goto memerr;
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+ if (!i)
+ goto auxerr;
+ if (i == 2) {
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_pop_info();
+#endif
+ return 1;
+ }
+ }
+ if (!combine) {
+ *pval = OPENSSL_malloc(it->size);
+ if (!*pval)
+ goto memerr;
+ memset(*pval, 0, it->size);
+ }
+ asn1_set_choice_selector(pval, -1, it);
+ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+ goto auxerr;
+ break;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ case ASN1_ITYPE_SEQUENCE:
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+ if (!i)
+ goto auxerr;
+ if (i == 2) {
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_pop_info();
+#endif
+ return 1;
+ }
+ }
+ if (!combine) {
+ *pval = OPENSSL_malloc(it->size);
+ if (!*pval)
+ goto memerr;
+ memset(*pval, 0, it->size);
+ asn1_do_lock(pval, 0, it);
+ asn1_enc_init(pval, it);
+ }
+ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ pseqval = asn1_get_field_ptr(pval, tt);
+ if (!ASN1_template_new(pseqval, tt))
+ goto memerr;
+ }
+ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+ goto auxerr;
+ break;
+ }
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_pop_info();
+#endif
+ return 1;
+
+ memerr:
+ ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_pop_info();
+#endif
+ return 0;
+
+ auxerr:
+ ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
+ ASN1_item_ex_free(pval, it);
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_pop_info();
+#endif
+ return 0;
+
+}
+
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ const ASN1_EXTERN_FUNCS *ef;
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_clear)
+ ef->asn1_ex_clear(pval, it);
+ else
+ *pval = NULL;
+ break;
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates)
+ asn1_template_clear(pval, it->templates);
+ else
+ asn1_primitive_clear(pval, it);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ asn1_primitive_clear(pval, it);
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ case ASN1_ITYPE_CHOICE:
+ case ASN1_ITYPE_SEQUENCE:
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ *pval = NULL;
+ break;
+ }
+}
+
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+ int ret;
+ if (tt->flags & ASN1_TFLG_OPTIONAL) {
+ asn1_template_clear(pval, tt);
+ return 1;
+ }
+ /* If ANY DEFINED BY nothing to do */
+
+ if (tt->flags & ASN1_TFLG_ADB_MASK) {
+ *pval = NULL;
+ return 1;
+ }
+#ifdef CRYPTO_MDEBUG
+ if (tt->field_name)
+ CRYPTO_push_info(tt->field_name);
+#endif
+ /* If SET OF or SEQUENCE OF, its a STACK */
+ if (tt->flags & ASN1_TFLG_SK_MASK) {
+ STACK_OF(ASN1_VALUE) *skval;
+ skval = sk_ASN1_VALUE_new_null();
+ if (!skval) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ goto done;
+ }
+ *pval = (ASN1_VALUE *)skval;
+ ret = 1;
+ goto done;
+ }
+ /* Otherwise pass it back to the item routine */
+ ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
+ done:
+#ifdef CRYPTO_MDEBUG
+ if (it->sname)
+ CRYPTO_pop_info();
+#endif
+ return ret;
+}
+
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ /* If ADB or STACK just NULL the field */
+ if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
+ *pval = NULL;
+ else
+ asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+}
+
+/*
+ * NB: could probably combine most of the real XXX_new() behaviour and junk
+ * all the old functions.
+ */
+
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ ASN1_TYPE *typ;
+ ASN1_STRING *str;
+ int utype;
+
+ if (!it)
+ return 0;
+
+ if (it->funcs) {
+ const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+ if (pf->prim_new)
+ return pf->prim_new(pval, it);
+ }
+
+ if (it->itype == ASN1_ITYPE_MSTRING)
+ utype = -1;
+ else
+ utype = it->utype;
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+ return 1;
+
+ case V_ASN1_BOOLEAN:
+ *(ASN1_BOOLEAN *)pval = it->size;
+ return 1;
+
+ case V_ASN1_NULL:
+ *pval = (ASN1_VALUE *)1;
+ return 1;
+
+ case V_ASN1_ANY:
+ typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
+ if (!typ)
+ return 0;
+ typ->value.ptr = NULL;
+ typ->type = -1;
+ *pval = (ASN1_VALUE *)typ;
+ break;
+
+ default:
+ 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)
+ return 1;
+ return 0;
+}
+
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ int utype;
+ if (it && it->funcs) {
+ const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+ if (pf->prim_clear)
+ pf->prim_clear(pval, it);
+ else
+ *pval = NULL;
+ return;
+ }
+ if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+ utype = -1;
+ else
+ utype = it->utype;
+ if (utype == V_ASN1_BOOLEAN)
+ *(ASN1_BOOLEAN *)pval = it->size;
+ else
+ *pval = NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c
new file mode 100644
index 00000000..5e7d53e9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c
@@ -0,0 +1,585 @@
+/* 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 <stddef.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#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, "<ABSENT>\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;
+ break;
+ }
+ /* 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);
+ if (!seqtt)
+ return 0;
+ 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<EMPTY>\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, int boolval,
+ const ASN1_PCTX *pctx)
+{
+ const char *str;
+ switch (boolval) {
+ 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 boolval = *(int *)fld;
+ if (boolval == -1)
+ boolval = it->size;
+ ret = asn1_print_boolean_ctx(out, boolval, 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/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c
new file mode 100644
index 00000000..740e86d5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c
@@ -0,0 +1,149 @@
+/* tasn_typ.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Declarations for string types */
+
+
+IMPLEMENT_ASN1_TYPE(ASN1_INTEGER)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER)
+
+IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_NULL)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
+
+IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
+
+IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_T61STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME)
+
+IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+
+IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_ANY)
+
+/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
+IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+/* Multistring types */
+
+IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+
+IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+
+/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
+IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
+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/Cryptlib/OpenSSL/crypto/asn1/tasn_utl.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_utl.c
new file mode 100644
index 00000000..41726d8f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_utl.c
@@ -0,0 +1,275 @@
+/* tasn_utl.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 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 <stddef.h>
+#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+
+/* Utility functions for manipulating fields and offsets */
+
+/* Add 'offset' to 'addr' */
+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+
+/*
+ * Given an ASN1_ITEM CHOICE type return the selector value
+ */
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ int *sel = offset2ptr(*pval, it->utype);
+ return *sel;
+}
+
+/*
+ * Given an ASN1_ITEM CHOICE type set the selector value, return old value.
+ */
+
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+ const ASN1_ITEM *it)
+{
+ int *sel, ret;
+ sel = offset2ptr(*pval, it->utype);
+ ret = *sel;
+ *sel = value;
+ return ret;
+}
+
+/*
+ * Do reference counting. The value 'op' decides what to do. if it is +1
+ * then the count is incremented. If op is 0 count is set to 1. If op is -1
+ * count is decremented and the return value is the current refrence count or
+ * 0 if no reference count exists.
+ */
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
+{
+ const ASN1_AUX *aux;
+ int *lck, ret;
+ if ((it->itype != ASN1_ITYPE_SEQUENCE)
+ && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
+ return 0;
+ aux = it->funcs;
+ if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
+ return 0;
+ lck = offset2ptr(*pval, aux->ref_offset);
+ if (op == 0) {
+ *lck = 1;
+ return 1;
+ }
+ ret = CRYPTO_add(lck, op, aux->ref_lock);
+#ifdef REF_PRINT
+ fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
+#endif
+#ifdef REF_CHECK
+ if (ret < 0)
+ fprintf(stderr, "%s, bad reference count\n", it->sname);
+#endif
+ return ret;
+}
+
+static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ const ASN1_AUX *aux;
+ if (!pval || !*pval)
+ return NULL;
+ aux = it->funcs;
+ if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
+ return NULL;
+ return offset2ptr(*pval, aux->enc_offset);
+}
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if (enc) {
+ enc->enc = NULL;
+ enc->len = 0;
+ enc->modified = 1;
+ }
+}
+
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if (enc) {
+ if (enc->enc)
+ OPENSSL_free(enc->enc);
+ enc->enc = NULL;
+ enc->len = 0;
+ enc->modified = 1;
+ }
+}
+
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+ const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if (!enc)
+ return 1;
+
+ if (enc->enc)
+ OPENSSL_free(enc->enc);
+ enc->enc = OPENSSL_malloc(inlen);
+ if (!enc->enc)
+ return 0;
+ memcpy(enc->enc, in, inlen);
+ enc->len = inlen;
+ enc->modified = 0;
+
+ return 1;
+}
+
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+ const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if (!enc || enc->modified)
+ return 0;
+ if (out) {
+ memcpy(*out, enc->enc, enc->len);
+ *out += enc->len;
+ }
+ if (len)
+ *len = enc->len;
+ return 1;
+}
+
+/* Given an ASN1_TEMPLATE get a pointer to a field */
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ ASN1_VALUE **pvaltmp;
+ if (tt->flags & ASN1_TFLG_COMBINE)
+ return pval;
+ pvaltmp = offset2ptr(*pval, tt->offset);
+ /*
+ * NOTE for BOOLEAN types the field is just a plain int so we can't
+ * return int **, so settle for (int *).
+ */
+ return pvaltmp;
+}
+
+/*
+ * Handle ANY DEFINED BY template, find the selector, look up the relevant
+ * ASN1_TEMPLATE in the table and return it.
+ */
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+ int nullerr)
+{
+ const ASN1_ADB *adb;
+ const ASN1_ADB_TABLE *atbl;
+ long selector;
+ ASN1_VALUE **sfld;
+ int i;
+ if (!(tt->flags & ASN1_TFLG_ADB_MASK))
+ return tt;
+
+ /* Else ANY DEFINED BY ... get the table */
+ adb = ASN1_ADB_ptr(tt->item);
+
+ /* Get the selector field */
+ sfld = offset2ptr(*pval, adb->offset);
+
+ /* Check if NULL */
+ if (!sfld) {
+ if (!adb->null_tt)
+ goto err;
+ return adb->null_tt;
+ }
+
+ /*
+ * Convert type to a long: NB: don't check for NID_undef here because it
+ * might be a legitimate value in the table
+ */
+ if (tt->flags & ASN1_TFLG_ADB_OID)
+ selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
+ else
+ selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
+
+ /*
+ * Try to find matching entry in table Maybe should check application
+ * types first to allow application override? Might also be useful to
+ * have a flag which indicates table is sorted and we can do a binary
+ * search. For now stick to a linear search.
+ */
+
+ for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
+ if (atbl->value == selector)
+ return &atbl->tt;
+
+ /* FIXME: need to search application table too */
+
+ /* No match, return default type */
+ if (!adb->default_tt)
+ goto err;
+ return adb->default_tt;
+
+ err:
+ /* FIXME: should log the value or OID of unsupported type */
+ if (nullerr)
+ ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_algor.c b/Cryptlib/OpenSSL/crypto/asn1/x_algor.c
new file mode 100644
index 00000000..fd7d16d4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_algor.c
@@ -0,0 +1,148 @@
+/* x_algor.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(X509_ALGOR) = {
+ ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
+ ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
+} ASN1_SEQUENCE_END(X509_ALGOR)
+
+ASN1_ITEM_TEMPLATE(X509_ALGORS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
+ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
+
+IMPLEMENT_STACK_OF(X509_ALGOR)
+IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
+
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
+{
+ if (!alg)
+ return 0;
+ if (ptype != V_ASN1_UNDEF) {
+ if (alg->parameter == NULL)
+ alg->parameter = ASN1_TYPE_new();
+ if (alg->parameter == NULL)
+ return 0;
+ }
+ if (alg) {
+ if (alg->algorithm)
+ ASN1_OBJECT_free(alg->algorithm);
+ alg->algorithm = aobj;
+ }
+ if (ptype == 0)
+ return 1;
+ if (ptype == V_ASN1_UNDEF) {
+ if (alg->parameter) {
+ ASN1_TYPE_free(alg->parameter);
+ alg->parameter = NULL;
+ }
+ } else
+ ASN1_TYPE_set(alg->parameter, ptype, pval);
+ return 1;
+}
+
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+ X509_ALGOR *algor)
+{
+ if (paobj)
+ *paobj = algor->algorithm;
+ if (pptype) {
+ if (algor->parameter == NULL) {
+ *pptype = V_ASN1_UNDEF;
+ return;
+ } else
+ *pptype = algor->parameter->type;
+ if (ppval)
+ *ppval = algor->parameter->value.ptr;
+ }
+}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
+{
+ int param_type;
+
+ if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+ param_type = V_ASN1_UNDEF;
+ else
+ param_type = V_ASN1_NULL;
+
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+}
+
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+{
+ int rv;
+ rv = OBJ_cmp(a->algorithm, b->algorithm);
+ if (rv)
+ return rv;
+ if (!a->parameter && !b->parameter)
+ return 0;
+ return ASN1_TYPE_cmp(a->parameter, b->parameter);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_attrib.c b/Cryptlib/OpenSSL/crypto/asn1/x_attrib.c
new file mode 100644
index 00000000..93ef53bd
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_attrib.c
@@ -0,0 +1,124 @@
+/* crypto/asn1/x_attrib.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/*-
+ * X509_ATTRIBUTE: this has the following form:
+ *
+ * typedef struct x509_attributes_st
+ * {
+ * ASN1_OBJECT *object;
+ * int single;
+ * union {
+ * char *ptr;
+ * STACK_OF(ASN1_TYPE) *set;
+ * ASN1_TYPE *single;
+ * } value;
+ * } X509_ATTRIBUTE;
+ *
+ * this needs some extra thought because the CHOICE type is
+ * merged with the main structure and because the value can
+ * be anything at all we *must* try the SET OF first because
+ * the ASN1_ANY type will swallow anything including the whole
+ * SET OF structure.
+ */
+
+ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
+ ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
+ ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
+} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
+
+ASN1_SEQUENCE(X509_ATTRIBUTE) = {
+ ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
+ /* CHOICE type merged with parent */
+ ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
+} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
+{
+ X509_ATTRIBUTE *ret = NULL;
+ ASN1_TYPE *val = NULL;
+
+ if ((ret = X509_ATTRIBUTE_new()) == NULL)
+ return (NULL);
+ ret->object = OBJ_nid2obj(nid);
+ ret->single = 0;
+ if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
+ goto err;
+ if ((val = ASN1_TYPE_new()) == NULL)
+ goto err;
+ if (!sk_ASN1_TYPE_push(ret->value.set, val))
+ goto err;
+
+ ASN1_TYPE_set(val, atrtype, value);
+ return (ret);
+ err:
+ if (ret != NULL)
+ X509_ATTRIBUTE_free(ret);
+ if (val != NULL)
+ ASN1_TYPE_free(val);
+ return (NULL);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_bignum.c b/Cryptlib/OpenSSL/crypto/asn1/x_bignum.c
new file mode 100644
index 00000000..eaf04663
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_bignum.c
@@ -0,0 +1,153 @@
+/* x_bignum.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/*
+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
+ * as a BIGNUM directly. Currently it ignores the sign which isn't a problem
+ * since all BIGNUMs used are non negative and anything that looks negative
+ * is normally due to an encoding error.
+ */
+
+#define BN_SENSITIVE 1
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it);
+
+static ASN1_PRIMITIVE_FUNCS bignum_pf = {
+ NULL, 0,
+ bn_new,
+ bn_free,
+ 0,
+ bn_c2i,
+ bn_i2c
+};
+
+ASN1_ITEM_start(BIGNUM)
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
+ASN1_ITEM_end(BIGNUM)
+
+ASN1_ITEM_start(CBIGNUM)
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
+ASN1_ITEM_end(CBIGNUM)
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ *pval = (ASN1_VALUE *)BN_new();
+ if (*pval)
+ return 1;
+ else
+ return 0;
+}
+
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ if (!*pval)
+ return;
+ if (it->size & BN_SENSITIVE)
+ BN_clear_free((BIGNUM *)*pval);
+ else
+ BN_free((BIGNUM *)*pval);
+ *pval = NULL;
+}
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it)
+{
+ BIGNUM *bn;
+ int pad;
+ if (!*pval)
+ return -1;
+ bn = (BIGNUM *)*pval;
+ /* If MSB set in an octet we need a padding byte */
+ if (BN_num_bits(bn) & 0x7)
+ pad = 0;
+ else
+ pad = 1;
+ if (cont) {
+ if (pad)
+ *cont++ = 0;
+ BN_bn2bin(bn, cont);
+ }
+ return pad + BN_num_bytes(bn);
+}
+
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it)
+{
+ BIGNUM *bn;
+
+ if (*pval == NULL && !bn_new(pval, it))
+ return 0;
+ bn = (BIGNUM *)*pval;
+ if (!BN_bin2bn(cont, len, bn)) {
+ bn_free(pval, it);
+ return 0;
+ }
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_crl.c b/Cryptlib/OpenSSL/crypto/asn1/x_crl.c
new file mode 100644
index 00000000..02795033
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_crl.c
@@ -0,0 +1,517 @@
+/* crypto/asn1/x_crl.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include "asn1_locl.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+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),
+ ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+ 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,
+ void *exarg)
+{
+ X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+ if (!a || !a->revoked)
+ return 1;
+ switch (operation) {
+ /*
+ * Just set cmp function here. We don't sort because that would
+ * affect the output of X509_CRL_print().
+ */
+ case ASN1_OP_D2I_POST:
+ (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+ break;
+ }
+ return 1;
+}
+
+
+ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
+ ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+ ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+ ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+ ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
+
+/*
+ * 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_authority_key_identifier)
+ || (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)
+} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
+
+static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
+ const X509_REVOKED *const *b)
+{
+ return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber,
+ (ASN1_STRING *)(*b)->serialNumber));
+}
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
+{
+ X509_CRL_INFO *inf;
+ inf = crl->crl;
+ if (!inf->revoked)
+ inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+ if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+ ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ inf->enc.modified = 1;
+ 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)
+
+IMPLEMENT_ASN1_SET_OF(X509_CRL)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_exten.c b/Cryptlib/OpenSSL/crypto/asn1/x_exten.c
new file mode 100644
index 00000000..00a9580a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_exten.c
@@ -0,0 +1,77 @@
+/* x_exten.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(X509_EXTENSION) = {
+ ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+ ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+ ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_EXTENSION)
+
+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
+ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_info.c b/Cryptlib/OpenSSL/crypto/asn1/x_info.c
new file mode 100644
index 00000000..067fd72a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_info.c
@@ -0,0 +1,117 @@
+/* crypto/asn1/x_info.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+X509_INFO *X509_INFO_new(void)
+{
+ X509_INFO *ret = NULL;
+
+ ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
+ if (ret == NULL) {
+ ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ ret->enc_cipher.cipher = NULL;
+ ret->enc_len = 0;
+ ret->enc_data = NULL;
+
+ ret->references = 1;
+ ret->x509 = NULL;
+ ret->crl = NULL;
+ ret->x_pkey = NULL;
+ return (ret);
+}
+
+void X509_INFO_free(X509_INFO *x)
+{
+ int i;
+
+ if (x == NULL)
+ return;
+
+ i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO);
+#ifdef REF_PRINT
+ REF_PRINT("X509_INFO", x);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "X509_INFO_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if (x->x509 != NULL)
+ X509_free(x->x509);
+ if (x->crl != NULL)
+ X509_CRL_free(x->crl);
+ if (x->x_pkey != NULL)
+ X509_PKEY_free(x->x_pkey);
+ if (x->enc_data != NULL)
+ OPENSSL_free(x->enc_data);
+ OPENSSL_free(x);
+}
+
+IMPLEMENT_STACK_OF(X509_INFO)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_long.c b/Cryptlib/OpenSSL/crypto/asn1/x_long.c
new file mode 100644
index 00000000..3aed44a3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_long.c
@@ -0,0 +1,196 @@
+/* x_long.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/*
+ * Custom primitive type for long handling. This converts between an
+ * ASN1_INTEGER and a long directly.
+ */
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+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,
+ long_new,
+ long_free,
+ long_free, /* Clear should set to initial value */
+ long_c2i,
+ long_i2c,
+ long_print
+};
+
+ASN1_ITEM_start(LONG)
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
+ASN1_ITEM_end(LONG)
+
+ASN1_ITEM_start(ZLONG)
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
+ASN1_ITEM_end(ZLONG)
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ *(long *)pval = it->size;
+ return 1;
+}
+
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ *(long *)pval = it->size;
+}
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it)
+{
+ long ltmp;
+ unsigned long utmp;
+ int clen, pad, i;
+ /* this exists to bypass broken gcc optimization */
+ char *cp = (char *)pval;
+
+ /* use memcpy, because we may not be long aligned */
+ memcpy(&ltmp, cp, sizeof(long));
+
+ if (ltmp == it->size)
+ return -1;
+ /*
+ * Convert the long to positive: we subtract one if negative so we can
+ * cleanly handle the padding if only the MSB of the leading octet is
+ * set.
+ */
+ if (ltmp < 0)
+ utmp = -ltmp - 1;
+ else
+ utmp = ltmp;
+ clen = BN_num_bits_word(utmp);
+ /* If MSB of leading octet set we need to pad */
+ if (!(clen & 0x7))
+ pad = 1;
+ else
+ pad = 0;
+
+ /* Convert number of bits to number of octets */
+ clen = (clen + 7) >> 3;
+
+ if (cont) {
+ if (pad)
+ *cont++ = (ltmp < 0) ? 0xff : 0;
+ for (i = clen - 1; i >= 0; i--) {
+ cont[i] = (unsigned char)(utmp & 0xff);
+ if (ltmp < 0)
+ cont[i] ^= 0xff;
+ utmp >>= 8;
+ }
+ }
+ return clen + pad;
+}
+
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it)
+{
+ int neg, i;
+ long ltmp;
+ unsigned long utmp = 0;
+ char *cp = (char *)pval;
+ if (len > (int)sizeof(long)) {
+ ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ return 0;
+ }
+ /* Is it negative? */
+ if (len && (cont[0] & 0x80))
+ neg = 1;
+ else
+ neg = 0;
+ utmp = 0;
+ for (i = 0; i < len; i++) {
+ utmp <<= 8;
+ if (neg)
+ utmp |= cont[i] ^ 0xff;
+ else
+ utmp |= cont[i];
+ }
+ ltmp = (long)utmp;
+ if (neg) {
+ ltmp++;
+ ltmp = -ltmp;
+ }
+ if (ltmp == it->size) {
+ ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ return 0;
+ }
+ memcpy(cp, &ltmp, 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/Cryptlib/OpenSSL/crypto/asn1/x_name.c b/Cryptlib/OpenSSL/crypto/asn1/x_name.c
new file mode 100644
index 00000000..a858c299
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_name.c
@@ -0,0 +1,538 @@
+/* crypto/asn1/x_name.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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+
+/*
+ * Maximum length of X509_NAME: much larger than anything we should
+ * ever see in practice.
+ */
+
+#define X509_NAME_MAX (1024 * 1024)
+
+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),
+ ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
+} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
+
+/*
+ * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
+ * declare two template wrappers for this
+ */
+
+ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
+ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
+
+ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
+ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
+
+/*
+ * Normally that's where it would end: we'd have two nested STACK structures
+ * representing the ASN1. Unfortunately X509_NAME uses a completely different
+ * form and caches encodings so we have to process the internal form and
+ * convert to the external form.
+ */
+
+const ASN1_EXTERN_FUNCS x509_name_ff = {
+ NULL,
+ x509_name_ex_new,
+ x509_name_ex_free,
+ 0, /* Default clear behaviour is OK */
+ x509_name_ex_d2i,
+ x509_name_ex_i2d,
+ x509_name_ex_print
+};
+
+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
+
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
+{
+ X509_NAME *ret = NULL;
+ ret = OPENSSL_malloc(sizeof(X509_NAME));
+ if (!ret)
+ goto memerr;
+ 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;
+
+ memerr:
+ ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
+ if (ret) {
+ if (ret->entries)
+ sk_X509_NAME_ENTRY_free(ret->entries);
+ OPENSSL_free(ret);
+ }
+ return 0;
+}
+
+static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ X509_NAME *a;
+ if (!pval || !*pval)
+ return;
+ a = (X509_NAME *)*pval;
+
+ 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;
+}
+
+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_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;
+ X509_NAME_ENTRY *entry;
+ if (len > X509_NAME_MAX) {
+ ASN1err(ASN1_F_X509_NAME_EX_D2I, ASN1_R_TOO_LONG);
+ return 0;
+ }
+ q = p;
+
+ /* Get internal representation of Name */
+ ret = ASN1_item_ex_d2i(&intname.a,
+ &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+ tag, aclass, opt, ctx);
+
+ if (ret <= 0)
+ return ret;
+
+ if (*val)
+ x509_name_ex_free(val, NULL);
+ if (!x509_name_ex_new(&nm.a, NULL))
+ goto err;
+ /* We've decoded it: now cache encoding */
+ if (!BUF_MEM_grow(nm.x->bytes, p - q))
+ goto err;
+ memcpy(nm.x->bytes->data, q, p - q);
+
+ /* Convert internal representation to X509_NAME structure */
+ 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;
+ if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+ goto err;
+ }
+ sk_X509_NAME_ENTRY_free(entries);
+ }
+ 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;
+ return ret;
+ err:
+ if (nm.x != NULL)
+ X509_NAME_free(nm.x);
+ ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+}
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass)
+{
+ int ret;
+ X509_NAME *a = (X509_NAME *)*val;
+ if (a->modified) {
+ 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) {
+ memcpy(*out, a->bytes->data, ret);
+ *out += ret;
+ }
+ 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_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_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_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
+ goto memerr;
+ set = entry->set;
+ }
+ if (!sk_X509_NAME_ENTRY_push(entries, entry))
+ goto memerr;
+ }
+ len = ASN1_item_ex_i2d(&intname.a, NULL,
+ ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+ if (!BUF_MEM_grow(a->bytes, len))
+ goto memerr;
+ p = (unsigned char *)a->bytes->data;
+ ASN1_item_ex_i2d(&intname.a,
+ &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
+ a->modified = 0;
+ return len;
+ 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();
+ if (!tmpentry)
+ goto err;
+ 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)) {
+ if (!ASN1_STRING_copy(out, in))
+ 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);
+ 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)
+{
+ X509_NAME *in;
+
+ if (!xn || !name)
+ return (0);
+
+ if (*xn != name) {
+ in = X509_NAME_dup(name);
+ if (in != NULL) {
+ X509_NAME_free(*xn);
+ *xn = in;
+ }
+ }
+ return (*xn != NULL);
+}
+
+IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
+
+IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_nx509.c b/Cryptlib/OpenSSL/crypto/asn1/x_nx509.c
new file mode 100644
index 00000000..5aa0ed58
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_nx509.c
@@ -0,0 +1,72 @@
+/* x_nx509.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 <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* 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/Cryptlib/OpenSSL/crypto/asn1/x_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/x_pkey.c
new file mode 100644
index 00000000..2da23e47
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_pkey.c
@@ -0,0 +1,153 @@
+/* crypto/asn1/x_pkey.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+
+/* need to implement */
+int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp)
+{
+ return (0);
+}
+
+X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length)
+{
+ int i;
+ M_ASN1_D2I_vars(a, X509_PKEY *, X509_PKEY_new);
+
+ M_ASN1_D2I_Init();
+ M_ASN1_D2I_start_sequence();
+ M_ASN1_D2I_get_x(X509_ALGOR, ret->enc_algor, d2i_X509_ALGOR);
+ M_ASN1_D2I_get_x(ASN1_OCTET_STRING, ret->enc_pkey, d2i_ASN1_OCTET_STRING);
+
+ ret->cipher.cipher =
+ EVP_get_cipherbyname(OBJ_nid2ln
+ (OBJ_obj2nid(ret->enc_algor->algorithm)));
+ if (ret->cipher.cipher == NULL) {
+ c.error = ASN1_R_UNSUPPORTED_CIPHER;
+ c.line = __LINE__;
+ goto err;
+ }
+ if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) {
+ i = ret->enc_algor->parameter->value.octet_string->length;
+ if (i > EVP_MAX_IV_LENGTH) {
+ c.error = ASN1_R_IV_TOO_LARGE;
+ c.line = __LINE__;
+ goto err;
+ }
+ memcpy(ret->cipher.iv,
+ ret->enc_algor->parameter->value.octet_string->data, i);
+ } else
+ memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH);
+ M_ASN1_D2I_Finish(a, X509_PKEY_free, ASN1_F_D2I_X509_PKEY);
+}
+
+X509_PKEY *X509_PKEY_new(void)
+{
+ X509_PKEY *ret = NULL;
+ ASN1_CTX c;
+
+ M_ASN1_New_Malloc(ret, X509_PKEY);
+ ret->version = 0;
+ M_ASN1_New(ret->enc_algor, X509_ALGOR_new);
+ M_ASN1_New(ret->enc_pkey, M_ASN1_OCTET_STRING_new);
+ ret->dec_pkey = NULL;
+ ret->key_length = 0;
+ ret->key_data = NULL;
+ ret->key_free = 0;
+ ret->cipher.cipher = NULL;
+ memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH);
+ ret->references = 1;
+ return (ret);
+ M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
+}
+
+void X509_PKEY_free(X509_PKEY *x)
+{
+ int i;
+
+ if (x == NULL)
+ return;
+
+ i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_PKEY);
+#ifdef REF_PRINT
+ REF_PRINT("X509_PKEY", x);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "X509_PKEY_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if (x->enc_algor != NULL)
+ X509_ALGOR_free(x->enc_algor);
+ if (x->enc_pkey != NULL)
+ M_ASN1_OCTET_STRING_free(x->enc_pkey);
+ if (x->dec_pkey != NULL)
+ EVP_PKEY_free(x->dec_pkey);
+ if ((x->key_data != NULL) && (x->key_free))
+ OPENSSL_free(x->key_data);
+ OPENSSL_free(x);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c b/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c
new file mode 100644
index 00000000..6c57a797
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c
@@ -0,0 +1,374 @@
+/* crypto/asn1/x_pubkey.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ if (operation == ASN1_OP_FREE_POST) {
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
+{
+ X509_PUBKEY *pk = NULL;
+
+ if (x == NULL)
+ return (0);
+
+ if ((pk = X509_PUBKEY_new()) == NULL)
+ goto error;
+
+ if (pkey->ameth) {
+ if (pkey->ameth->pub_encode) {
+ if (!pkey->ameth->pub_encode(pk, pkey)) {
+ X509err(X509_F_X509_PUBKEY_SET,
+ X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
+
+ if (*x != NULL)
+ X509_PUBKEY_free(*x);
+
+ *x = pk;
+
+ return 1;
+ error:
+ if (pk != NULL)
+ X509_PUBKEY_free(pk);
+ return 0;
+}
+
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+{
+ EVP_PKEY *ret = NULL;
+
+ if (key == NULL)
+ goto error;
+
+ if (key->pkey != NULL) {
+ CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ return key->pkey;
+ }
+
+ if (key->public_key == NULL)
+ goto error;
+
+ if ((ret = EVP_PKEY_new()) == NULL) {
+ X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
+ goto error;
+ }
+
+ if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
+
+ if (ret->ameth->pub_decode) {
+ if (!ret->ameth->pub_decode(ret, key)) {
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+
+ /* Check to see if another thread set key->pkey first */
+ CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+ if (key->pkey) {
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+ EVP_PKEY_free(ret);
+ ret = key->pkey;
+ } else {
+ key->pkey = ret;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+ }
+ CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+ return ret;
+
+ error:
+ if (ret != NULL)
+ EVP_PKEY_free(ret);
+ return (NULL);
+}
+
+/*
+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
+ * decode as X509_PUBKEY
+ */
+
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+ X509_PUBKEY *xpk;
+ EVP_PKEY *pktmp;
+ const unsigned char *q;
+ q = *pp;
+ xpk = d2i_X509_PUBKEY(NULL, &q, length);
+ if (!xpk)
+ return NULL;
+ pktmp = X509_PUBKEY_get(xpk);
+ X509_PUBKEY_free(xpk);
+ if (!pktmp)
+ return NULL;
+ *pp = q;
+ if (a) {
+ EVP_PKEY_free(*a);
+ *a = pktmp;
+ }
+ return pktmp;
+}
+
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+{
+ X509_PUBKEY *xpk = NULL;
+ int ret;
+ if (!a)
+ return 0;
+ if (!X509_PUBKEY_set(&xpk, a))
+ return 0;
+ ret = i2d_X509_PUBKEY(xpk, pp);
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+/*
+ * The following are equivalents but which return RSA and DSA keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ RSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (!pktmp) {
+ ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ EVP_PKEY_set1_RSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ DSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ DSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (!pktmp) {
+ ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ EVP_PKEY_set1_DSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ EC_KEY *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return (NULL);
+ key = EVP_PKEY_get1_EC_KEY(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return (NULL);
+ *pp = q;
+ if (a) {
+ EC_KEY_free(*a);
+ *a = key;
+ }
+ return (key);
+}
+
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return (0);
+ if ((pktmp = EVP_PKEY_new()) == NULL) {
+ ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ EVP_PKEY_set1_EC_KEY(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ 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/Cryptlib/OpenSSL/crypto/asn1/x_req.c b/Cryptlib/OpenSSL/crypto/asn1/x_req.c
new file mode 100644
index 00000000..ae293aa0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_req.c
@@ -0,0 +1,116 @@
+/* crypto/asn1/x_req.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/*-
+ * X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK.
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
+
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+
+ if (operation == ASN1_OP_NEW_POST) {
+ rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+ if (!rinf->attributes)
+ return 0;
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
+ ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+ ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+ /* This isn't really OPTIONAL but it gets round invalid
+ * encodings
+ */
+ ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
+
+ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
+ ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
+ ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_sig.c b/Cryptlib/OpenSSL/crypto/asn1/x_sig.c
new file mode 100644
index 00000000..dd33720c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_sig.c
@@ -0,0 +1,69 @@
+/* crypto/asn1/x_sig.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+ASN1_SEQUENCE(X509_SIG) = {
+ ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_SIG)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_spki.c b/Cryptlib/OpenSSL/crypto/asn1/x_spki.c
new file mode 100644
index 00000000..1df6b87d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_spki.c
@@ -0,0 +1,82 @@
+/* crypto/asn1/x_spki.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.]
+ */
+
+ /*
+ * This module was send to me my Pat Richards <patr@x509.com> who wrote it.
+ * It is under my Copyright with his permission
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
+ ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
+ ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+
+ASN1_SEQUENCE(NETSCAPE_SPKI) = {
+ ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
+ ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
+ ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_val.c b/Cryptlib/OpenSSL/crypto/asn1/x_val.c
new file mode 100644
index 00000000..ee75a1e2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_val.c
@@ -0,0 +1,69 @@
+/* crypto/asn1/x_val.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+ASN1_SEQUENCE(X509_VAL) = {
+ ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
+ ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
+} ASN1_SEQUENCE_END(X509_VAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
new file mode 100644
index 00000000..e31e1e75
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
@@ -0,0 +1,239 @@
+/* crypto/asn1/x_x509.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
+ ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+ ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
+ ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+ ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
+ ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+ ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+ ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+ ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
+/* X509 top level structure needs a bit of customisation */
+
+extern void policy_cache_free(X509_POLICY_CACHE *cache);
+
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509 *ret = (X509 *)*pval;
+
+ switch (operation) {
+
+ case ASN1_OP_NEW_POST:
+ ret->valid = 0;
+ ret->name = NULL;
+ ret->ex_flags = 0;
+ ret->ex_pathlen = -1;
+ ret->skid = NULL;
+ ret->akid = NULL;
+#ifndef OPENSSL_NO_RFC3779
+ ret->rfc3779_addr = NULL;
+ ret->rfc3779_asid = NULL;
+#endif
+ ret->aux = NULL;
+ ret->crldp = NULL;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+ break;
+
+ case ASN1_OP_D2I_POST:
+ if (ret->name != NULL)
+ OPENSSL_free(ret->name);
+ ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
+ break;
+
+ case ASN1_OP_FREE_POST:
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+ 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);
+#endif
+
+ if (ret->name != NULL)
+ OPENSSL_free(ret->name);
+ break;
+
+ }
+
+ return 1;
+
+}
+
+ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
+ ASN1_SIMPLE(X509, cert_info, X509_CINF),
+ ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509, X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+
+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)
+{
+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int X509_set_ex_data(X509 *r, int idx, void *arg)
+{
+ return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *X509_get_ex_data(X509 *r, int idx)
+{
+ return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+/*
+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
+ * extra info tagged on the end. Since these functions set how a certificate
+ * is trusted they should only be used when the certificate comes from a
+ * reliable source such as local storage.
+ */
+
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
+{
+ const unsigned char *q;
+ X509 *ret;
+ int freeret = 0;
+
+ /* Save start position */
+ q = *pp;
+
+ if (!a || *a == NULL) {
+ freeret = 1;
+ }
+ ret = d2i_X509(a, &q, length);
+ /* If certificate unreadable then forget it */
+ if (!ret)
+ return NULL;
+ /* update length */
+ length -= q - *pp;
+ if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
+ goto err;
+ *pp = q;
+ return ret;
+ err:
+ if (freeret) {
+ X509_free(ret);
+ if (a)
+ *a = NULL;
+ }
+ return NULL;
+}
+
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+ int length, tmplen;
+ unsigned char *start = pp != NULL ? *pp : NULL;
+ length = i2d_X509(a, pp);
+ if (length < 0 || a == NULL)
+ return length;
+
+ tmplen = i2d_X509_CERT_AUX(a->aux, pp);
+ if (tmplen < 0) {
+ if (start != NULL)
+ *pp = start;
+ return tmplen;
+ }
+ length += tmplen;
+
+ return length;
+}
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
+{
+ x->cert_info->enc.modified = 1;
+ return i2d_X509_CINF(x->cert_info, pp);
+}
+
+void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
+ const X509 *x)
+{
+ if (psig)
+ *psig = x->signature;
+ if (palg)
+ *palg = x->sig_alg;
+}
+
+int X509_get_signature_nid(const X509 *x)
+{
+ return OBJ_obj2nid(x->sig_alg->algorithm);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_x509a.c b/Cryptlib/OpenSSL/crypto/asn1/x_x509a.c
new file mode 100644
index 00000000..ad93592a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_x509a.c
@@ -0,0 +1,196 @@
+/* a_x509a.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/*
+ * X509_CERT_AUX routines. These are used to encode additional user
+ * modifiable data about a certificate. This data is appended to the X509
+ * encoding when the *_X509_AUX routines are used. This means that the
+ * "traditional" X509 routines will simply ignore the extra data.
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+ASN1_SEQUENCE(X509_CERT_AUX) = {
+ ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+ ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+ ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+} ASN1_SEQUENCE_END(X509_CERT_AUX)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+static X509_CERT_AUX *aux_get(X509 *x)
+{
+ if (!x)
+ return NULL;
+ if (!x->aux && !(x->aux = X509_CERT_AUX_new()))
+ return NULL;
+ return x->aux;
+}
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len)
+{
+ X509_CERT_AUX *aux;
+ if (!name) {
+ if (!x || !x->aux || !x->aux->alias)
+ return 1;
+ ASN1_UTF8STRING_free(x->aux->alias);
+ x->aux->alias = NULL;
+ return 1;
+ }
+ if (!(aux = aux_get(x)))
+ return 0;
+ if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new()))
+ return 0;
+ return ASN1_STRING_set(aux->alias, name, len);
+}
+
+int X509_keyid_set1(X509 *x, unsigned char *id, int len)
+{
+ X509_CERT_AUX *aux;
+ if (!id) {
+ if (!x || !x->aux || !x->aux->keyid)
+ return 1;
+ ASN1_OCTET_STRING_free(x->aux->keyid);
+ x->aux->keyid = NULL;
+ return 1;
+ }
+ if (!(aux = aux_get(x)))
+ return 0;
+ if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new()))
+ return 0;
+ return ASN1_STRING_set(aux->keyid, id, len);
+}
+
+unsigned char *X509_alias_get0(X509 *x, int *len)
+{
+ if (!x->aux || !x->aux->alias)
+ return NULL;
+ if (len)
+ *len = x->aux->alias->length;
+ return x->aux->alias->data;
+}
+
+unsigned char *X509_keyid_get0(X509 *x, int *len)
+{
+ if (!x->aux || !x->aux->keyid)
+ return NULL;
+ if (len)
+ *len = x->aux->keyid->length;
+ return x->aux->keyid->data;
+}
+
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
+{
+ X509_CERT_AUX *aux;
+ ASN1_OBJECT *objtmp;
+ if (!(objtmp = OBJ_dup(obj)))
+ return 0;
+ if (!(aux = aux_get(x)))
+ return 0;
+ if (!aux->trust && !(aux->trust = sk_ASN1_OBJECT_new_null()))
+ return 0;
+ return sk_ASN1_OBJECT_push(aux->trust, objtmp);
+}
+
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
+{
+ X509_CERT_AUX *aux;
+ ASN1_OBJECT *objtmp;
+ if (!(objtmp = OBJ_dup(obj)))
+ return 0;
+ if (!(aux = aux_get(x)))
+ goto err;
+ if (!aux->reject && !(aux->reject = sk_ASN1_OBJECT_new_null()))
+ goto err;
+ return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+ err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
+}
+
+void X509_trust_clear(X509 *x)
+{
+ if (x->aux && x->aux->trust) {
+ sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+ x->aux->trust = NULL;
+ }
+}
+
+void X509_reject_clear(X509 *x)
+{
+ if (x->aux && x->aux->reject) {
+ sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+ x->aux->reject = NULL;
+ }
+}
+
+ASN1_SEQUENCE(X509_CERT_PAIR) = {
+ ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
+ ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
+} ASN1_SEQUENCE_END(X509_CERT_PAIR)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)
diff --git a/Cryptlib/OpenSSL/crypto/bio/b_dump.c b/Cryptlib/OpenSSL/crypto/bio/b_dump.c
new file mode 100644
index 00000000..ccf0e287
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/b_dump.c
@@ -0,0 +1,208 @@
+/* crypto/bio/b_dump.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.]
+ */
+
+/*
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bio_lcl.h"
+
+#define TRUNCATE
+#define DUMP_WIDTH 16
+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
+
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+ void *u, const char *s, int len)
+{
+ return BIO_dump_indent_cb(cb, u, s, len, 0);
+}
+
+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
+ void *u, const char *s, int len, int indent)
+{
+ int ret = 0;
+ char buf[288 + 1], tmp[20], str[128 + 1];
+ int i, j, rows, trc;
+ unsigned char ch;
+ int dump_width;
+
+ trc = 0;
+
+#ifdef TRUNCATE
+ for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
+ trc++;
+#endif
+
+ if (indent < 0)
+ indent = 0;
+ if (indent) {
+ if (indent > 128)
+ indent = 128;
+ memset(str, ' ', indent);
+ }
+ str[indent] = '\0';
+
+ dump_width = DUMP_WIDTH_LESS_INDENT(indent);
+ rows = (len / dump_width);
+ if ((rows * dump_width) < len)
+ rows++;
+ for (i = 0; i < rows; i++) {
+ BUF_strlcpy(buf, str, sizeof buf);
+ BIO_snprintf(tmp, sizeof tmp, "%04x - ", i * dump_width);
+ BUF_strlcat(buf, tmp, sizeof buf);
+ for (j = 0; j < dump_width; j++) {
+ if (((i * dump_width) + j) >= len) {
+ BUF_strlcat(buf, " ", sizeof buf);
+ } else {
+ ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+ BIO_snprintf(tmp, sizeof tmp, "%02x%c", ch,
+ j == 7 ? '-' : ' ');
+ BUF_strlcat(buf, tmp, sizeof buf);
+ }
+ }
+ BUF_strlcat(buf, " ", sizeof buf);
+ for (j = 0; j < dump_width; j++) {
+ if (((i * dump_width) + j) >= len)
+ break;
+ ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+#ifndef CHARSET_EBCDIC
+ BIO_snprintf(tmp, sizeof tmp, "%c",
+ ((ch >= ' ') && (ch <= '~')) ? ch : '.');
+#else
+ BIO_snprintf(tmp, sizeof tmp, "%c",
+ ((ch >= os_toascii[' ']) && (ch <= os_toascii['~']))
+ ? os_toebcdic[ch]
+ : '.');
+#endif
+ BUF_strlcat(buf, tmp, sizeof buf);
+ }
+ BUF_strlcat(buf, "\n", sizeof buf);
+ /*
+ * if this is the last call then update the ddt_dump thing so that we
+ * will move the selection point in the debug window
+ */
+ ret += cb((void *)buf, strlen(buf), u);
+ }
+#ifdef TRUNCATE
+ if (trc > 0) {
+ BIO_snprintf(buf, sizeof buf, "%s%04x - <SPACES/NULS>\n", str,
+ len + trc);
+ ret += cb((void *)buf, strlen(buf), u);
+ }
+#endif
+ return (ret);
+}
+
+#ifndef OPENSSL_NO_FP_API
+static int write_fp(const void *data, size_t len, void *fp)
+{
+ return UP_fwrite(data, len, 1, fp);
+}
+
+int BIO_dump_fp(FILE *fp, const char *s, int len)
+{
+ return BIO_dump_cb(write_fp, fp, s, len);
+}
+
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
+{
+ return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
+}
+#endif
+
+static int write_bio(const void *data, size_t len, void *bp)
+{
+ return BIO_write((BIO *)bp, (const char *)data, len);
+}
+
+int BIO_dump(BIO *bp, const char *s, int len)
+{
+ return BIO_dump_cb(write_bio, bp, s, len);
+}
+
+int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
+{
+ return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
+}
+
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+ int datalen)
+{
+ int i, j = 0;
+
+ if (datalen < 1)
+ return 1;
+
+ for (i = 0; i < datalen - 1; i++) {
+ if (i && !j)
+ BIO_printf(out, "%*s", indent, "");
+
+ BIO_printf(out, "%02X:", data[i]);
+
+ j = (j + 1) % width;
+ if (!j)
+ BIO_printf(out, "\n");
+ }
+
+ if (i && !j)
+ BIO_printf(out, "%*s", indent, "");
+ BIO_printf(out, "%02X", data[datalen - 1]);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/b_print.c b/Cryptlib/OpenSSL/crypto/bio/b_print.c
new file mode 100644
index 00000000..dfc26bcd
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/b_print.c
@@ -0,0 +1,873 @@
+/* crypto/bio/b_print.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.]
+ */
+
+/* disable assert() unless BIO_DEBUG has been defined */
+#ifndef BIO_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+/*
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <limits.h>
+#include "cryptlib.h"
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <openssl/bn.h> /* To get BN_LLONG properly defined */
+#include <openssl/bio.h>
+
+#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
+# ifndef HAVE_LONG_LONG
+# define HAVE_LONG_LONG 1
+# endif
+#endif
+
+/***************************************************************************/
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell <papowell@astart.com>
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions.
+ */
+
+/*-
+ * This code contains numerious changes and enhancements which were
+ * made by lots of contributors over the last years to Patrick Powell's
+ * original code:
+ *
+ * o Patrick Powell <papowell@astart.com> (1995)
+ * o Brandon Long <blong@fiction.net> (1996, for Mutt)
+ * o Thomas Roessler <roessler@guug.de> (1998, for Mutt)
+ * o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt)
+ * o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
+ * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
+ * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
+ * o ... (for OpenSSL)
+ */
+
+#ifdef HAVE_LONG_DOUBLE
+# define LDOUBLE long double
+#else
+# define LDOUBLE double
+#endif
+
+#ifdef HAVE_LONG_LONG
+# if defined(_WIN32) && !defined(__GNUC__)
+# define LLONG __int64
+# else
+# define LLONG long long
+# endif
+#else
+# define LLONG long
+#endif
+
+static int fmtstr(char **, char **, size_t *, size_t *,
+ const char *, int, int, int);
+static int fmtint(char **, char **, size_t *, size_t *,
+ LLONG, int, int, int, int);
+#ifndef OPENSSL_SYS_UEFI
+static int fmtfp(char **, char **, size_t *, size_t *,
+ LDOUBLE, int, int, int);
+#endif
+static int doapr_outch(char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
+ size_t *maxlen, size_t *retlen, int *truncated,
+ const char *format, va_list args);
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS 1
+#define DP_S_MIN 2
+#define DP_S_DOT 3
+#define DP_S_MAX 4
+#define DP_S_MOD 5
+#define DP_S_CONV 6
+#define DP_S_DONE 7
+
+/* format flags - Bits */
+#define DP_F_MINUS (1 << 0)
+#define DP_F_PLUS (1 << 1)
+#define DP_F_SPACE (1 << 2)
+#define DP_F_NUM (1 << 3)
+#define DP_F_ZERO (1 << 4)
+#define DP_F_UP (1 << 5)
+#define DP_F_UNSIGNED (1 << 6)
+
+/* conversion flags */
+#define DP_C_SHORT 1
+#define DP_C_LONG 2
+#define DP_C_LDOUBLE 3
+#define DP_C_LLONG 4
+
+/* some handy macros */
+#define char_to_int(p) (p - '0')
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
+
+static int
+_dopr(char **sbuffer,
+ char **buffer,
+ size_t *maxlen,
+ size_t *retlen, int *truncated, const char *format, va_list args)
+{
+ char ch;
+ LLONG value;
+#ifndef OPENSSL_SYS_UEFI
+ LDOUBLE fvalue;
+#endif
+ char *strvalue;
+ int min;
+ int max;
+ int state;
+ int flags;
+ int cflags;
+ size_t currlen;
+
+ state = DP_S_DEFAULT;
+ flags = currlen = cflags = min = 0;
+ max = -1;
+ ch = *format++;
+
+ while (state != DP_S_DONE) {
+ if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
+ state = DP_S_DONE;
+
+ switch (state) {
+ case DP_S_DEFAULT:
+ if (ch == '%')
+ state = DP_S_FLAGS;
+ else
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
+ ch = *format++;
+ break;
+ case DP_S_FLAGS:
+ switch (ch) {
+ case '-':
+ flags |= DP_F_MINUS;
+ ch = *format++;
+ break;
+ case '+':
+ flags |= DP_F_PLUS;
+ ch = *format++;
+ break;
+ case ' ':
+ flags |= DP_F_SPACE;
+ ch = *format++;
+ break;
+ case '#':
+ flags |= DP_F_NUM;
+ ch = *format++;
+ break;
+ case '0':
+ flags |= DP_F_ZERO;
+ ch = *format++;
+ break;
+ default:
+ state = DP_S_MIN;
+ break;
+ }
+ break;
+ case DP_S_MIN:
+ if (isdigit((unsigned char)ch)) {
+ min = 10 * min + char_to_int(ch);
+ ch = *format++;
+ } else if (ch == '*') {
+ min = va_arg(args, int);
+ ch = *format++;
+ state = DP_S_DOT;
+ } else
+ state = DP_S_DOT;
+ break;
+ case DP_S_DOT:
+ if (ch == '.') {
+ state = DP_S_MAX;
+ ch = *format++;
+ } else
+ state = DP_S_MOD;
+ break;
+ case DP_S_MAX:
+ if (isdigit((unsigned char)ch)) {
+ if (max < 0)
+ max = 0;
+ max = 10 * max + char_to_int(ch);
+ ch = *format++;
+ } else if (ch == '*') {
+ max = va_arg(args, int);
+ ch = *format++;
+ state = DP_S_MOD;
+ } else
+ state = DP_S_MOD;
+ break;
+ case DP_S_MOD:
+ switch (ch) {
+ case 'h':
+ cflags = DP_C_SHORT;
+ ch = *format++;
+ break;
+ case 'l':
+ if (*format == 'l') {
+ cflags = DP_C_LLONG;
+ format++;
+ } else
+ cflags = DP_C_LONG;
+ ch = *format++;
+ break;
+ case 'q':
+ cflags = DP_C_LLONG;
+ ch = *format++;
+ break;
+#ifndef OPENSSL_SYS_UEFI
+ case 'L':
+ cflags = DP_C_LDOUBLE;
+ ch = *format++;
+ break;
+#endif
+ default:
+ break;
+ }
+ state = DP_S_CONV;
+ break;
+ case DP_S_CONV:
+ switch (ch) {
+ case 'd':
+ case 'i':
+ switch (cflags) {
+ case DP_C_SHORT:
+ value = (short int)va_arg(args, int);
+ break;
+ case DP_C_LONG:
+ value = va_arg(args, long int);
+ break;
+ case DP_C_LLONG:
+ value = va_arg(args, LLONG);
+ break;
+ default:
+ value = va_arg(args, int);
+ break;
+ }
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+ max, flags))
+ return 0;
+ break;
+ case 'X':
+ flags |= DP_F_UP;
+ /* FALLTHROUGH */
+ case 'x':
+ case 'o':
+ case 'u':
+ flags |= DP_F_UNSIGNED;
+ switch (cflags) {
+ case DP_C_SHORT:
+ value = (unsigned short int)va_arg(args, unsigned int);
+ break;
+ case DP_C_LONG:
+ value = (LLONG) va_arg(args, unsigned long int);
+ break;
+ case DP_C_LLONG:
+ value = va_arg(args, unsigned LLONG);
+ break;
+ default:
+ value = (LLONG) va_arg(args, unsigned int);
+ break;
+ }
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
+ ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
+ min, max, flags))
+ return 0;
+ break;
+#ifndef OPENSSL_SYS_UEFI
+ case 'f':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+ flags))
+ return 0;
+ break;
+ case 'E':
+ flags |= DP_F_UP;
+ case 'e':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ break;
+ case 'G':
+ flags |= DP_F_UP;
+ case 'g':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ break;
+#endif
+ case 'c':
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+ va_arg(args, int)))
+ return 0;
+ break;
+ case 's':
+ strvalue = va_arg(args, char *);
+ if (max < 0) {
+ if (buffer)
+ max = INT_MAX;
+ else
+ max = *maxlen;
+ }
+ if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+ flags, min, max))
+ return 0;
+ break;
+ case 'p':
+ value = (long)va_arg(args, void *);
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+ value, 16, min, max, flags | DP_F_NUM))
+ return 0;
+ break;
+ case 'n': /* XXX */
+ if (cflags == DP_C_SHORT) {
+ short int *num;
+ num = va_arg(args, short int *);
+ *num = currlen;
+ } else if (cflags == DP_C_LONG) { /* XXX */
+ long int *num;
+ num = va_arg(args, long int *);
+ *num = (long int)currlen;
+ } else if (cflags == DP_C_LLONG) { /* XXX */
+ LLONG *num;
+ num = va_arg(args, LLONG *);
+ *num = (LLONG) currlen;
+ } else {
+ int *num;
+ num = va_arg(args, int *);
+ *num = currlen;
+ }
+ break;
+ case '%':
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
+ break;
+ case 'w':
+ /* not supported yet, treat as next char */
+ ch = *format++;
+ break;
+ default:
+ /* unknown, skip */
+ break;
+ }
+ ch = *format++;
+ state = DP_S_DEFAULT;
+ flags = cflags = min = 0;
+ max = -1;
+ break;
+ case DP_S_DONE:
+ break;
+ default:
+ break;
+ }
+ }
+ *truncated = (currlen > *maxlen - 1);
+ if (*truncated)
+ currlen = *maxlen - 1;
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+ return 0;
+ *retlen = currlen - 1;
+ return 1;
+}
+
+static int
+fmtstr(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, const char *value, int flags, int min, int max)
+{
+ int padlen;
+ size_t strln;
+ int cnt = 0;
+
+ if (value == 0)
+ value = "<NULL>";
+
+ strln = strlen(value);
+ if (strln > INT_MAX)
+ strln = INT_MAX;
+
+ padlen = min - strln;
+ if (min < 0 || padlen < 0)
+ padlen = 0;
+ if (flags & DP_F_MINUS)
+ padlen = -padlen;
+
+ while ((padlen > 0) && (cnt < max)) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --padlen;
+ ++cnt;
+ }
+ while (*value && (cnt < max)) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+ return 0;
+ ++cnt;
+ }
+ while ((padlen < 0) && (cnt < max)) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++padlen;
+ ++cnt;
+ }
+ return 1;
+}
+
+static int
+fmtint(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, LLONG value, int base, int min, int max, int flags)
+{
+ int signvalue = 0;
+ const char *prefix = "";
+ unsigned LLONG uvalue;
+ char convert[DECIMAL_SIZE(value) + 3];
+ int place = 0;
+ int spadlen = 0;
+ int zpadlen = 0;
+ int caps = 0;
+
+ if (max < 0)
+ max = 0;
+ uvalue = value;
+ if (!(flags & DP_F_UNSIGNED)) {
+ if (value < 0) {
+ signvalue = '-';
+ uvalue = -value;
+ } else if (flags & DP_F_PLUS)
+ signvalue = '+';
+ else if (flags & DP_F_SPACE)
+ signvalue = ' ';
+ }
+ if (flags & DP_F_NUM) {
+ if (base == 8)
+ prefix = "0";
+ if (base == 16)
+ prefix = "0x";
+ }
+ if (flags & DP_F_UP)
+ caps = 1;
+ do {
+ convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+ [uvalue % (unsigned)base];
+ uvalue = (uvalue / (unsigned)base);
+ } while (uvalue && (place < (int)sizeof(convert)));
+ if (place == sizeof(convert))
+ place--;
+ convert[place] = 0;
+
+ zpadlen = max - place;
+ spadlen =
+ min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
+ if (zpadlen < 0)
+ zpadlen = 0;
+ if (spadlen < 0)
+ spadlen = 0;
+ if (flags & DP_F_ZERO) {
+ zpadlen = OSSL_MAX(zpadlen, spadlen);
+ spadlen = 0;
+ }
+ if (flags & DP_F_MINUS)
+ spadlen = -spadlen;
+
+ /* spaces */
+ while (spadlen > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --spadlen;
+ }
+
+ /* sign */
+ if (signvalue)
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+
+ /* prefix */
+ while (*prefix) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+ return 0;
+ prefix++;
+ }
+
+ /* zeros */
+ if (zpadlen > 0) {
+ while (zpadlen > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --zpadlen;
+ }
+ }
+ /* digits */
+ while (place > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+ return 0;
+ }
+
+ /* left justified spaces */
+ while (spadlen < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++spadlen;
+ }
+ return 1;
+}
+
+#ifndef OPENSSL_SYS_UEFI
+static LDOUBLE abs_val(LDOUBLE value)
+{
+ LDOUBLE result = value;
+ if (value < 0)
+ result = -value;
+ return result;
+}
+
+static LDOUBLE pow_10(int in_exp)
+{
+ LDOUBLE result = 1;
+ while (in_exp) {
+ result *= 10;
+ in_exp--;
+ }
+ return result;
+}
+
+static long roundv(LDOUBLE value)
+{
+ long intpart;
+ intpart = (long)value;
+ value = value - intpart;
+ if (value >= 0.5)
+ intpart++;
+ return intpart;
+}
+
+static int
+fmtfp(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags)
+{
+ int signvalue = 0;
+ LDOUBLE ufvalue;
+ char iconvert[20];
+ char fconvert[20];
+ int iplace = 0;
+ int fplace = 0;
+ int padlen = 0;
+ int zpadlen = 0;
+ long intpart;
+ long fracpart;
+ long max10;
+
+ if (max < 0)
+ max = 6;
+ ufvalue = abs_val(fvalue);
+ if (fvalue < 0)
+ signvalue = '-';
+ else if (flags & DP_F_PLUS)
+ signvalue = '+';
+ else if (flags & DP_F_SPACE)
+ signvalue = ' ';
+
+ intpart = (long)ufvalue;
+
+ /*
+ * sorry, we only support 9 digits past the decimal because of our
+ * conversion method
+ */
+ if (max > 9)
+ max = 9;
+
+ /*
+ * we "cheat" by converting the fractional part to integer by multiplying
+ * by a factor of 10
+ */
+ max10 = roundv(pow_10(max));
+ fracpart = roundv(pow_10(max) * (ufvalue - intpart));
+
+ if (fracpart >= max10) {
+ intpart++;
+ fracpart -= max10;
+ }
+
+ /* convert integer part */
+ do {
+ iconvert[iplace++] = "0123456789"[intpart % 10];
+ intpart = (intpart / 10);
+ } while (intpart && (iplace < (int)sizeof(iconvert)));
+ if (iplace == sizeof iconvert)
+ iplace--;
+ iconvert[iplace] = 0;
+
+ /* convert fractional part */
+ do {
+ fconvert[fplace++] = "0123456789"[fracpart % 10];
+ fracpart = (fracpart / 10);
+ } while (fplace < max);
+ if (fplace == sizeof fconvert)
+ fplace--;
+ fconvert[fplace] = 0;
+
+ /* -1 for decimal point, another -1 if we are printing a sign */
+ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+ zpadlen = max - fplace;
+ if (zpadlen < 0)
+ zpadlen = 0;
+ if (padlen < 0)
+ padlen = 0;
+ if (flags & DP_F_MINUS)
+ padlen = -padlen;
+
+ if ((flags & DP_F_ZERO) && (padlen > 0)) {
+ if (signvalue) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+ --padlen;
+ signvalue = 0;
+ }
+ while (padlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --padlen;
+ }
+ }
+ while (padlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --padlen;
+ }
+ if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+
+ while (iplace > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+ return 0;
+ }
+
+ /*
+ * Decimal point. This should probably use locale to find the correct
+ * char to print out.
+ */
+ if (max > 0 || (flags & DP_F_NUM)) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+ return 0;
+
+ while (fplace > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
+ fconvert[--fplace]))
+ return 0;
+ }
+ }
+ while (zpadlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --zpadlen;
+ }
+
+ while (padlen < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++padlen;
+ }
+ return 1;
+}
+#endif
+
+#define BUFFER_INC 1024
+
+static int
+doapr_outch(char **sbuffer,
+ char **buffer, size_t *currlen, size_t *maxlen, int c)
+{
+ /* If we haven't at least one buffer, someone has doe a big booboo */
+ assert(*sbuffer != NULL || buffer != NULL);
+
+ /* |currlen| must always be <= |*maxlen| */
+ assert(*currlen <= *maxlen);
+
+ if (buffer && *currlen == *maxlen) {
+ if (*maxlen > INT_MAX - BUFFER_INC)
+ return 0;
+
+ *maxlen += BUFFER_INC;
+ if (*buffer == NULL) {
+ *buffer = OPENSSL_malloc(*maxlen);
+ if (*buffer == NULL)
+ return 0;
+ if (*currlen > 0) {
+ assert(*sbuffer != NULL);
+ memcpy(*buffer, *sbuffer, *currlen);
+ }
+ *sbuffer = NULL;
+ } else {
+ char *tmpbuf;
+ tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+ if (tmpbuf == NULL)
+ return 0;
+ *buffer = tmpbuf;
+ }
+ }
+
+ if (*currlen < *maxlen) {
+ if (*sbuffer)
+ (*sbuffer)[(*currlen)++] = (char)c;
+ else
+ (*buffer)[(*currlen)++] = (char)c;
+ }
+
+ return 1;
+}
+
+/***************************************************************************/
+
+int BIO_printf(BIO *bio, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+
+ ret = BIO_vprintf(bio, format, args);
+
+ va_end(args);
+ return (ret);
+}
+
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+{
+ int ret;
+ size_t retlen;
+ char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable
+ * in small-stack environments, like threads
+ * or DOS programs. */
+ char *hugebufp = hugebuf;
+ size_t hugebufsize = sizeof(hugebuf);
+ char *dynbuf = NULL;
+ int ignored;
+
+ dynbuf = NULL;
+ CRYPTO_push_info("doapr()");
+ if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
+ args)) {
+ OPENSSL_free(dynbuf);
+ return -1;
+ }
+ if (dynbuf) {
+ ret = BIO_write(bio, dynbuf, (int)retlen);
+ OPENSSL_free(dynbuf);
+ } else {
+ ret = BIO_write(bio, hugebuf, (int)retlen);
+ }
+ CRYPTO_pop_info();
+ return (ret);
+}
+
+/*
+ * As snprintf is not available everywhere, we provide our own
+ * implementation. This function has nothing to do with BIOs, but it's
+ * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
+ * function should be renamed, but to what?)
+ */
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+
+ ret = BIO_vsnprintf(buf, n, format, args);
+
+ va_end(args);
+ return (ret);
+}
+
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+{
+ size_t retlen;
+ int truncated;
+
+ if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+ return -1;
+
+ if (truncated)
+ /*
+ * In case of truncation, return -1 like traditional snprintf.
+ * (Current drafts for ISO/IEC 9899 say snprintf should return the
+ * number of characters that would have been written, had the buffer
+ * been large enough.)
+ */
+ return -1;
+ else
+ return (retlen <= INT_MAX) ? (int)retlen : -1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/b_sock.c b/Cryptlib/OpenSSL/crypto/bio/b_sock.c
new file mode 100644
index 00000000..5bad0a2b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/b_sock.c
@@ -0,0 +1,962 @@
+/* crypto/bio/b_sock.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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
+# include <netdb.h>
+# if defined(NETWARE_CLIB)
+# include <sys/ioctl.h>
+NETDB_DEFINE_CONTEXT
+# endif
+#endif
+#ifndef OPENSSL_NO_SOCK
+# include <openssl/dso.h>
+# define SOCKET_PROTOCOL IPPROTO_TCP
+# ifdef SO_MAXCONN
+# define MAX_LISTEN SO_MAXCONN
+# elif defined(SOMAXCONN)
+# define MAX_LISTEN SOMAXCONN
+# else
+# define MAX_LISTEN 32
+# endif
+# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
+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;
+
+# define GHBN_NUM 4
+static struct ghbn_cache_st {
+ char name[129];
+ struct hostent *ent;
+ unsigned long order;
+} ghbn_cache[GHBN_NUM];
+# endif
+
+static int get_ip(const char *str, unsigned char *ip);
+# if 0
+static void ghbn_free(struct hostent *a);
+static struct hostent *ghbn_dup(struct hostent *a);
+# endif
+int BIO_get_host_ip(const char *str, unsigned char *ip)
+{
+ int i;
+ int err = 1;
+ int locked = 0;
+ struct hostent *he;
+
+ i = get_ip(str, ip);
+ if (i < 0) {
+ BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS);
+ goto err;
+ }
+
+ /*
+ * At this point, we have something that is most probably correct in some
+ * way, so let's init the socket.
+ */
+ if (BIO_sock_init() != 1)
+ return 0; /* don't generate another error code here */
+
+ /*
+ * If the string actually contained an IP address, we need not do
+ * anything more
+ */
+ if (i > 0)
+ return (1);
+
+ /* do a gethostbyname */
+ CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
+ locked = 1;
+ he = BIO_gethostbyname(str);
+ if (he == NULL) {
+ BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
+ goto err;
+ }
+
+ /* cast to short because of win16 winsock definition */
+ if ((short)he->h_addrtype != AF_INET) {
+ BIOerr(BIO_F_BIO_GET_HOST_IP,
+ BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
+ goto err;
+ }
+ for (i = 0; i < 4; i++)
+ ip[i] = he->h_addr_list[0][i];
+ err = 0;
+
+ err:
+ if (locked)
+ CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
+ if (err) {
+ ERR_add_error_data(2, "host=", str);
+ return 0;
+ } else
+ return 1;
+}
+
+int BIO_get_port(const char *str, unsigned short *port_ptr)
+{
+ int i;
+ struct servent *s;
+
+ if (str == NULL) {
+ BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
+ return (0);
+ }
+ i = atoi(str);
+ if (i != 0)
+ *port_ptr = (unsigned short)i;
+ else {
+ CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
+ /*
+ * Note: under VMS with SOCKETSHR, it seems like the first parameter
+ * is 'char *', instead of 'const char *'
+ */
+# ifndef CONST_STRICT
+ s = getservbyname((char *)str, "tcp");
+# else
+ s = getservbyname(str, "tcp");
+# endif
+ if (s != NULL)
+ *port_ptr = ntohs((unsigned short)s->s_port);
+ CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
+ if (s == NULL) {
+ if (strcmp(str, "http") == 0)
+ *port_ptr = 80;
+ else if (strcmp(str, "telnet") == 0)
+ *port_ptr = 23;
+ else if (strcmp(str, "socks") == 0)
+ *port_ptr = 1080;
+ else if (strcmp(str, "https") == 0)
+ *port_ptr = 443;
+ else if (strcmp(str, "ssl") == 0)
+ *port_ptr = 443;
+ else if (strcmp(str, "ftp") == 0)
+ *port_ptr = 21;
+ else if (strcmp(str, "gopher") == 0)
+ *port_ptr = 70;
+# if 0
+ else if (strcmp(str, "wais") == 0)
+ *port_ptr = 21;
+# endif
+ else {
+ SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error());
+ ERR_add_error_data(3, "service='", str, "'");
+ return (0);
+ }
+ }
+ }
+ return (1);
+}
+
+int BIO_sock_error(int sock)
+{
+ int j, i;
+ union {
+ size_t s;
+ int i;
+ } size;
+
+# if defined(OPENSSL_SYS_BEOS_R5)
+ return 0;
+# endif
+
+ /* heuristic way to adapt for platforms that expect 64-bit optlen */
+ size.s = 0, size.i = sizeof(j);
+ /*
+ * Note: under Windows the third parameter is of type (char *) 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
+ * (char *) or (void *).
+ */
+ i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size);
+ if (i < 0)
+ return (1);
+ else
+ return (j);
+}
+
+# if 0
+long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
+{
+ int i;
+ char **p;
+
+ switch (cmd) {
+ case BIO_GHBN_CTRL_HITS:
+ return (BIO_ghbn_hits);
+ /* break; */
+ case BIO_GHBN_CTRL_MISSES:
+ return (BIO_ghbn_miss);
+ /* break; */
+ case BIO_GHBN_CTRL_CACHE_SIZE:
+ return (GHBN_NUM);
+ /* break; */
+ case BIO_GHBN_CTRL_GET_ENTRY:
+ if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) {
+ p = (char **)parg;
+ if (p == NULL)
+ return (0);
+ *p = ghbn_cache[iarg].name;
+ ghbn_cache[iarg].name[128] = '\0';
+ return (1);
+ }
+ return (0);
+ /* break; */
+ case BIO_GHBN_CTRL_FLUSH:
+ for (i = 0; i < GHBN_NUM; i++)
+ ghbn_cache[i].order = 0;
+ break;
+ default:
+ return (0);
+ }
+ return (1);
+}
+# endif
+
+# if 0
+static struct hostent *ghbn_dup(struct hostent *a)
+{
+ struct hostent *ret;
+ int i, j;
+
+ MemCheck_off();
+ ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
+ if (ret == NULL)
+ return (NULL);
+ memset(ret, 0, sizeof(struct hostent));
+
+ for (i = 0; a->h_aliases[i] != NULL; i++) ;
+ i++;
+ ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *));
+ if (ret->h_aliases == NULL)
+ goto err;
+ memset(ret->h_aliases, 0, i * sizeof(char *));
+
+ for (i = 0; a->h_addr_list[i] != NULL; i++) ;
+ i++;
+ ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *));
+ if (ret->h_addr_list == NULL)
+ goto err;
+ memset(ret->h_addr_list, 0, i * sizeof(char *));
+
+ j = strlen(a->h_name) + 1;
+ if ((ret->h_name = OPENSSL_malloc(j)) == NULL)
+ goto err;
+ memcpy((char *)ret->h_name, a->h_name, j);
+ for (i = 0; a->h_aliases[i] != NULL; i++) {
+ j = strlen(a->h_aliases[i]) + 1;
+ if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL)
+ goto err;
+ memcpy(ret->h_aliases[i], a->h_aliases[i], j);
+ }
+ ret->h_length = a->h_length;
+ ret->h_addrtype = a->h_addrtype;
+ for (i = 0; a->h_addr_list[i] != NULL; i++) {
+ if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL)
+ goto err;
+ memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length);
+ }
+ if (0) {
+ err:
+ if (ret != NULL)
+ ghbn_free(ret);
+ ret = NULL;
+ }
+ MemCheck_on();
+ return (ret);
+}
+
+static void ghbn_free(struct hostent *a)
+{
+ int i;
+
+ if (a == NULL)
+ return;
+
+ if (a->h_aliases != NULL) {
+ for (i = 0; a->h_aliases[i] != NULL; i++)
+ OPENSSL_free(a->h_aliases[i]);
+ OPENSSL_free(a->h_aliases);
+ }
+ if (a->h_addr_list != NULL) {
+ for (i = 0; a->h_addr_list[i] != NULL; i++)
+ OPENSSL_free(a->h_addr_list[i]);
+ OPENSSL_free(a->h_addr_list);
+ }
+ if (a->h_name != NULL)
+ OPENSSL_free(a->h_name);
+ OPENSSL_free(a);
+}
+
+# endif
+
+struct hostent *BIO_gethostbyname(const char *name)
+{
+# if 1
+ /*
+ * Caching gethostbyname() results forever is wrong, so we have to let
+ * the true gethostbyname() worry about this
+ */
+# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
+ return gethostbyname((char *)name);
+# else
+ return gethostbyname(name);
+# endif
+# else
+ struct hostent *ret;
+ int i, lowi = 0, j;
+ unsigned long low = (unsigned long)-1;
+
+# if 0
+ /*
+ * It doesn't make sense to use locking here: The function interface is
+ * not thread-safe, because threads can never be sure when some other
+ * thread destroys the data they were given a pointer to.
+ */
+ CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
+# endif
+ j = strlen(name);
+ if (j < 128) {
+ for (i = 0; i < GHBN_NUM; i++) {
+ if (low > ghbn_cache[i].order) {
+ low = ghbn_cache[i].order;
+ lowi = i;
+ }
+ if (ghbn_cache[i].order > 0) {
+ if (strncmp(name, ghbn_cache[i].name, 128) == 0)
+ break;
+ }
+ }
+ } else
+ i = GHBN_NUM;
+
+ if (i == GHBN_NUM) { /* no hit */
+ BIO_ghbn_miss++;
+ /*
+ * Note: under VMS with SOCKETSHR, it seems like the first parameter
+ * is 'char *', instead of 'const char *'
+ */
+# ifndef CONST_STRICT
+ ret = gethostbyname((char *)name);
+# else
+ ret = gethostbyname(name);
+# endif
+
+ if (ret == NULL)
+ goto end;
+ if (j > 128) { /* too big to cache */
+# if 0
+ /*
+ * If we were trying to make this function thread-safe (which is
+ * bound to fail), we'd have to give up in this case (or allocate
+ * more memory).
+ */
+ ret = NULL;
+# endif
+ goto end;
+ }
+
+ /* else add to cache */
+ if (ghbn_cache[lowi].ent != NULL)
+ ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
+ ghbn_cache[lowi].name[0] = '\0';
+
+ if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) {
+ BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+ strncpy(ghbn_cache[lowi].name, name, 128);
+ ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits;
+ } else {
+ BIO_ghbn_hits++;
+ ret = ghbn_cache[i].ent;
+ ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits;
+ }
+ end:
+# if 0
+ CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
+# endif
+ return (ret);
+# endif
+}
+
+int BIO_sock_init(void)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+ static struct WSAData wsa_state;
+
+ if (!wsa_init_done) {
+ int err;
+
+ wsa_init_done = 1;
+ memset(&wsa_state, 0, sizeof(wsa_state));
+ /*
+ * 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);
+ BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
+ return (-1);
+ }
+ }
+# endif /* OPENSSL_SYS_WINDOWS */
+# ifdef WATT32
+ extern int _watt_do_exit;
+ _watt_do_exit = 0; /* don't make sock_init() call exit() */
+ if (sock_init())
+ return (-1);
+# endif
+
+# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+ WORD wVerReq;
+ WSADATA wsaData;
+ int err;
+
+ if (!wsa_init_done) {
+ wsa_init_done = 1;
+ wVerReq = MAKEWORD(2, 0);
+ err = WSAStartup(wVerReq, &wsaData);
+ if (err != 0) {
+ SYSerr(SYS_F_WSASTARTUP, err);
+ BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
+ return (-1);
+ }
+ }
+# endif
+
+ return (1);
+}
+
+void BIO_sock_cleanup(void)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+ if (wsa_init_done) {
+ wsa_init_done = 0;
+# if 0 /* this call is claimed to be non-present in
+ * Winsock2 */
+ WSACancelBlockingCall();
+# endif
+ WSACleanup();
+ }
+# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+ if (wsa_init_done) {
+ wsa_init_done = 0;
+ WSACleanup();
+ }
+# endif
+}
+
+# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
+
+int BIO_socket_ioctl(int fd, long type, void *arg)
+{
+ int i;
+
+# ifdef __DJGPP__
+ i = ioctlsocket(fd, type, (char *)arg);
+# else
+# if defined(OPENSSL_SYS_VMS)
+ /*-
+ * 2011-02-18 SMS.
+ * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
+ * observe that all the consumers pass in an "unsigned long *",
+ * so we arrange a local copy with a short pointer, and use
+ * that, instead.
+ */
+# if __INITIAL_POINTER_SIZE == 64
+# define ARG arg_32p
+# pragma pointer_size save
+# pragma pointer_size 32
+ unsigned long arg_32;
+ unsigned long *arg_32p;
+# pragma pointer_size restore
+ arg_32p = &arg_32;
+ arg_32 = *((unsigned long *)arg);
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define ARG arg
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+# else /* defined(OPENSSL_SYS_VMS) */
+# define ARG arg
+# endif /* defined(OPENSSL_SYS_VMS) [else] */
+
+ i = ioctlsocket(fd, type, ARG);
+# endif /* __DJGPP__ */
+ if (i < 0)
+ SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
+ return (i);
+}
+# endif /* __VMS_VER */
+
+/*
+ * The reason I have implemented this instead of using sscanf is because
+ * Visual C 1.52c gives an unresolved external when linking a DLL :-(
+ */
+static int get_ip(const char *str, unsigned char ip[4])
+{
+ unsigned int tmp[4];
+ int num = 0, c, ok = 0;
+
+ tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
+
+ for (;;) {
+ c = *(str++);
+ if ((c >= '0') && (c <= '9')) {
+ ok = 1;
+ tmp[num] = tmp[num] * 10 + c - '0';
+ if (tmp[num] > 255)
+ return (0);
+ } else if (c == '.') {
+ if (!ok)
+ return (-1);
+ if (num == 3)
+ return (0);
+ num++;
+ ok = 0;
+ } else if (c == '\0' && (num == 3) && ok)
+ break;
+ else
+ return (0);
+ }
+ ip[0] = tmp[0];
+ ip[1] = tmp[1];
+ ip[2] = tmp[2];
+ ip[3] = tmp[3];
+ return (1);
+}
+
+int BIO_get_accept_socket(char *host, int bind_mode)
+{
+ int ret = 0;
+ 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;
+ char *h, *p;
+ unsigned long l;
+ int err_num;
+
+ if (BIO_sock_init() != 1)
+ return (INVALID_SOCKET);
+
+ if ((str = BUF_strdup(host)) == NULL)
+ return (INVALID_SOCKET);
+
+ h = p = NULL;
+ h = str;
+ for (e = str; *e; e++) {
+ if (*e == ':') {
+ p = e;
+ } else if (*e == '/') {
+ *e = '\0';
+ break;
+ }
+ }
+ 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));
+ hint.ai_flags = AI_PASSIVE;
+ if (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') {
+ hint.ai_family = AF_INET;
+ 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.sa_in.sin_family = AF_INET;
+ server.sa_in.sin_port = htons(port);
+ addrlen = sizeof(server.sa_in);
+
+ 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;
+ l = (unsigned long)
+ ((unsigned long)ip[0] << 24L) |
+ ((unsigned long)ip[1] << 16L) |
+ ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
+ server.sa_in.sin_addr.s_addr = htonl(l);
+ }
+
+ again:
+ s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
+ if (s == INVALID_SOCKET) {
+ SYSerr(SYS_F_SOCKET, get_last_socket_error());
+ ERR_add_error_data(3, "port='", host, "'");
+ BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ goto err;
+ }
+# ifdef SO_REUSEADDR
+ if (bind_mode == BIO_BIND_REUSEADDR) {
+ int i = 1;
+
+ ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i));
+ bind_mode = BIO_BIND_NORMAL;
+ }
+# endif
+ 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
+ {
+ 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, &client.sa, addrlen);
+ closesocket(cs);
+ if (ii == INVALID_SOCKET) {
+ bind_mode = BIO_BIND_REUSEADDR;
+ closesocket(s);
+ goto again;
+ }
+ /* else error */
+ }
+ /* else error */
+ }
+# endif
+ SYSerr(SYS_F_BIND, err_num);
+ ERR_add_error_data(3, "port='", host, "'");
+ BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET);
+ goto err;
+ }
+ if (listen(s, MAX_LISTEN) == -1) {
+ SYSerr(SYS_F_BIND, get_last_socket_error());
+ ERR_add_error_data(3, "port='", host, "'");
+ BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET);
+ goto err;
+ }
+ ret = 1;
+ err:
+ if (str != NULL)
+ OPENSSL_free(str);
+ if ((ret == 0) && (s != INVALID_SOCKET)) {
+ closesocket(s);
+ s = INVALID_SOCKET;
+ }
+ return (s);
+}
+
+int BIO_accept(int sock, char **addr)
+{
+ int ret = INVALID_SOCKET;
+ unsigned long l;
+ unsigned short port;
+ char *p;
+
+ 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.
+ * <appro>
+ */
+ 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;
+ SYSerr(SYS_F_ACCEPT, get_last_socket_error());
+ BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
+ goto end;
+ }
+
+ if (addr == NULL)
+ goto end;
+
+# 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... <appro>
+ */
+
+ 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) {
+ BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+ *addr = p;
+ }
+ BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d",
+ (unsigned char)(l >> 24L) & 0xff,
+ (unsigned char)(l >> 16L) & 0xff,
+ (unsigned char)(l >> 8L) & 0xff,
+ (unsigned char)(l) & 0xff, port);
+ end:
+ return (ret);
+}
+
+int BIO_set_tcp_ndelay(int s, int on)
+{
+ int ret = 0;
+# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
+ int opt;
+
+# ifdef SOL_TCP
+ opt = SOL_TCP;
+# else
+# ifdef IPPROTO_TCP
+ opt = IPPROTO_TCP;
+# endif
+# endif
+
+ ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
+# endif
+ return (ret == 0);
+}
+
+int BIO_socket_nbio(int s, int mode)
+{
+ int ret = -1;
+ int l;
+
+ l = mode;
+# ifdef FIONBIO
+ ret = BIO_socket_ioctl(s, FIONBIO, &l);
+# endif
+ return (ret == 0);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bio/bf_buff.c b/Cryptlib/OpenSSL/crypto/bio/bf_buff.c
new file mode 100644
index 00000000..478fa16a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bf_buff.c
@@ -0,0 +1,517 @@
+/* crypto/bio/bf_buff.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+static int buffer_write(BIO *h, const char *buf, int num);
+static int buffer_read(BIO *h, char *buf, int size);
+static int buffer_puts(BIO *h, const char *str);
+static int buffer_gets(BIO *h, char *str, int size);
+static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int buffer_new(BIO *h);
+static int buffer_free(BIO *data);
+static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define DEFAULT_BUFFER_SIZE 4096
+
+static BIO_METHOD methods_buffer = {
+ BIO_TYPE_BUFFER,
+ "buffer",
+ buffer_write,
+ buffer_read,
+ buffer_puts,
+ buffer_gets,
+ buffer_ctrl,
+ buffer_new,
+ buffer_free,
+ buffer_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_buffer(void)
+{
+ return (&methods_buffer);
+}
+
+static int buffer_new(BIO *bi)
+{
+ BIO_F_BUFFER_CTX *ctx;
+
+ ctx = (BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
+ if (ctx == NULL)
+ return (0);
+ ctx->ibuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+ if (ctx->ibuf == NULL) {
+ OPENSSL_free(ctx);
+ return (0);
+ }
+ ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+ if (ctx->obuf == NULL) {
+ OPENSSL_free(ctx->ibuf);
+ OPENSSL_free(ctx);
+ return (0);
+ }
+ ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
+ ctx->obuf_size = DEFAULT_BUFFER_SIZE;
+ ctx->ibuf_len = 0;
+ ctx->ibuf_off = 0;
+ ctx->obuf_len = 0;
+ ctx->obuf_off = 0;
+
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int buffer_free(BIO *a)
+{
+ BIO_F_BUFFER_CTX *b;
+
+ if (a == NULL)
+ return (0);
+ b = (BIO_F_BUFFER_CTX *)a->ptr;
+ if (b->ibuf != NULL)
+ OPENSSL_free(b->ibuf);
+ if (b->obuf != NULL)
+ OPENSSL_free(b->obuf);
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int buffer_read(BIO *b, char *out, int outl)
+{
+ int i, num = 0;
+ BIO_F_BUFFER_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+ num = 0;
+ BIO_clear_retry_flags(b);
+
+ start:
+ i = ctx->ibuf_len;
+ /* If there is stuff left over, grab it */
+ if (i != 0) {
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
+ ctx->ibuf_off += i;
+ ctx->ibuf_len -= i;
+ num += i;
+ if (outl == i)
+ return (num);
+ outl -= i;
+ out += i;
+ }
+
+ /*
+ * We may have done a partial read. try to do more. We have nothing in
+ * the buffer. If we get an error and have read some data, just return it
+ * and let them retry to get the error again. copy direct to parent
+ * address space
+ */
+ if (outl > ctx->ibuf_size) {
+ for (;;) {
+ i = BIO_read(b->next_bio, out, outl);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return (num);
+ }
+ num += i;
+ if (outl == i)
+ return (num);
+ out += i;
+ outl -= i;
+ }
+ }
+ /* else */
+
+ /* we are going to be doing some buffering */
+ i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return (num);
+ }
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = i;
+
+ /* Lets re-read using ourselves :-) */
+ goto start;
+}
+
+static int buffer_write(BIO *b, const char *in, int inl)
+{
+ int i, num = 0;
+ BIO_F_BUFFER_CTX *ctx;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ BIO_clear_retry_flags(b);
+ start:
+ i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
+ /* add to buffer and return */
+ if (i >= inl) {
+ memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
+ ctx->obuf_len += inl;
+ return (num + inl);
+ }
+ /* else */
+ /* stuff already in buffer, so add to it first, then flush */
+ if (ctx->obuf_len != 0) {
+ if (i > 0) { /* lets fill it up if we can */
+ memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
+ in += i;
+ inl -= i;
+ num += i;
+ ctx->obuf_len += i;
+ }
+ /* we now have a full buffer needing flushing */
+ for (;;) {
+ i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
+ ctx->obuf_len);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return (num);
+ }
+ ctx->obuf_off += i;
+ ctx->obuf_len -= i;
+ if (ctx->obuf_len == 0)
+ break;
+ }
+ }
+ /*
+ * we only get here if the buffer has been flushed and we still have
+ * stuff to write
+ */
+ ctx->obuf_off = 0;
+
+ /* we now have inl bytes to write */
+ while (inl >= ctx->obuf_size) {
+ i = BIO_write(b->next_bio, in, inl);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return (num);
+ }
+ num += i;
+ in += i;
+ inl -= i;
+ if (inl == 0)
+ return (num);
+ }
+
+ /*
+ * copy the rest into the buffer since we have only a small amount left
+ */
+ goto start;
+}
+
+static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ BIO_F_BUFFER_CTX *ctx;
+ long ret = 1;
+ char *p1, *p2;
+ int r, i, *ip;
+ int ibs, obs;
+
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = 0;
+ ctx->obuf_off = 0;
+ ctx->obuf_len = 0;
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->obuf_len;
+ break;
+ case BIO_C_GET_BUFF_NUM_LINES:
+ ret = 0;
+ p1 = ctx->ibuf;
+ for (i = 0; i < ctx->ibuf_len; i++) {
+ if (p1[ctx->ibuf_off + i] == '\n')
+ ret++;
+ }
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = (long)ctx->obuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_CTRL_PENDING:
+ ret = (long)ctx->ibuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_C_SET_BUFF_READ_DATA:
+ if (num > ctx->ibuf_size) {
+ p1 = OPENSSL_malloc((int)num);
+ if (p1 == NULL)
+ goto malloc_error;
+ if (ctx->ibuf != NULL)
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = p1;
+ }
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = (int)num;
+ memcpy(ctx->ibuf, ptr, (int)num);
+ ret = 1;
+ break;
+ case BIO_C_SET_BUFF_SIZE:
+ if (ptr != NULL) {
+ ip = (int *)ptr;
+ if (*ip == 0) {
+ ibs = (int)num;
+ obs = ctx->obuf_size;
+ } else { /* if (*ip == 1) */
+
+ ibs = ctx->ibuf_size;
+ obs = (int)num;
+ }
+ } else {
+ ibs = (int)num;
+ obs = (int)num;
+ }
+ p1 = ctx->ibuf;
+ p2 = ctx->obuf;
+ if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
+ p1 = (char *)OPENSSL_malloc((int)num);
+ if (p1 == NULL)
+ goto malloc_error;
+ }
+ if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
+ p2 = (char *)OPENSSL_malloc((int)num);
+ if (p2 == NULL) {
+ if (p1 != ctx->ibuf)
+ OPENSSL_free(p1);
+ goto malloc_error;
+ }
+ }
+ if (ctx->ibuf != p1) {
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = p1;
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = 0;
+ ctx->ibuf_size = ibs;
+ }
+ if (ctx->obuf != p2) {
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf = p2;
+ ctx->obuf_off = 0;
+ ctx->obuf_len = 0;
+ ctx->obuf_size = obs;
+ }
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ if (b->next_bio == NULL)
+ return (0);
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (b->next_bio == NULL)
+ return (0);
+ if (ctx->obuf_len <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+
+ for (;;) {
+ BIO_clear_retry_flags(b);
+ if (ctx->obuf_len > 0) {
+ r = BIO_write(b->next_bio,
+ &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
+#if 0
+ fprintf(stderr, "FLUSH [%3d] %3d -> %3d\n", ctx->obuf_off,
+ ctx->obuf_len, r);
+#endif
+ BIO_copy_next_retry(b);
+ if (r <= 0)
+ return ((long)r);
+ ctx->obuf_off += r;
+ ctx->obuf_len -= r;
+ } else {
+ ctx->obuf_len = 0;
+ ctx->obuf_off = 0;
+ ret = 1;
+ break;
+ }
+ }
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
+ !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+ ret = 0;
+ break;
+ default:
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+ malloc_error:
+ BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+ return (0);
+}
+
+static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int buffer_gets(BIO *b, char *buf, int size)
+{
+ BIO_F_BUFFER_CTX *ctx;
+ int num = 0, i, flag;
+ char *p;
+
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+ size--; /* reserve space for a '\0' */
+ BIO_clear_retry_flags(b);
+
+ for (;;) {
+ if (ctx->ibuf_len > 0) {
+ p = &(ctx->ibuf[ctx->ibuf_off]);
+ flag = 0;
+ for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
+ *(buf++) = p[i];
+ if (p[i] == '\n') {
+ flag = 1;
+ i++;
+ break;
+ }
+ }
+ num += i;
+ size -= i;
+ ctx->ibuf_len -= i;
+ ctx->ibuf_off += i;
+ if (flag || size == 0) {
+ *buf = '\0';
+ return (num);
+ }
+ } else { /* read another chunk */
+
+ i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ *buf = '\0';
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return (num);
+ }
+ ctx->ibuf_len = i;
+ ctx->ibuf_off = 0;
+ }
+ }
+}
+
+static int buffer_puts(BIO *b, const char *str)
+{
+ return (buffer_write(b, str, strlen(str)));
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bf_nbio.c b/Cryptlib/OpenSSL/crypto/bio/bf_nbio.c
new file mode 100644
index 00000000..a04f32a0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bf_nbio.c
@@ -0,0 +1,253 @@
+/* crypto/bio/bf_nbio.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int nbiof_write(BIO *h, const char *buf, int num);
+static int nbiof_read(BIO *h, char *buf, int size);
+static int nbiof_puts(BIO *h, const char *str);
+static int nbiof_gets(BIO *h, char *str, int size);
+static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nbiof_new(BIO *h);
+static int nbiof_free(BIO *data);
+static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+typedef struct nbio_test_st {
+ /* only set if we sent a 'should retry' error */
+ int lrn;
+ int lwn;
+} NBIO_TEST;
+
+static BIO_METHOD methods_nbiof = {
+ BIO_TYPE_NBIO_TEST,
+ "non-blocking IO test filter",
+ nbiof_write,
+ nbiof_read,
+ nbiof_puts,
+ nbiof_gets,
+ nbiof_ctrl,
+ nbiof_new,
+ nbiof_free,
+ nbiof_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_nbio_test(void)
+{
+ return (&methods_nbiof);
+}
+
+static int nbiof_new(BIO *bi)
+{
+ NBIO_TEST *nt;
+
+ if (!(nt = (NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST))))
+ return (0);
+ nt->lrn = -1;
+ nt->lwn = -1;
+ bi->ptr = (char *)nt;
+ bi->init = 1;
+ bi->flags = 0;
+ return (1);
+}
+
+static int nbiof_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ if (a->ptr != NULL)
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int nbiof_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+#if 1
+ int num;
+ unsigned char n;
+#endif
+
+ if (out == NULL)
+ return (0);
+ if (b->next_bio == NULL)
+ return (0);
+
+ BIO_clear_retry_flags(b);
+#if 1
+ if (RAND_pseudo_bytes(&n, 1) < 0)
+ return -1;
+ num = (n & 0x07);
+
+ if (outl > num)
+ outl = num;
+
+ if (num == 0) {
+ ret = -1;
+ BIO_set_retry_read(b);
+ } else
+#endif
+ {
+ ret = BIO_read(b->next_bio, out, outl);
+ if (ret < 0)
+ BIO_copy_next_retry(b);
+ }
+ return (ret);
+}
+
+static int nbiof_write(BIO *b, const char *in, int inl)
+{
+ NBIO_TEST *nt;
+ int ret = 0;
+ int num;
+ unsigned char n;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+ if (b->next_bio == NULL)
+ return (0);
+ nt = (NBIO_TEST *)b->ptr;
+
+ BIO_clear_retry_flags(b);
+
+#if 1
+ if (nt->lwn > 0) {
+ num = nt->lwn;
+ nt->lwn = 0;
+ } else {
+ if (RAND_pseudo_bytes(&n, 1) < 0)
+ return -1;
+ num = (n & 7);
+ }
+
+ if (inl > num)
+ inl = num;
+
+ if (num == 0) {
+ ret = -1;
+ BIO_set_retry_write(b);
+ } else
+#endif
+ {
+ ret = BIO_write(b->next_bio, in, inl);
+ if (ret < 0) {
+ BIO_copy_next_retry(b);
+ nt->lwn = inl;
+ }
+ }
+ return (ret);
+}
+
+static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_DUP:
+ ret = 0L;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int nbiof_gets(BIO *bp, char *buf, int size)
+{
+ if (bp->next_bio == NULL)
+ return (0);
+ return (BIO_gets(bp->next_bio, buf, size));
+}
+
+static int nbiof_puts(BIO *bp, const char *str)
+{
+ if (bp->next_bio == NULL)
+ return (0);
+ return (BIO_puts(bp->next_bio, str));
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bf_null.c b/Cryptlib/OpenSSL/crypto/bio/bf_null.c
new file mode 100644
index 00000000..e0c79e82
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bf_null.c
@@ -0,0 +1,189 @@
+/* crypto/bio/bf_null.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int nullf_write(BIO *h, const char *buf, int num);
+static int nullf_read(BIO *h, char *buf, int size);
+static int nullf_puts(BIO *h, const char *str);
+static int nullf_gets(BIO *h, char *str, int size);
+static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nullf_new(BIO *h);
+static int nullf_free(BIO *data);
+static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+static BIO_METHOD methods_nullf = {
+ BIO_TYPE_NULL_FILTER,
+ "NULL filter",
+ nullf_write,
+ nullf_read,
+ nullf_puts,
+ nullf_gets,
+ nullf_ctrl,
+ nullf_new,
+ nullf_free,
+ nullf_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_null(void)
+{
+ return (&methods_nullf);
+}
+
+static int nullf_new(BIO *bi)
+{
+ bi->init = 1;
+ bi->ptr = NULL;
+ bi->flags = 0;
+ return (1);
+}
+
+static int nullf_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ /*-
+ a->ptr=NULL;
+ a->init=0;
+ a->flags=0;
+ */
+ return (1);
+}
+
+static int nullf_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out == NULL)
+ return (0);
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_read(b->next_bio, out, outl);
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static int nullf_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_write(b->next_bio, in, inl);
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_DUP:
+ ret = 0L;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ return (ret);
+}
+
+static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int nullf_gets(BIO *bp, char *buf, int size)
+{
+ if (bp->next_bio == NULL)
+ return (0);
+ return (BIO_gets(bp->next_bio, buf, size));
+}
+
+static int nullf_puts(BIO *bp, const char *str)
+{
+ if (bp->next_bio == NULL)
+ return (0);
+ return (BIO_puts(bp->next_bio, str));
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bio_cb.c b/Cryptlib/OpenSSL/crypto/bio/bio_cb.c
new file mode 100644
index 00000000..d3e86068
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bio_cb.c
@@ -0,0 +1,145 @@
+/* crypto/bio/bio_cb.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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp,
+ int argi, long argl, long ret)
+{
+ BIO *b;
+ MS_STATIC char buf[256];
+ char *p;
+ long r = 1;
+ int len;
+ size_t p_maxlen;
+
+ if (BIO_CB_RETURN & cmd)
+ r = ret;
+
+ len = BIO_snprintf(buf,sizeof buf,"BIO[%p]: ",(void *)bio);
+
+ p = buf + len;
+ p_maxlen = sizeof(buf) - len;
+
+ switch (cmd) {
+ case BIO_CB_FREE:
+ BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name);
+ break;
+ case BIO_CB_READ:
+ if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+ 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,%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,%lu) - %s fd=%d\n",
+ bio->num, (unsigned long)argi,
+ bio->method->name, bio->num);
+ else
+ 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(%lu) - %s\n", (unsigned long)argi,
+ bio->method->name);
+ break;
+ case BIO_CB_CTRL:
+ 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);
+ break;
+ case BIO_CB_RETURN | BIO_CB_WRITE:
+ BIO_snprintf(p, p_maxlen, "write return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_GETS:
+ BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_PUTS:
+ BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_CTRL:
+ BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret);
+ break;
+ default:
+ BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd);
+ break;
+ }
+
+ b = (BIO *)bio->cb_arg;
+ if (b != NULL)
+ BIO_write(b, buf, strlen(buf));
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+ else
+ fputs(buf, stderr);
+#endif
+ return (r);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bio_err.c b/Cryptlib/OpenSSL/crypto/bio/bio_err.c
new file mode 100644
index 00000000..d9007aa3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bio_err.c
@@ -0,0 +1,157 @@
+/* crypto/bio/bio_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2015 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
+
+static ERR_STRING_DATA BIO_str_functs[] = {
+ {ERR_FUNC(BIO_F_ACPT_STATE), "ACPT_STATE"},
+ {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"},
+ {ERR_FUNC(BIO_F_BIO_BER_GET_HEADER), "BIO_BER_GET_HEADER"},
+ {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"},
+ {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"},
+ {ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME), "BIO_gethostbyname"},
+ {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"},
+ {ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET), "BIO_get_accept_socket"},
+ {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"},
+ {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"},
+ {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "BIO_MAKE_PAIR"},
+ {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"},
+ {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"},
+ {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"},
+ {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"},
+ {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"},
+ {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"},
+ {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"},
+ {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"},
+ {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"},
+ {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"},
+ {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"},
+ {ERR_FUNC(BIO_F_BUFFER_CTRL), "BUFFER_CTRL"},
+ {ERR_FUNC(BIO_F_CONN_CTRL), "CONN_CTRL"},
+ {ERR_FUNC(BIO_F_CONN_STATE), "CONN_STATE"},
+ {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "DGRAM_SCTP_READ"},
+ {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "DGRAM_SCTP_WRITE"},
+ {ERR_FUNC(BIO_F_FILE_CTRL), "FILE_CTRL"},
+ {ERR_FUNC(BIO_F_FILE_READ), "FILE_READ"},
+ {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "LINEBUFFER_CTRL"},
+ {ERR_FUNC(BIO_F_MEM_READ), "MEM_READ"},
+ {ERR_FUNC(BIO_F_MEM_WRITE), "MEM_WRITE"},
+ {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"},
+ {ERR_FUNC(BIO_F_WSASTARTUP), "WSASTARTUP"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA BIO_str_reasons[] = {
+ {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"},
+ {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
+ {ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP), "bad hostname lookup"},
+ {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"},
+ {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"},
+ {ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO), "EOF on memory BIO"},
+ {ERR_REASON(BIO_R_ERROR_SETTING_NBIO), "error setting nbio"},
+ {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET),
+ "error setting nbio on accepted socket"},
+ {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET),
+ "error setting nbio on accept socket"},
+ {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
+ "gethostbyname addr is not af inet"},
+ {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"},
+ {ERR_REASON(BIO_R_INVALID_IP_ADDRESS), "invalid ip address"},
+ {ERR_REASON(BIO_R_IN_USE), "in use"},
+ {ERR_REASON(BIO_R_KEEPALIVE), "keepalive"},
+ {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"},
+ {ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"},
+ {ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED), "no hostname specified"},
+ {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"},
+ {ERR_REASON(BIO_R_NO_PORT_SPECIFIED), "no port specified"},
+ {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"},
+ {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"},
+ {ERR_REASON(BIO_R_TAG_MISMATCH), "tag mismatch"},
+ {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"},
+ {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"},
+ {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"},
+ {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"},
+ {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"},
+ {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"},
+ {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_BIO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, BIO_str_functs);
+ ERR_load_strings(0, BIO_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bio_lcl.h b/Cryptlib/OpenSSL/crypto/bio/bio_lcl.h
new file mode 100644
index 00000000..741884da
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bio_lcl.h
@@ -0,0 +1,36 @@
+#include <openssl/bio.h>
+
+#if BIO_FLAGS_UPLINK==0
+/* Shortcut UPLINK calls on most platforms... */
+# define UP_stdin stdin
+# define UP_stdout stdout
+# define UP_stderr stderr
+# define UP_fprintf fprintf
+# define UP_fgets fgets
+# define UP_fread fread
+# define UP_fwrite fwrite
+# undef UP_fsetmod
+# define UP_feof feof
+# define UP_fclose fclose
+
+# define UP_fopen fopen
+# define UP_fseek fseek
+# 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/Cryptlib/OpenSSL/crypto/bio/bio_lib.c b/Cryptlib/OpenSSL/crypto/bio/bio_lib.c
new file mode 100644
index 00000000..07934f8a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bio_lib.c
@@ -0,0 +1,596 @@
+/* crypto/bio/bio_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 <stdio.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/stack.h>
+
+BIO *BIO_new(BIO_METHOD *method)
+{
+ BIO *ret = NULL;
+
+ ret = (BIO *)OPENSSL_malloc(sizeof(BIO));
+ if (ret == NULL) {
+ BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ if (!BIO_set(ret, method)) {
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+ return (ret);
+}
+
+int BIO_set(BIO *bio, BIO_METHOD *method)
+{
+ bio->method = method;
+ bio->callback = NULL;
+ bio->cb_arg = NULL;
+ bio->init = 0;
+ bio->shutdown = 1;
+ bio->flags = 0;
+ bio->retry_reason = 0;
+ bio->num = 0;
+ bio->ptr = NULL;
+ bio->prev_bio = NULL;
+ bio->next_bio = NULL;
+ bio->references = 1;
+ bio->num_read = 0L;
+ bio->num_write = 0L;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+ if (method->create != NULL)
+ if (!method->create(bio)) {
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+ return (0);
+ }
+ return (1);
+}
+
+int BIO_free(BIO *a)
+{
+ int i;
+
+ if (a == NULL)
+ return (0);
+
+ i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
+#ifdef REF_PRINT
+ REF_PRINT("BIO", a);
+#endif
+ if (i > 0)
+ return (1);
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "BIO_free, bad reference count\n");
+ abort();
+ }
+#endif
+ if ((a->callback != NULL) &&
+ ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
+ return (i);
+
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
+
+ if ((a->method != NULL) && (a->method->destroy != NULL))
+ a->method->destroy(a);
+ OPENSSL_free(a);
+ return (1);
+}
+
+void BIO_vfree(BIO *a)
+{
+ BIO_free(a);
+}
+
+void BIO_clear_flags(BIO *b, int flags)
+{
+ b->flags &= ~flags;
+}
+
+int BIO_test_flags(const BIO *b, int flags)
+{
+ return (b->flags & flags);
+}
+
+void BIO_set_flags(BIO *b, int flags)
+{
+ b->flags |= flags;
+}
+
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
+ int, long, long) {
+ return b->callback;
+}
+
+void BIO_set_callback(BIO *b,
+ long (*cb) (struct bio_st *, int, const char *, int,
+ long, long))
+{
+ b->callback = cb;
+}
+
+void BIO_set_callback_arg(BIO *b, char *arg)
+{
+ b->cb_arg = arg;
+}
+
+char *BIO_get_callback_arg(const BIO *b)
+{
+ return b->cb_arg;
+}
+
+const char *BIO_method_name(const BIO *b)
+{
+ return b->method->name;
+}
+
+int BIO_method_type(const BIO *b)
+{
+ return b->method->type;
+}
+
+int BIO_read(BIO *b, void *out, int outl)
+{
+ int i;
+ long (*cb) (BIO *, int, const char *, int, long, long);
+
+ if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
+ BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
+ return (-2);
+ }
+
+ cb = b->callback;
+ if ((cb != NULL) &&
+ ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
+ return (i);
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
+ return (-2);
+ }
+
+ i = b->method->bread(b, out, outl);
+
+ if (i > 0)
+ b->num_read += (unsigned long)i;
+
+ if (cb != NULL)
+ i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i);
+ return (i);
+}
+
+int BIO_write(BIO *b, const void *in, int inl)
+{
+ int i;
+ long (*cb) (BIO *, int, const char *, int, long, long);
+
+ if (b == NULL)
+ return (0);
+
+ cb = b->callback;
+ if ((b->method == NULL) || (b->method->bwrite == NULL)) {
+ BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
+ return (-2);
+ }
+
+ if ((cb != NULL) &&
+ ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
+ return (i);
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
+ return (-2);
+ }
+
+ i = b->method->bwrite(b, in, inl);
+
+ if (i > 0)
+ b->num_write += (unsigned long)i;
+
+ if (cb != NULL)
+ i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i);
+ return (i);
+}
+
+int BIO_puts(BIO *b, const char *in)
+{
+ int i;
+ long (*cb) (BIO *, int, const char *, int, long, long);
+
+ if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
+ BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
+ return (-2);
+ }
+
+ cb = b->callback;
+
+ if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
+ return (i);
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
+ return (-2);
+ }
+
+ i = b->method->bputs(b, in);
+
+ if (i > 0)
+ b->num_write += (unsigned long)i;
+
+ if (cb != NULL)
+ i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i);
+ return (i);
+}
+
+int BIO_gets(BIO *b, char *in, int inl)
+{
+ int i;
+ long (*cb) (BIO *, int, const char *, int, long, long);
+
+ if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
+ BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
+ return (-2);
+ }
+
+ cb = b->callback;
+
+ if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
+ return (i);
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
+ return (-2);
+ }
+
+ i = b->method->bgets(b, in, inl);
+
+ if (cb != NULL)
+ i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i);
+ return (i);
+}
+
+int BIO_indent(BIO *b, int indent, int max)
+{
+ if (indent < 0)
+ indent = 0;
+ if (indent > max)
+ indent = max;
+ while (indent--)
+ if (BIO_puts(b, " ") != 1)
+ return 0;
+ return 1;
+}
+
+long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
+{
+ int i;
+
+ i = iarg;
+ return (BIO_ctrl(b, cmd, larg, (char *)&i));
+}
+
+char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
+{
+ char *p = NULL;
+
+ if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
+ return (NULL);
+ else
+ return (p);
+}
+
+long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
+{
+ long ret;
+ long (*cb) (BIO *, int, const char *, int, long, long);
+
+ if (b == NULL)
+ return (0);
+
+ if ((b->method == NULL) || (b->method->ctrl == NULL)) {
+ BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
+ return (-2);
+ }
+
+ cb = b->callback;
+
+ if ((cb != NULL) &&
+ ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
+ return (ret);
+
+ ret = b->method->ctrl(b, cmd, larg, parg);
+
+ if (cb != NULL)
+ ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret);
+ return (ret);
+}
+
+long BIO_callback_ctrl(BIO *b, int cmd,
+ void (*fp) (struct bio_st *, int, const char *, int,
+ long, long))
+{
+ long ret;
+ long (*cb) (BIO *, int, const char *, int, long, long);
+
+ if (b == NULL)
+ return (0);
+
+ if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
+ BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
+ return (-2);
+ }
+
+ cb = b->callback;
+
+ if ((cb != NULL) &&
+ ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
+ return (ret);
+
+ ret = b->method->callback_ctrl(b, cmd, fp);
+
+ if (cb != NULL)
+ ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
+ return (ret);
+}
+
+/*
+ * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
+ * do; but those macros have inappropriate return type, and for interfacing
+ * from other programming languages, C macros aren't much of a help anyway.
+ */
+size_t BIO_ctrl_pending(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+}
+
+size_t BIO_ctrl_wpending(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+}
+
+/* put the 'bio' on the end of b's list of operators */
+BIO *BIO_push(BIO *b, BIO *bio)
+{
+ BIO *lb;
+
+ if (b == NULL)
+ return (bio);
+ lb = b;
+ while (lb->next_bio != NULL)
+ lb = lb->next_bio;
+ lb->next_bio = bio;
+ if (bio != NULL)
+ bio->prev_bio = lb;
+ /* called to do internal processing */
+ BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
+ return (b);
+}
+
+/* Remove the first and return the rest */
+BIO *BIO_pop(BIO *b)
+{
+ BIO *ret;
+
+ if (b == NULL)
+ return (NULL);
+ ret = b->next_bio;
+
+ BIO_ctrl(b, BIO_CTRL_POP, 0, b);
+
+ if (b->prev_bio != NULL)
+ b->prev_bio->next_bio = b->next_bio;
+ if (b->next_bio != NULL)
+ b->next_bio->prev_bio = b->prev_bio;
+
+ b->next_bio = NULL;
+ b->prev_bio = NULL;
+ return (ret);
+}
+
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
+{
+ BIO *b, *last;
+
+ b = last = bio;
+ for (;;) {
+ if (!BIO_should_retry(b))
+ break;
+ last = b;
+ b = b->next_bio;
+ if (b == NULL)
+ break;
+ }
+ if (reason != NULL)
+ *reason = last->retry_reason;
+ return (last);
+}
+
+int BIO_get_retry_reason(BIO *bio)
+{
+ return (bio->retry_reason);
+}
+
+BIO *BIO_find_type(BIO *bio, int type)
+{
+ int mt, mask;
+
+ if (!bio)
+ return NULL;
+ mask = type & 0xff;
+ do {
+ if (bio->method != NULL) {
+ mt = bio->method->type;
+
+ if (!mask) {
+ if (mt & type)
+ return (bio);
+ } else if (mt == type)
+ return (bio);
+ }
+ bio = bio->next_bio;
+ } while (bio != NULL);
+ return (NULL);
+}
+
+BIO *BIO_next(BIO *b)
+{
+ if (!b)
+ return NULL;
+ return b->next_bio;
+}
+
+void BIO_free_all(BIO *bio)
+{
+ BIO *b;
+ int ref;
+
+ while (bio != NULL) {
+ b = bio;
+ ref = b->references;
+ bio = bio->next_bio;
+ BIO_free(b);
+ /* Since ref count > 1, don't free anyone else. */
+ if (ref > 1)
+ break;
+ }
+}
+
+BIO *BIO_dup_chain(BIO *in)
+{
+ BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
+
+ for (bio = in; bio != NULL; bio = bio->next_bio) {
+ if ((new_bio = BIO_new(bio->method)) == NULL)
+ goto err;
+ new_bio->callback = bio->callback;
+ new_bio->cb_arg = bio->cb_arg;
+ new_bio->init = bio->init;
+ new_bio->shutdown = bio->shutdown;
+ new_bio->flags = bio->flags;
+
+ /* This will let SSL_s_sock() work with stdin/stdout */
+ new_bio->num = bio->num;
+
+ if (!BIO_dup_state(bio, (char *)new_bio)) {
+ BIO_free(new_bio);
+ goto err;
+ }
+
+ /* copy app data */
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
+ &bio->ex_data)) {
+ BIO_free(new_bio);
+ goto err;
+ }
+
+ if (ret == NULL) {
+ eoc = new_bio;
+ ret = eoc;
+ } else {
+ BIO_push(eoc, new_bio);
+ eoc = new_bio;
+ }
+ }
+ return (ret);
+ err:
+ BIO_free_all(ret);
+
+ return (NULL);
+}
+
+void BIO_copy_next_retry(BIO *b)
+{
+ BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
+ b->retry_reason = b->next_bio->retry_reason;
+}
+
+int BIO_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_BIO, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int BIO_set_ex_data(BIO *bio, int idx, void *data)
+{
+ return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
+}
+
+void *BIO_get_ex_data(BIO *bio, int idx)
+{
+ return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
+}
+
+unsigned long BIO_number_read(BIO *bio)
+{
+ if (bio)
+ return bio->num_read;
+ return 0;
+}
+
+unsigned long BIO_number_written(BIO *bio)
+{
+ if (bio)
+ return bio->num_write;
+ return 0;
+}
+
+IMPLEMENT_STACK_OF(BIO)
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_acpt.c b/Cryptlib/OpenSSL/crypto/bio/bss_acpt.c
new file mode 100644
index 00000000..4a5e39bd
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_acpt.c
@@ -0,0 +1,463 @@
+/* crypto/bio/bss_acpt.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 <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+# ifdef OPENSSL_SYS_WIN16
+# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
+# else
+# define SOCKET_PROTOCOL IPPROTO_TCP
+# 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
+
+typedef struct bio_accept_st {
+ int state;
+ char *param_addr;
+ int accept_sock;
+ int accept_nbio;
+ char *addr;
+ int nbio;
+ /*
+ * If 0, it means normal, if 1, do a connect on bind failure, and if
+ * there is no-one listening, bind with SO_REUSEADDR. If 2, always use
+ * SO_REUSEADDR.
+ */
+ int bind_mode;
+ BIO *bio_chain;
+} BIO_ACCEPT;
+
+static int acpt_write(BIO *h, const char *buf, int num);
+static int acpt_read(BIO *h, char *buf, int size);
+static int acpt_puts(BIO *h, const char *str);
+static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+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);
+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
+# define ACPT_S_OK 3
+
+static BIO_METHOD methods_acceptp = {
+ BIO_TYPE_ACCEPT,
+ "socket accept",
+ acpt_write,
+ acpt_read,
+ acpt_puts,
+ NULL, /* connect_gets, */
+ acpt_ctrl,
+ acpt_new,
+ acpt_free,
+ NULL,
+};
+
+BIO_METHOD *BIO_s_accept(void)
+{
+ return (&methods_acceptp);
+}
+
+static int acpt_new(BIO *bi)
+{
+ BIO_ACCEPT *ba;
+
+ bi->init = 0;
+ bi->num = INVALID_SOCKET;
+ bi->flags = 0;
+ if ((ba = BIO_ACCEPT_new()) == NULL)
+ return (0);
+ bi->ptr = (char *)ba;
+ ba->state = ACPT_S_BEFORE;
+ bi->shutdown = 1;
+ return (1);
+}
+
+static BIO_ACCEPT *BIO_ACCEPT_new(void)
+{
+ BIO_ACCEPT *ret;
+
+ if ((ret = (BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL)
+ return (NULL);
+
+ memset(ret, 0, sizeof(BIO_ACCEPT));
+ ret->accept_sock = INVALID_SOCKET;
+ ret->bind_mode = BIO_BIND_NORMAL;
+ return (ret);
+}
+
+static void BIO_ACCEPT_free(BIO_ACCEPT *a)
+{
+ if (a == NULL)
+ return;
+
+ if (a->param_addr != NULL)
+ OPENSSL_free(a->param_addr);
+ if (a->addr != NULL)
+ OPENSSL_free(a->addr);
+ if (a->bio_chain != NULL)
+ BIO_free(a->bio_chain);
+ OPENSSL_free(a);
+}
+
+static void acpt_close_socket(BIO *bio)
+{
+ BIO_ACCEPT *c;
+
+ c = (BIO_ACCEPT *)bio->ptr;
+ if (c->accept_sock != INVALID_SOCKET) {
+ shutdown(c->accept_sock, 2);
+ closesocket(c->accept_sock);
+ c->accept_sock = INVALID_SOCKET;
+ bio->num = INVALID_SOCKET;
+ }
+}
+
+static int acpt_free(BIO *a)
+{
+ BIO_ACCEPT *data;
+
+ if (a == NULL)
+ return (0);
+ data = (BIO_ACCEPT *)a->ptr;
+
+ if (a->shutdown) {
+ acpt_close_socket(a);
+ BIO_ACCEPT_free(data);
+ a->ptr = NULL;
+ a->flags = 0;
+ a->init = 0;
+ }
+ return (1);
+}
+
+static int acpt_state(BIO *b, BIO_ACCEPT *c)
+{
+ BIO *bio = NULL, *dbio;
+ int s = -1;
+ int i;
+
+ again:
+ switch (c->state) {
+ case ACPT_S_BEFORE:
+ if (c->param_addr == NULL) {
+ BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED);
+ return (-1);
+ }
+ s = BIO_get_accept_socket(c->param_addr, c->bind_mode);
+ if (s == INVALID_SOCKET)
+ return (-1);
+
+ if (c->accept_nbio) {
+ if (!BIO_socket_nbio(s, 1)) {
+ closesocket(s);
+ BIOerr(BIO_F_ACPT_STATE,
+ BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
+ return (-1);
+ }
+ }
+ c->accept_sock = s;
+ b->num = s;
+ c->state = ACPT_S_GET_ACCEPT_SOCKET;
+ return (1);
+ /* break; */
+ case ACPT_S_GET_ACCEPT_SOCKET:
+ if (b->next_bio != NULL) {
+ c->state = ACPT_S_OK;
+ goto again;
+ }
+ BIO_clear_retry_flags(b);
+ b->retry_reason = 0;
+ i = BIO_accept(c->accept_sock, &(c->addr));
+
+ /* -2 return means we should retry */
+ if (i == -2) {
+ BIO_set_retry_special(b);
+ b->retry_reason = BIO_RR_ACCEPT;
+ return -1;
+ }
+
+ if (i < 0)
+ return (i);
+
+ bio = BIO_new_socket(i, BIO_CLOSE);
+ if (bio == NULL)
+ goto err;
+
+ BIO_set_callback(bio, BIO_get_callback(b));
+ BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
+
+ if (c->nbio) {
+ if (!BIO_socket_nbio(i, 1)) {
+ BIOerr(BIO_F_ACPT_STATE,
+ BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
+ goto err;
+ }
+ }
+
+ /*
+ * If the accept BIO has an bio_chain, we dup it and put the new
+ * socket at the end.
+ */
+ if (c->bio_chain != NULL) {
+ if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
+ goto err;
+ if (!BIO_push(dbio, bio))
+ goto err;
+ bio = dbio;
+ }
+ if (BIO_push(b, bio) == NULL)
+ goto err;
+
+ c->state = ACPT_S_OK;
+ return (1);
+ err:
+ if (bio != NULL)
+ BIO_free(bio);
+ else if (s >= 0)
+ closesocket(s);
+ return (0);
+ /* break; */
+ case ACPT_S_OK:
+ if (b->next_bio == NULL) {
+ c->state = ACPT_S_GET_ACCEPT_SOCKET;
+ goto again;
+ }
+ return (1);
+ /* break; */
+ default:
+ return (0);
+ /* break; */
+ }
+
+}
+
+static int acpt_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ BIO_ACCEPT *data;
+
+ BIO_clear_retry_flags(b);
+ data = (BIO_ACCEPT *)b->ptr;
+
+ while (b->next_bio == NULL) {
+ ret = acpt_state(b, data);
+ if (ret <= 0)
+ return (ret);
+ }
+
+ ret = BIO_read(b->next_bio, out, outl);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static int acpt_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ BIO_ACCEPT *data;
+
+ BIO_clear_retry_flags(b);
+ data = (BIO_ACCEPT *)b->ptr;
+
+ while (b->next_bio == NULL) {
+ ret = acpt_state(b, data);
+ if (ret <= 0)
+ return (ret);
+ }
+
+ ret = BIO_write(b->next_bio, in, inl);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ int *ip;
+ long ret = 1;
+ BIO_ACCEPT *data;
+ char **pp;
+
+ data = (BIO_ACCEPT *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ret = 0;
+ data->state = ACPT_S_BEFORE;
+ acpt_close_socket(b);
+ b->flags = 0;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ /* use this one to start the connection */
+ ret = (long)acpt_state(b, data);
+ break;
+ case BIO_C_SET_ACCEPT:
+ if (ptr != NULL) {
+ if (num == 0) {
+ b->init = 1;
+ if (data->param_addr != NULL)
+ OPENSSL_free(data->param_addr);
+ data->param_addr = BUF_strdup(ptr);
+ } else if (num == 1) {
+ data->accept_nbio = (ptr != NULL);
+ } else if (num == 2) {
+ if (data->bio_chain != NULL)
+ BIO_free(data->bio_chain);
+ data->bio_chain = (BIO *)ptr;
+ }
+ }
+ break;
+ case BIO_C_SET_NBIO:
+ data->nbio = (int)num;
+ break;
+ case BIO_C_SET_FD:
+ b->init = 1;
+ b->num = *((int *)ptr);
+ data->accept_sock = b->num;
+ data->state = ACPT_S_GET_ACCEPT_SOCKET;
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = data->accept_sock;
+ ret = data->accept_sock;
+ } else
+ ret = -1;
+ break;
+ case BIO_C_GET_ACCEPT:
+ if (b->init) {
+ if (ptr != NULL) {
+ pp = (char **)ptr;
+ *pp = data->param_addr;
+ } else
+ ret = -1;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_FLUSH:
+ break;
+ case BIO_C_SET_BIND_MODE:
+ data->bind_mode = (int)num;
+ break;
+ case BIO_C_GET_BIND_MODE:
+ ret = (long)data->bind_mode;
+ break;
+ case BIO_CTRL_DUP:
+/*- dbio=(BIO *)ptr;
+ if (data->param_port) EAY EAY
+ BIO_set_port(dbio,data->param_port);
+ if (data->param_hostname)
+ BIO_set_hostname(dbio,data->param_hostname);
+ BIO_set_nbio(dbio,data->nbio); */
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int acpt_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = acpt_write(bp, str, n);
+ return (ret);
+}
+
+BIO *BIO_new_accept(const char *str)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_accept());
+ if (ret == NULL)
+ return (NULL);
+ if (BIO_set_accept_port(ret, str))
+ return (ret);
+ else {
+ BIO_free(ret);
+ return (NULL);
+ }
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_bio.c b/Cryptlib/OpenSSL/crypto/bio/bss_bio.c
new file mode 100644
index 00000000..4d8727f8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_bio.c
@@ -0,0 +1,886 @@
+/* crypto/bio/bss_bio.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).
+ *
+ */
+
+/*
+ * Special method for a BIO where the other endpoint is also a BIO of this
+ * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
+ * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
+ * library with I/O interfaces for which no specific BIO method is available.
+ * See ssl/ssltest.c for some hints on how this can be used.
+ */
+
+/* BIO_DEBUG implies BIO_PAIR_DEBUG */
+#ifdef BIO_DEBUG
+# ifndef BIO_PAIR_DEBUG
+# define BIO_PAIR_DEBUG
+# endif
+#endif
+
+/* disable assert() unless BIO_PAIR_DEBUG has been defined */
+#ifndef BIO_PAIR_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+#include "e_os.h"
+
+/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
+#if defined(OPENSSL_SYS_VXWORKS)
+# undef SSIZE_MAX
+#endif
+#ifndef SSIZE_MAX
+# define SSIZE_MAX INT_MAX
+#endif
+
+static int bio_new(BIO *bio);
+static int bio_free(BIO *bio);
+static int bio_read(BIO *bio, char *buf, int size);
+static int bio_write(BIO *bio, const char *buf, int num);
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static int bio_puts(BIO *bio, const char *str);
+
+static int bio_make_pair(BIO *bio1, BIO *bio2);
+static void bio_destroy_pair(BIO *bio);
+
+static BIO_METHOD methods_biop = {
+ BIO_TYPE_BIO,
+ "BIO pair",
+ bio_write,
+ bio_read,
+ bio_puts,
+ NULL /* no bio_gets */ ,
+ bio_ctrl,
+ bio_new,
+ bio_free,
+ NULL /* no bio_callback_ctrl */
+};
+
+BIO_METHOD *BIO_s_bio(void)
+{
+ return &methods_biop;
+}
+
+struct bio_bio_st {
+ BIO *peer; /* NULL if buf == NULL. If peer != NULL, then
+ * peer->ptr is also a bio_bio_st, and its
+ * "peer" member points back to us. peer !=
+ * NULL iff init != 0 in the BIO. */
+ /* This is for what we write (i.e. reading uses peer's struct): */
+ int closed; /* valid iff peer != NULL */
+ size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
+ size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
+ size_t size;
+ char *buf; /* "size" elements (if != NULL) */
+ size_t request; /* valid iff peer != NULL; 0 if len != 0,
+ * otherwise set by peer to number of bytes
+ * it (unsuccessfully) tried to read, never
+ * more than buffer space (size-len)
+ * warrants. */
+};
+
+static int bio_new(BIO *bio)
+{
+ struct bio_bio_st *b;
+
+ b = OPENSSL_malloc(sizeof *b);
+ if (b == NULL)
+ return 0;
+
+ b->peer = NULL;
+ /* enough for one TLS record (just a default) */
+ b->size = 17 * 1024;
+ b->buf = NULL;
+
+ bio->ptr = b;
+ return 1;
+}
+
+static int bio_free(BIO *bio)
+{
+ struct bio_bio_st *b;
+
+ if (bio == NULL)
+ return 0;
+ b = bio->ptr;
+
+ assert(b != NULL);
+
+ if (b->peer)
+ bio_destroy_pair(bio);
+
+ if (b->buf != NULL) {
+ OPENSSL_free(b->buf);
+ }
+
+ OPENSSL_free(b);
+
+ return 1;
+}
+
+static int bio_read(BIO *bio, char *buf, int size_)
+{
+ size_t size = size_;
+ size_t rest;
+ struct bio_bio_st *b, *peer_b;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ peer_b = b->peer->ptr;
+ assert(peer_b != NULL);
+ assert(peer_b->buf != NULL);
+
+ peer_b->request = 0; /* will be set in "retry_read" situation */
+
+ if (buf == NULL || size == 0)
+ return 0;
+
+ if (peer_b->len == 0) {
+ if (peer_b->closed)
+ return 0; /* writer has closed, and no data is left */
+ else {
+ BIO_set_retry_read(bio); /* buffer is empty */
+ if (size <= peer_b->size)
+ peer_b->request = size;
+ else
+ /*
+ * don't ask for more than the peer can deliver in one write
+ */
+ peer_b->request = peer_b->size;
+ return -1;
+ }
+ }
+
+ /* we can read */
+ if (peer_b->len < size)
+ size = peer_b->len;
+
+ /* now read "size" bytes */
+
+ rest = size;
+
+ assert(rest > 0);
+ do { /* one or two iterations */
+ size_t chunk;
+
+ assert(rest <= peer_b->len);
+ if (peer_b->offset + rest <= peer_b->size)
+ chunk = rest;
+ else
+ /* wrap around ring buffer */
+ chunk = peer_b->size - peer_b->offset;
+ assert(peer_b->offset + chunk <= peer_b->size);
+
+ memcpy(buf, peer_b->buf + peer_b->offset, chunk);
+
+ peer_b->len -= chunk;
+ if (peer_b->len) {
+ peer_b->offset += chunk;
+ assert(peer_b->offset <= peer_b->size);
+ if (peer_b->offset == peer_b->size)
+ peer_b->offset = 0;
+ buf += chunk;
+ } else {
+ /* buffer now empty, no need to advance "buf" */
+ assert(chunk == rest);
+ peer_b->offset = 0;
+ }
+ rest -= chunk;
+ }
+ while (rest);
+
+ return size;
+}
+
+/*-
+ * non-copying interface: provide pointer to available data in buffer
+ * bio_nread0: return number of available bytes
+ * bio_nread: also advance index
+ * (example usage: bio_nread0(), read from buffer, bio_nread()
+ * or just bio_nread(), read from buffer)
+ */
+/*
+ * WARNING: The non-copying interface is largely untested as of yet and may
+ * contain bugs.
+ */
+static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
+{
+ struct bio_bio_st *b, *peer_b;
+ ossl_ssize_t num;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ peer_b = b->peer->ptr;
+ assert(peer_b != NULL);
+ assert(peer_b->buf != NULL);
+
+ peer_b->request = 0;
+
+ if (peer_b->len == 0) {
+ char dummy;
+
+ /* avoid code duplication -- nothing available for reading */
+ return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
+ }
+
+ num = peer_b->len;
+ if (peer_b->size < peer_b->offset + num)
+ /* no ring buffer wrap-around for non-copying interface */
+ num = peer_b->size - peer_b->offset;
+ assert(num > 0);
+
+ if (buf != NULL)
+ *buf = peer_b->buf + peer_b->offset;
+ return num;
+}
+
+static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
+{
+ struct bio_bio_st *b, *peer_b;
+ ossl_ssize_t num, available;
+
+ if (num_ > SSIZE_MAX)
+ num = SSIZE_MAX;
+ else
+ num = (ossl_ssize_t) num_;
+
+ available = bio_nread0(bio, buf);
+ if (num > available)
+ num = available;
+ if (num <= 0)
+ return num;
+
+ b = bio->ptr;
+ peer_b = b->peer->ptr;
+
+ peer_b->len -= num;
+ if (peer_b->len) {
+ peer_b->offset += num;
+ assert(peer_b->offset <= peer_b->size);
+ if (peer_b->offset == peer_b->size)
+ peer_b->offset = 0;
+ } else
+ peer_b->offset = 0;
+
+ return num;
+}
+
+static int bio_write(BIO *bio, const char *buf, int num_)
+{
+ size_t num = num_;
+ size_t rest;
+ struct bio_bio_st *b;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init || buf == NULL || num == 0)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ assert(b->buf != NULL);
+
+ b->request = 0;
+ if (b->closed) {
+ /* we already closed */
+ BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
+ return -1;
+ }
+
+ assert(b->len <= b->size);
+
+ if (b->len == b->size) {
+ BIO_set_retry_write(bio); /* buffer is full */
+ return -1;
+ }
+
+ /* we can write */
+ if (num > b->size - b->len)
+ num = b->size - b->len;
+
+ /* now write "num" bytes */
+
+ rest = num;
+
+ assert(rest > 0);
+ do { /* one or two iterations */
+ size_t write_offset;
+ size_t chunk;
+
+ assert(b->len + rest <= b->size);
+
+ write_offset = b->offset + b->len;
+ if (write_offset >= b->size)
+ write_offset -= b->size;
+ /* b->buf[write_offset] is the first byte we can write to. */
+
+ if (write_offset + rest <= b->size)
+ chunk = rest;
+ else
+ /* wrap around ring buffer */
+ chunk = b->size - write_offset;
+
+ memcpy(b->buf + write_offset, buf, chunk);
+
+ b->len += chunk;
+
+ assert(b->len <= b->size);
+
+ rest -= chunk;
+ buf += chunk;
+ }
+ while (rest);
+
+ return num;
+}
+
+/*-
+ * non-copying interface: provide pointer to region to write to
+ * bio_nwrite0: check how much space is available
+ * bio_nwrite: also increase length
+ * (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
+ * or just bio_nwrite(), write to buffer)
+ */
+static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
+{
+ struct bio_bio_st *b;
+ size_t num;
+ size_t write_offset;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ assert(b->buf != NULL);
+
+ b->request = 0;
+ if (b->closed) {
+ BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
+ return -1;
+ }
+
+ assert(b->len <= b->size);
+
+ if (b->len == b->size) {
+ BIO_set_retry_write(bio);
+ return -1;
+ }
+
+ num = b->size - b->len;
+ write_offset = b->offset + b->len;
+ if (write_offset >= b->size)
+ write_offset -= b->size;
+ if (write_offset + num > b->size)
+ /*
+ * no ring buffer wrap-around for non-copying interface (to fulfil
+ * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
+ * to be called twice)
+ */
+ num = b->size - write_offset;
+
+ if (buf != NULL)
+ *buf = b->buf + write_offset;
+ assert(write_offset + num <= b->size);
+
+ return num;
+}
+
+static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
+{
+ struct bio_bio_st *b;
+ ossl_ssize_t num, space;
+
+ if (num_ > SSIZE_MAX)
+ num = SSIZE_MAX;
+ else
+ num = (ossl_ssize_t) num_;
+
+ space = bio_nwrite0(bio, buf);
+ if (num > space)
+ num = space;
+ if (num <= 0)
+ return num;
+ b = bio->ptr;
+ assert(b != NULL);
+ b->len += num;
+ assert(b->len <= b->size);
+
+ return num;
+}
+
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ long ret;
+ struct bio_bio_st *b = bio->ptr;
+
+ assert(b != NULL);
+
+ switch (cmd) {
+ /* specific CTRL codes */
+
+ case BIO_C_SET_WRITE_BUF_SIZE:
+ if (b->peer) {
+ BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
+ ret = 0;
+ } else if (num == 0) {
+ BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
+ ret = 0;
+ } else {
+ size_t new_size = num;
+
+ if (b->size != new_size) {
+ if (b->buf) {
+ OPENSSL_free(b->buf);
+ b->buf = NULL;
+ }
+ b->size = new_size;
+ }
+ ret = 1;
+ }
+ break;
+
+ case BIO_C_GET_WRITE_BUF_SIZE:
+ ret = (long)b->size;
+ break;
+
+ case BIO_C_MAKE_BIO_PAIR:
+ {
+ BIO *other_bio = ptr;
+
+ if (bio_make_pair(bio, other_bio))
+ ret = 1;
+ else
+ ret = 0;
+ }
+ break;
+
+ case BIO_C_DESTROY_BIO_PAIR:
+ /*
+ * Affects both BIOs in the pair -- call just once! Or let
+ * BIO_free(bio1); BIO_free(bio2); do the job.
+ */
+ bio_destroy_pair(bio);
+ ret = 1;
+ break;
+
+ case BIO_C_GET_WRITE_GUARANTEE:
+ /*
+ * How many bytes can the caller feed to the next write without
+ * having to keep any?
+ */
+ if (b->peer == NULL || b->closed)
+ ret = 0;
+ else
+ ret = (long)b->size - b->len;
+ break;
+
+ case BIO_C_GET_READ_REQUEST:
+ /*
+ * If the peer unsuccessfully tried to read, how many bytes were
+ * requested? (As with BIO_CTRL_PENDING, that number can usually be
+ * treated as boolean.)
+ */
+ ret = (long)b->request;
+ break;
+
+ case BIO_C_RESET_READ_REQUEST:
+ /*
+ * Reset request. (Can be useful after read attempts at the other
+ * side that are meant to be non-blocking, e.g. when probing SSL_read
+ * to see if any data is available.)
+ */
+ b->request = 0;
+ ret = 1;
+ break;
+
+ case BIO_C_SHUTDOWN_WR:
+ /* similar to shutdown(..., SHUT_WR) */
+ b->closed = 1;
+ ret = 1;
+ break;
+
+ case BIO_C_NREAD0:
+ /* prepare for non-copying read */
+ ret = (long)bio_nread0(bio, ptr);
+ break;
+
+ case BIO_C_NREAD:
+ /* non-copying read */
+ ret = (long)bio_nread(bio, ptr, (size_t)num);
+ break;
+
+ case BIO_C_NWRITE0:
+ /* prepare for non-copying write */
+ ret = (long)bio_nwrite0(bio, ptr);
+ break;
+
+ case BIO_C_NWRITE:
+ /* non-copying write */
+ ret = (long)bio_nwrite(bio, ptr, (size_t)num);
+ break;
+
+ /* standard CTRL codes follow */
+
+ case BIO_CTRL_RESET:
+ if (b->buf != NULL) {
+ b->len = 0;
+ b->offset = 0;
+ }
+ ret = 0;
+ break;
+
+ case BIO_CTRL_GET_CLOSE:
+ ret = bio->shutdown;
+ break;
+
+ case BIO_CTRL_SET_CLOSE:
+ bio->shutdown = (int)num;
+ ret = 1;
+ break;
+
+ case BIO_CTRL_PENDING:
+ if (b->peer != NULL) {
+ struct bio_bio_st *peer_b = b->peer->ptr;
+
+ ret = (long)peer_b->len;
+ } else
+ ret = 0;
+ break;
+
+ case BIO_CTRL_WPENDING:
+ if (b->buf != NULL)
+ ret = (long)b->len;
+ else
+ ret = 0;
+ break;
+
+ case BIO_CTRL_DUP:
+ /* See BIO_dup_chain for circumstances we have to expect. */
+ {
+ BIO *other_bio = ptr;
+ struct bio_bio_st *other_b;
+
+ assert(other_bio != NULL);
+ other_b = other_bio->ptr;
+ assert(other_b != NULL);
+
+ assert(other_b->buf == NULL); /* other_bio is always fresh */
+
+ other_b->size = b->size;
+ }
+
+ ret = 1;
+ break;
+
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+
+ case BIO_CTRL_EOF:
+ {
+ BIO *other_bio = ptr;
+
+ if (other_bio) {
+ struct bio_bio_st *other_b = other_bio->ptr;
+
+ assert(other_b != NULL);
+ ret = other_b->len == 0 && other_b->closed;
+ } else
+ ret = 1;
+ }
+ break;
+
+ default:
+ ret = 0;
+ }
+ return ret;
+}
+
+static int bio_puts(BIO *bio, const char *str)
+{
+ return bio_write(bio, str, strlen(str));
+}
+
+static int bio_make_pair(BIO *bio1, BIO *bio2)
+{
+ struct bio_bio_st *b1, *b2;
+
+ assert(bio1 != NULL);
+ assert(bio2 != NULL);
+
+ b1 = bio1->ptr;
+ b2 = bio2->ptr;
+
+ if (b1->peer != NULL || b2->peer != NULL) {
+ BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
+ return 0;
+ }
+
+ if (b1->buf == NULL) {
+ b1->buf = OPENSSL_malloc(b1->size);
+ if (b1->buf == NULL) {
+ BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ b1->len = 0;
+ b1->offset = 0;
+ }
+
+ if (b2->buf == NULL) {
+ b2->buf = OPENSSL_malloc(b2->size);
+ if (b2->buf == NULL) {
+ BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ b2->len = 0;
+ b2->offset = 0;
+ }
+
+ b1->peer = bio2;
+ b1->closed = 0;
+ b1->request = 0;
+ b2->peer = bio1;
+ b2->closed = 0;
+ b2->request = 0;
+
+ bio1->init = 1;
+ bio2->init = 1;
+
+ return 1;
+}
+
+static void bio_destroy_pair(BIO *bio)
+{
+ struct bio_bio_st *b = bio->ptr;
+
+ if (b != NULL) {
+ BIO *peer_bio = b->peer;
+
+ if (peer_bio != NULL) {
+ struct bio_bio_st *peer_b = peer_bio->ptr;
+
+ assert(peer_b != NULL);
+ assert(peer_b->peer == bio);
+
+ peer_b->peer = NULL;
+ peer_bio->init = 0;
+ assert(peer_b->buf != NULL);
+ peer_b->len = 0;
+ peer_b->offset = 0;
+
+ b->peer = NULL;
+ bio->init = 0;
+ assert(b->buf != NULL);
+ b->len = 0;
+ b->offset = 0;
+ }
+ }
+}
+
+/* Exported convenience functions */
+int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
+ BIO **bio2_p, size_t writebuf2)
+{
+ BIO *bio1 = NULL, *bio2 = NULL;
+ long r;
+ int ret = 0;
+
+ bio1 = BIO_new(BIO_s_bio());
+ if (bio1 == NULL)
+ goto err;
+ bio2 = BIO_new(BIO_s_bio());
+ if (bio2 == NULL)
+ goto err;
+
+ if (writebuf1) {
+ r = BIO_set_write_buf_size(bio1, writebuf1);
+ if (!r)
+ goto err;
+ }
+ if (writebuf2) {
+ r = BIO_set_write_buf_size(bio2, writebuf2);
+ if (!r)
+ goto err;
+ }
+
+ r = BIO_make_bio_pair(bio1, bio2);
+ if (!r)
+ goto err;
+ ret = 1;
+
+ err:
+ if (ret == 0) {
+ if (bio1) {
+ BIO_free(bio1);
+ bio1 = NULL;
+ }
+ if (bio2) {
+ BIO_free(bio2);
+ bio2 = NULL;
+ }
+ }
+
+ *bio1_p = bio1;
+ *bio2_p = bio2;
+ return ret;
+}
+
+size_t BIO_ctrl_get_write_guarantee(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
+}
+
+size_t BIO_ctrl_get_read_request(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
+}
+
+int BIO_ctrl_reset_read_request(BIO *bio)
+{
+ return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+}
+
+/*
+ * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
+ * (conceivably some other BIOs could allow non-copying reads and writes
+ * too.)
+ */
+int BIO_nread0(BIO *bio, char **buf)
+{
+ long ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
+ if (ret > INT_MAX)
+ return INT_MAX;
+ else
+ return (int)ret;
+}
+
+int BIO_nread(BIO *bio, char **buf, int num)
+{
+ int ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
+ if (ret > 0)
+ bio->num_read += ret;
+ return ret;
+}
+
+int BIO_nwrite0(BIO *bio, char **buf)
+{
+ long ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
+ if (ret > INT_MAX)
+ return INT_MAX;
+ else
+ return (int)ret;
+}
+
+int BIO_nwrite(BIO *bio, char **buf, int num)
+{
+ int ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
+ if (ret > 0)
+ bio->num_write += ret;
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_conn.c b/Cryptlib/OpenSSL/crypto/bio/bss_conn.c
new file mode 100644
index 00000000..7d15ad29
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_conn.c
@@ -0,0 +1,612 @@
+/* crypto/bio/bss_conn.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 <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+# ifdef OPENSSL_SYS_WIN16
+# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
+# else
+# define SOCKET_PROTOCOL IPPROTO_TCP
+# 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
+
+typedef struct bio_connect_st {
+ int state;
+ char *param_hostname;
+ char *param_port;
+ int nbio;
+ unsigned char ip[4];
+ unsigned short port;
+ struct sockaddr_in them;
+ /*
+ * int socket; this will be kept in bio->num so that it is compatible
+ * with the bss_sock bio
+ */
+ /*
+ * called when the connection is initially made callback(BIO,state,ret);
+ * The callback should return 'ret'. state is for compatibility with the
+ * ssl info_callback
+ */
+ int (*info_callback) (const BIO *bio, int state, int ret);
+} BIO_CONNECT;
+
+static int conn_write(BIO *h, const char *buf, int num);
+static int conn_read(BIO *h, char *buf, int size);
+static int conn_puts(BIO *h, const char *str);
+static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int conn_new(BIO *h);
+static int conn_free(BIO *data);
+static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
+
+static int conn_state(BIO *b, BIO_CONNECT *c);
+static void conn_close_socket(BIO *data);
+BIO_CONNECT *BIO_CONNECT_new(void);
+void BIO_CONNECT_free(BIO_CONNECT *a);
+
+static BIO_METHOD methods_connectp = {
+ BIO_TYPE_CONNECT,
+ "socket connect",
+ conn_write,
+ conn_read,
+ conn_puts,
+ NULL, /* connect_gets, */
+ conn_ctrl,
+ conn_new,
+ conn_free,
+ conn_callback_ctrl,
+};
+
+static int conn_state(BIO *b, BIO_CONNECT *c)
+{
+ int ret = -1, i;
+ unsigned long l;
+ char *p, *q;
+ int (*cb) (const BIO *, int, int) = NULL;
+
+ if (c->info_callback != NULL)
+ cb = c->info_callback;
+
+ for (;;) {
+ switch (c->state) {
+ case BIO_CONN_S_BEFORE:
+ p = c->param_hostname;
+ if (p == NULL) {
+ BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED);
+ goto exit_loop;
+ }
+ for (; *p != '\0'; p++) {
+ if ((*p == ':') || (*p == '/'))
+ break;
+ }
+
+ i = *p;
+ if ((i == ':') || (i == '/')) {
+
+ *(p++) = '\0';
+ if (i == ':') {
+ for (q = p; *q; q++)
+ if (*q == '/') {
+ *q = '\0';
+ break;
+ }
+ if (c->param_port != NULL)
+ OPENSSL_free(c->param_port);
+ c->param_port = BUF_strdup(p);
+ }
+ }
+
+ if (c->param_port == NULL) {
+ BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED);
+ ERR_add_error_data(2, "host=", c->param_hostname);
+ goto exit_loop;
+ }
+ c->state = BIO_CONN_S_GET_IP;
+ break;
+
+ case BIO_CONN_S_GET_IP:
+ if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0)
+ goto exit_loop;
+ c->state = BIO_CONN_S_GET_PORT;
+ break;
+
+ case BIO_CONN_S_GET_PORT:
+ if (c->param_port == NULL) {
+ /* abort(); */
+ goto exit_loop;
+ } else if (BIO_get_port(c->param_port, &c->port) <= 0)
+ goto exit_loop;
+ c->state = BIO_CONN_S_CREATE_SOCKET;
+ break;
+
+ case BIO_CONN_S_CREATE_SOCKET:
+ /* now setup address */
+ memset((char *)&c->them, 0, sizeof(c->them));
+ c->them.sin_family = AF_INET;
+ c->them.sin_port = htons((unsigned short)c->port);
+ l = (unsigned long)
+ ((unsigned long)c->ip[0] << 24L) |
+ ((unsigned long)c->ip[1] << 16L) |
+ ((unsigned long)c->ip[2] << 8L) | ((unsigned long)c->ip[3]);
+ c->them.sin_addr.s_addr = htonl(l);
+ c->state = BIO_CONN_S_CREATE_SOCKET;
+
+ ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
+ if (ret == INVALID_SOCKET) {
+ SYSerr(SYS_F_SOCKET, get_last_socket_error());
+ ERR_add_error_data(4, "host=", c->param_hostname,
+ ":", c->param_port);
+ BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ goto exit_loop;
+ }
+ b->num = ret;
+ c->state = BIO_CONN_S_NBIO;
+ break;
+
+ case BIO_CONN_S_NBIO:
+ if (c->nbio) {
+ if (!BIO_socket_nbio(b->num, 1)) {
+ BIOerr(BIO_F_CONN_STATE, BIO_R_ERROR_SETTING_NBIO);
+ ERR_add_error_data(4, "host=",
+ c->param_hostname, ":", c->param_port);
+ goto exit_loop;
+ }
+ }
+ c->state = BIO_CONN_S_CONNECT;
+
+# if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
+ i = 1;
+ i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
+ sizeof(i));
+ if (i < 0) {
+ SYSerr(SYS_F_SOCKET, get_last_socket_error());
+ ERR_add_error_data(4, "host=", c->param_hostname,
+ ":", c->param_port);
+ BIOerr(BIO_F_CONN_STATE, BIO_R_KEEPALIVE);
+ goto exit_loop;
+ }
+# endif
+ break;
+
+ case BIO_CONN_S_CONNECT:
+ BIO_clear_retry_flags(b);
+ ret = connect(b->num,
+ (struct sockaddr *)&c->them, sizeof(c->them));
+ b->retry_reason = 0;
+ if (ret < 0) {
+ if (BIO_sock_should_retry(ret)) {
+ BIO_set_retry_special(b);
+ c->state = BIO_CONN_S_BLOCKED_CONNECT;
+ b->retry_reason = BIO_RR_CONNECT;
+ } else {
+ SYSerr(SYS_F_CONNECT, get_last_socket_error());
+ ERR_add_error_data(4, "host=",
+ c->param_hostname, ":", c->param_port);
+ BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
+ }
+ goto exit_loop;
+ } else
+ c->state = BIO_CONN_S_OK;
+ break;
+
+ case BIO_CONN_S_BLOCKED_CONNECT:
+ i = BIO_sock_error(b->num);
+ if (i) {
+ BIO_clear_retry_flags(b);
+ SYSerr(SYS_F_CONNECT, i);
+ ERR_add_error_data(4, "host=",
+ c->param_hostname, ":", c->param_port);
+ BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
+ ret = 0;
+ goto exit_loop;
+ } else
+ c->state = BIO_CONN_S_OK;
+ break;
+
+ case BIO_CONN_S_OK:
+ ret = 1;
+ goto exit_loop;
+ default:
+ /* abort(); */
+ goto exit_loop;
+ }
+
+ if (cb != NULL) {
+ if (!(ret = cb((BIO *)b, c->state, ret)))
+ goto end;
+ }
+ }
+
+ /* Loop does not exit */
+ exit_loop:
+ if (cb != NULL)
+ ret = cb((BIO *)b, c->state, ret);
+ end:
+ return (ret);
+}
+
+BIO_CONNECT *BIO_CONNECT_new(void)
+{
+ BIO_CONNECT *ret;
+
+ if ((ret = (BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL)
+ return (NULL);
+ ret->state = BIO_CONN_S_BEFORE;
+ ret->param_hostname = NULL;
+ ret->param_port = NULL;
+ ret->info_callback = NULL;
+ ret->nbio = 0;
+ ret->ip[0] = 0;
+ ret->ip[1] = 0;
+ ret->ip[2] = 0;
+ ret->ip[3] = 0;
+ ret->port = 0;
+ memset((char *)&ret->them, 0, sizeof(ret->them));
+ return (ret);
+}
+
+void BIO_CONNECT_free(BIO_CONNECT *a)
+{
+ if (a == NULL)
+ return;
+
+ if (a->param_hostname != NULL)
+ OPENSSL_free(a->param_hostname);
+ if (a->param_port != NULL)
+ OPENSSL_free(a->param_port);
+ OPENSSL_free(a);
+}
+
+BIO_METHOD *BIO_s_connect(void)
+{
+ return (&methods_connectp);
+}
+
+static int conn_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = INVALID_SOCKET;
+ bi->flags = 0;
+ if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
+ return (0);
+ else
+ return (1);
+}
+
+static void conn_close_socket(BIO *bio)
+{
+ BIO_CONNECT *c;
+
+ c = (BIO_CONNECT *)bio->ptr;
+ if (bio->num != INVALID_SOCKET) {
+ /* Only do a shutdown if things were established */
+ if (c->state == BIO_CONN_S_OK)
+ shutdown(bio->num, 2);
+ closesocket(bio->num);
+ bio->num = INVALID_SOCKET;
+ }
+}
+
+static int conn_free(BIO *a)
+{
+ BIO_CONNECT *data;
+
+ if (a == NULL)
+ return (0);
+ data = (BIO_CONNECT *)a->ptr;
+
+ if (a->shutdown) {
+ conn_close_socket(a);
+ BIO_CONNECT_free(data);
+ a->ptr = NULL;
+ a->flags = 0;
+ a->init = 0;
+ }
+ return (1);
+}
+
+static int conn_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+ if (data->state != BIO_CONN_S_OK) {
+ ret = conn_state(b, data);
+ if (ret <= 0)
+ return (ret);
+ }
+
+ if (out != NULL) {
+ clear_socket_error();
+ ret = readsocket(b->num, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return (ret);
+}
+
+static int conn_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+ if (data->state != BIO_CONN_S_OK) {
+ ret = conn_state(b, data);
+ if (ret <= 0)
+ return (ret);
+ }
+
+ clear_socket_error();
+ ret = writesocket(b->num, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return (ret);
+}
+
+static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ int *ip;
+ const char **pptr = NULL;
+ long ret = 1;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ret = 0;
+ data->state = BIO_CONN_S_BEFORE;
+ conn_close_socket(b);
+ b->flags = 0;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ /* use this one to start the connection */
+ if (data->state != BIO_CONN_S_OK)
+ ret = (long)conn_state(b, data);
+ else
+ ret = 1;
+ break;
+ case BIO_C_GET_CONNECT:
+ if (ptr != NULL) {
+ pptr = (const char **)ptr;
+ }
+
+ if (b->init) {
+ if (pptr != NULL) {
+ ret = 1;
+ if (num == 0) {
+ *pptr = data->param_hostname;
+ } else if (num == 1) {
+ *pptr = data->param_port;
+ } else if (num == 2) {
+ *pptr = (char *)&(data->ip[0]);
+ } else {
+ ret = 0;
+ }
+ }
+ if (num == 3) {
+ ret = data->port;
+ }
+ } else {
+ if (pptr != NULL)
+ *pptr = "not initialized";
+ ret = 0;
+ }
+ break;
+ case BIO_C_SET_CONNECT:
+ if (ptr != NULL) {
+ b->init = 1;
+ if (num == 0) {
+ if (data->param_hostname != NULL)
+ OPENSSL_free(data->param_hostname);
+ data->param_hostname = BUF_strdup(ptr);
+ } else if (num == 1) {
+ if (data->param_port != NULL)
+ OPENSSL_free(data->param_port);
+ data->param_port = BUF_strdup(ptr);
+ } else if (num == 2) {
+ char buf[16];
+ unsigned char *p = ptr;
+
+ BIO_snprintf(buf, sizeof buf, "%d.%d.%d.%d",
+ p[0], p[1], p[2], p[3]);
+ if (data->param_hostname != NULL)
+ OPENSSL_free(data->param_hostname);
+ data->param_hostname = BUF_strdup(buf);
+ memcpy(&(data->ip[0]), ptr, 4);
+ } else if (num == 3) {
+ char buf[DECIMAL_SIZE(int) + 1];
+
+ BIO_snprintf(buf, sizeof buf, "%d", *(int *)ptr);
+ if (data->param_port != NULL)
+ OPENSSL_free(data->param_port);
+ data->param_port = BUF_strdup(buf);
+ data->port = *(int *)ptr;
+ }
+ }
+ break;
+ case BIO_C_SET_NBIO:
+ data->nbio = (int)num;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_FLUSH:
+ break;
+ case BIO_CTRL_DUP:
+ {
+ dbio = (BIO *)ptr;
+ if (data->param_port)
+ BIO_set_conn_port(dbio, data->param_port);
+ if (data->param_hostname)
+ BIO_set_conn_hostname(dbio, data->param_hostname);
+ BIO_set_nbio(dbio, data->nbio);
+ /*
+ * FIXME: the cast of the function seems unlikely to be a good
+ * idea
+ */
+ (void)BIO_set_info_callback(dbio,
+ (bio_info_cb *)data->info_callback);
+ }
+ break;
+ case BIO_CTRL_SET_CALLBACK:
+ {
+# if 0 /* FIXME: Should this be used? -- Richard
+ * Levitte */
+ BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ret = -1;
+# else
+ ret = 0;
+# endif
+ }
+ break;
+ case BIO_CTRL_GET_CALLBACK:
+ {
+ int (**fptr) (const BIO *bio, int state, int xret);
+
+ fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
+ *fptr = data->info_callback;
+ }
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_SET_CALLBACK:
+ {
+ data->info_callback =
+ (int (*)(const struct bio_st *, int, int))fp;
+ }
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int conn_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = conn_write(bp, str, n);
+ return (ret);
+}
+
+BIO *BIO_new_connect(const char *str)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_connect());
+ if (ret == NULL)
+ return (NULL);
+ if (BIO_set_conn_hostname(ret, str))
+ return (ret);
+ else {
+ BIO_free(ret);
+ return (NULL);
+ }
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_dgram.c b/Cryptlib/OpenSSL/crypto/bio/bss_dgram.c
new file mode 100644
index 00000000..bdd7bf88
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_dgram.c
@@ -0,0 +1,2081 @@
+/* crypto/bio/bio_dgram.c */
+/*
+ * 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).
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#include <openssl/bio.h>
+#ifndef OPENSSL_NO_DGRAM
+
+# if defined(OPENSSL_SYS_VMS)
+# include <sys/timeb.h>
+# endif
+
+# ifndef OPENSSL_NO_SCTP
+# include <netinet/sctp.h>
+# include <fcntl.h>
+# define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00
+# define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
+# endif
+
+# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
+# define IP_MTU 14 /* linux is lame */
+# endif
+
+# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
+# define IPPROTO_IPV6 41 /* windows is lame */
+# endif
+
+# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
+/* Standard definition causes type-punning problems. */
+# undef IN6_IS_ADDR_V4MAPPED
+# define s6_addr32 __u6_addr.__u6_addr32
+# define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+# endif
+
+# ifdef WATT32
+# define sock_write SockWrite /* Watt-32 uses same names */
+# define sock_read SockRead
+# define sock_puts SockPuts
+# endif
+
+static int dgram_write(BIO *h, const char *buf, int num);
+static int dgram_read(BIO *h, char *buf, int size);
+static int dgram_puts(BIO *h, const char *str);
+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_new(BIO *h);
+static int dgram_free(BIO *data);
+static int dgram_clear(BIO *bio);
+
+# ifndef OPENSSL_NO_SCTP
+static int dgram_sctp_write(BIO *h, const char *buf, int num);
+static int dgram_sctp_read(BIO *h, char *buf, int size);
+static int dgram_sctp_puts(BIO *h, const char *str);
+static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_sctp_new(BIO *h);
+static int dgram_sctp_free(BIO *data);
+# ifdef SCTP_AUTHENTICATION_EVENT
+static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
+ *snp);
+# endif
+# endif
+
+static int BIO_dgram_should_retry(int s);
+
+static void get_current_time(struct timeval *t);
+
+static BIO_METHOD methods_dgramp = {
+ BIO_TYPE_DGRAM,
+ "datagram socket",
+ dgram_write,
+ dgram_read,
+ dgram_puts,
+ NULL, /* dgram_gets, */
+ dgram_ctrl,
+ dgram_new,
+ dgram_free,
+ NULL,
+};
+
+# ifndef OPENSSL_NO_SCTP
+static BIO_METHOD methods_dgramp_sctp = {
+ BIO_TYPE_DGRAM_SCTP,
+ "datagram sctp socket",
+ dgram_sctp_write,
+ dgram_sctp_read,
+ dgram_sctp_puts,
+ NULL, /* dgram_gets, */
+ dgram_sctp_ctrl,
+ dgram_sctp_new,
+ dgram_sctp_free,
+ NULL,
+};
+# endif
+
+typedef struct bio_dgram_data_st {
+ 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;
+ struct timeval next_timeout;
+ struct timeval socket_timeout;
+} bio_dgram_data;
+
+# ifndef OPENSSL_NO_SCTP
+typedef struct bio_dgram_sctp_save_message_st {
+ BIO *bio;
+ char *data;
+ int length;
+} bio_dgram_sctp_save_message;
+
+typedef struct bio_dgram_sctp_data_st {
+ 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;
+ struct bio_dgram_sctp_sndinfo sndinfo;
+ struct bio_dgram_sctp_rcvinfo rcvinfo;
+ struct bio_dgram_sctp_prinfo prinfo;
+ void (*handle_notifications) (BIO *bio, void *context, void *buf);
+ void *notification_context;
+ int in_handshake;
+ int ccs_rcvd;
+ int ccs_sent;
+ int save_shutdown;
+ int peer_auth_tested;
+ bio_dgram_sctp_save_message saved_message;
+} bio_dgram_sctp_data;
+# endif
+
+BIO_METHOD *BIO_s_datagram(void)
+{
+ return (&methods_dgramp);
+}
+
+BIO *BIO_new_dgram(int fd, int close_flag)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_datagram());
+ if (ret == NULL)
+ return (NULL);
+ BIO_set_fd(ret, fd, close_flag);
+ return (ret);
+}
+
+static int dgram_new(BIO *bi)
+{
+ bio_dgram_data *data = NULL;
+
+ bi->init = 0;
+ bi->num = 0;
+ data = OPENSSL_malloc(sizeof(bio_dgram_data));
+ if (data == NULL)
+ return 0;
+ memset(data, 0x00, sizeof(bio_dgram_data));
+ bi->ptr = data;
+
+ bi->flags = 0;
+ return (1);
+}
+
+static int dgram_free(BIO *a)
+{
+ bio_dgram_data *data;
+
+ if (a == NULL)
+ return (0);
+ if (!dgram_clear(a))
+ return 0;
+
+ data = (bio_dgram_data *)a->ptr;
+ if (data != NULL)
+ OPENSSL_free(data);
+
+ return (1);
+}
+
+static int dgram_clear(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ if (a->shutdown) {
+ if (a->init) {
+ SHUTDOWN2(a->num);
+ }
+ a->init = 0;
+ a->flags = 0;
+ }
+ return (1);
+}
+
+static void dgram_adjust_rcv_timeout(BIO *b)
+{
+# if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ union {
+ size_t s;
+ int i;
+ } sz = {
+ 0
+ };
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+ struct timeval timenow, timeleft;
+
+ /* Read current socket timeout */
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+
+ sz.i = sizeof(timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, &sz.i) < 0) {
+ perror("getsockopt");
+ } else {
+ data->socket_timeout.tv_sec = timeout / 1000;
+ data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
+ }
+# else
+ sz.i = sizeof(data->socket_timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ &(data->socket_timeout), (void *)&sz) < 0) {
+ perror("getsockopt");
+ } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
+ OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
+# endif
+
+ /* Get current time */
+ get_current_time(&timenow);
+
+ /* Calculate time left until timer expires */
+ memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+ if (timeleft.tv_usec < timenow.tv_usec) {
+ timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
+ timeleft.tv_sec--;
+ } else {
+ timeleft.tv_usec -= timenow.tv_usec;
+ }
+ if (timeleft.tv_sec < timenow.tv_sec) {
+ timeleft.tv_sec = 0;
+ timeleft.tv_usec = 1;
+ } else {
+ timeleft.tv_sec -= timenow.tv_sec;
+ }
+
+ /*
+ * Adjust socket timeout if next handhake message timer will expire
+ * earlier.
+ */
+ if ((data->socket_timeout.tv_sec == 0
+ && data->socket_timeout.tv_usec == 0)
+ || (data->socket_timeout.tv_sec > timeleft.tv_sec)
+ || (data->socket_timeout.tv_sec == timeleft.tv_sec
+ && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
+# ifdef OPENSSL_SYS_WINDOWS
+ timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ }
+# else
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ }
+# endif
+ }
+ }
+# endif
+}
+
+static void dgram_reset_rcv_timeout(BIO *b)
+{
+# if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout = data->socket_timeout.tv_sec * 1000 +
+ data->socket_timeout.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ }
+# else
+ if (setsockopt
+ (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ }
+# endif
+ }
+# endif
+}
+
+static int dgram_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+ struct {
+ /*
+ * See commentary in b_sock.c. <appro>
+ */
+ 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(&sa.peer, 0x00, sizeof(sa.peer));
+ dgram_adjust_rcv_timeout(b);
+ 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;
+ }
+
+ if (!data->connected && ret >= 0)
+ BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
+
+ BIO_clear_retry_flags(b);
+ if (ret < 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_read(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+
+ dgram_reset_rcv_timeout(b);
+ }
+ return (ret);
+}
+
+static int dgram_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ clear_socket_error();
+
+ 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_IPV6
+ 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.sa, peerlen);
+# else
+ ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
+# endif
+ }
+
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_write(b);
+ data->_errno = get_last_socket_error();
+
+# if 0 /* higher layers are responsible for querying
+ * MTU, if necessary */
+ if (data->_errno == EMSGSIZE)
+ /* retrieve the new MTU */
+ BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+# endif
+ }
+ }
+ return (ret);
+}
+
+static long dgram_get_mtu_overhead(bio_dgram_data *data)
+{
+ long ret;
+
+ switch (data->peer.sa.sa_family) {
+ case AF_INET:
+ /*
+ * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
+ */
+ ret = 28;
+ break;
+# if OPENSSL_USE_IPV6
+ case AF_INET6:
+# ifdef IN6_IS_ADDR_V4MAPPED
+ if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
+ /*
+ * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
+ */
+ ret = 28;
+ else
+# endif
+ /*
+ * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
+ */
+ ret = 48;
+ break;
+# endif
+ default:
+ /* We don't know. Go with the historical default */
+ ret = 28;
+ break;
+ }
+ return ret;
+}
+
+static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ int *ip;
+ struct sockaddr *to = NULL;
+ bio_dgram_data *data = NULL;
+ int sockopt_val = 0;
+# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+ socklen_t sockopt_len; /* assume that system supporting IP_MTU is
+ * modern enough to define socklen_t */
+ socklen_t addr_len;
+ 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;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ ret = 0;
+ break;
+ case BIO_CTRL_INFO:
+ ret = 0;
+ break;
+ case BIO_C_SET_FD:
+ dgram_clear(b);
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ 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;
+ break;
+ case BIO_CTRL_DGRAM_CONNECT:
+ to = (struct sockaddr *)ptr;
+# if 0
+ if (connect(b->num, to, sizeof(struct sockaddr)) < 0) {
+ perror("connect");
+ ret = 0;
+ } else {
+# endif
+ 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
+ break;
+ /* (Linux)kernel sets DF bit on outgoing IP packets */
+ case BIO_CTRL_DGRAM_MTU_DISCOVER:
+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+ addr_len = (socklen_t) sizeof(addr);
+ memset((void *)&addr, 0, sizeof(addr));
+ if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+ ret = 0;
+ break;
+ }
+ switch (addr.sa.sa_family) {
+ case AF_INET:
+ sockopt_val = IP_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+ 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;
+ }
+ ret = -1;
+# else
+ break;
+# endif
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
+ 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.sa.sa_family) {
+ case AF_INET:
+ if ((ret =
+ getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+ &sockopt_len)) < 0 || sockopt_val < 0) {
+ ret = 0;
+ } else {
+ /*
+ * we assume that the transport protocol is UDP and no IP
+ * options are used.
+ */
+ data->mtu = sockopt_val - 8 - 20;
+ 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) {
+ ret = 0;
+ } else {
+ /*
+ * we assume that the transport protocol is UDP and no IPV6
+ * options are used.
+ */
+ data->mtu = sockopt_val - 8 - 40;
+ ret = data->mtu;
+ }
+ break;
+# endif
+ default:
+ ret = 0;
+ break;
+ }
+# else
+ ret = 0;
+# endif
+ break;
+ case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+ ret = -dgram_get_mtu_overhead(data);
+ switch (data->peer.sa.sa_family) {
+ case AF_INET:
+ ret += 576;
+ break;
+# if OPENSSL_USE_IPV6
+ case AF_INET6:
+# ifdef IN6_IS_ADDR_V4MAPPED
+ if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
+ ret += 576;
+ else
+# endif
+ ret += 1280;
+ break;
+# endif
+ default:
+ ret += 576;
+ break;
+ }
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU:
+ return data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ data->mtu = num;
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ to = (struct sockaddr *)ptr;
+
+ if (to != NULL) {
+ data->connected = 1;
+ 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(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_SET_NEXT_TIMEOUT:
+ memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+ break;
+# if defined(SO_RCVTIMEO)
+ case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+# ifdef OPENSSL_SYS_WINDOWS
+ {
+ struct timeval *tv = (struct timeval *)ptr;
+ int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+ }
+# else
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# endif
+ break;
+ case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+ {
+ union {
+ size_t s;
+ int i;
+ } sz = {
+ 0
+ };
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+ struct timeval *tv = (struct timeval *)ptr;
+
+ sz.i = sizeof(timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, &sz.i) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else {
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout % 1000) * 1000;
+ ret = sizeof(*tv);
+ }
+# else
+ sz.i = sizeof(struct timeval);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ ptr, (void *)&sz) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
+ OPENSSL_assert(sz.s <= sizeof(struct timeval));
+ ret = (int)sz.s;
+ } else
+ ret = sz.i;
+# endif
+ }
+ break;
+# endif
+# if defined(SO_SNDTIMEO)
+ case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+# ifdef OPENSSL_SYS_WINDOWS
+ {
+ struct timeval *tv = (struct timeval *)ptr;
+ int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+ }
+# else
+ if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# endif
+ break;
+ case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+ {
+ union {
+ size_t s;
+ int i;
+ } sz = {
+ 0
+ };
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+ struct timeval *tv = (struct timeval *)ptr;
+
+ sz.i = sizeof(timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ (void *)&timeout, &sz.i) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else {
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout % 1000) * 1000;
+ ret = sizeof(*tv);
+ }
+# else
+ sz.i = sizeof(struct timeval);
+ if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ ptr, (void *)&sz) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
+ OPENSSL_assert(sz.s <= sizeof(struct timeval));
+ ret = (int)sz.s;
+ } else
+ ret = sz.i;
+# endif
+ }
+ break;
+# endif
+ case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+ /* fall-through */
+ case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+# ifdef OPENSSL_SYS_WINDOWS
+ if (data->_errno == WSAETIMEDOUT)
+# else
+ if (data->_errno == EAGAIN)
+# endif
+ {
+ ret = 1;
+ data->_errno = 0;
+ } else
+ ret = 0;
+ break;
+# ifdef EMSGSIZE
+ case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+ if (data->_errno == EMSGSIZE) {
+ ret = 1;
+ data->_errno = 0;
+ } else
+ ret = 0;
+ break;
+# endif
+ case BIO_CTRL_DGRAM_SET_DONT_FRAG:
+ sockopt_val = num ? 1 : 0;
+
+ switch (data->peer.sa.sa_family) {
+ case AF_INET:
+# if defined(IP_DONTFRAG)
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
+ &sockopt_val, sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
+ if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+ (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
+ (const char *)&sockopt_val,
+ sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# else
+ ret = -1;
+# endif
+ break;
+# if OPENSSL_USE_IPV6
+ case AF_INET6:
+# if defined(IPV6_DONTFRAG)
+ if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
+ (const void *)&sockopt_val,
+ sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
+ if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+ (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# else
+ ret = -1;
+# endif
+ break;
+# endif
+ default:
+ ret = -1;
+ break;
+ }
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ ret = dgram_get_mtu_overhead(data);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int dgram_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = dgram_write(bp, str, n);
+ return (ret);
+}
+
+# ifndef OPENSSL_NO_SCTP
+BIO_METHOD *BIO_s_datagram_sctp(void)
+{
+ return (&methods_dgramp_sctp);
+}
+
+BIO *BIO_new_dgram_sctp(int fd, int close_flag)
+{
+ BIO *bio;
+ int ret, optval = 20000;
+ int auth_data = 0, auth_forward = 0;
+ unsigned char *p;
+ struct sctp_authchunk auth;
+ struct sctp_authchunks *authchunks;
+ socklen_t sockopt_len;
+# ifdef SCTP_AUTHENTICATION_EVENT
+# ifdef SCTP_EVENT
+ struct sctp_event event;
+# else
+ struct sctp_event_subscribe event;
+# endif
+# endif
+
+ bio = BIO_new(BIO_s_datagram_sctp());
+ if (bio == NULL)
+ return (NULL);
+ BIO_set_fd(bio, fd, close_flag);
+
+ /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
+ auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
+ sizeof(struct sctp_authchunk));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+ auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
+ sizeof(struct sctp_authchunk));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+
+ /*
+ * Test if activation was successful. When using accept(), SCTP-AUTH has
+ * to be activated for the listening socket already, otherwise the
+ * connected socket won't use it.
+ */
+ sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+ authchunks = OPENSSL_malloc(sockopt_len);
+ if (!authchunks) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+ memset(authchunks, 0, sizeof(sockopt_len));
+ ret =
+ getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
+ &sockopt_len);
+
+ if (ret < 0) {
+ OPENSSL_free(authchunks);
+ BIO_vfree(bio);
+ return (NULL);
+ }
+
+ for (p = (unsigned char *)authchunks->gauth_chunks;
+ p < (unsigned char *)authchunks + sockopt_len;
+ p += sizeof(uint8_t)) {
+ if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
+ auth_data = 1;
+ if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
+ auth_forward = 1;
+ }
+
+ OPENSSL_free(authchunks);
+
+ OPENSSL_assert(auth_data);
+ OPENSSL_assert(auth_forward);
+
+# ifdef SCTP_AUTHENTICATION_EVENT
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_AUTHENTICATION_EVENT;
+ event.se_on = 1;
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+# else
+ sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+
+ event.sctp_authentication_event = 1;
+
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+# endif
+# endif
+
+ /*
+ * Disable partial delivery by setting the min size larger than the max
+ * record size of 2^14 + 2048 + 13
+ */
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
+ sizeof(optval));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return (NULL);
+ }
+
+ return (bio);
+}
+
+int BIO_dgram_is_sctp(BIO *bio)
+{
+ return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
+}
+
+static int dgram_sctp_new(BIO *bi)
+{
+ bio_dgram_sctp_data *data = NULL;
+
+ bi->init = 0;
+ bi->num = 0;
+ data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data));
+ if (data == NULL)
+ return 0;
+ memset(data, 0x00, sizeof(bio_dgram_sctp_data));
+# ifdef SCTP_PR_SCTP_NONE
+ data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
+# endif
+ bi->ptr = data;
+
+ bi->flags = 0;
+ return (1);
+}
+
+static int dgram_sctp_free(BIO *a)
+{
+ bio_dgram_sctp_data *data;
+
+ if (a == NULL)
+ return (0);
+ if (!dgram_clear(a))
+ return 0;
+
+ data = (bio_dgram_sctp_data *) a->ptr;
+ if (data != NULL) {
+ if (data->saved_message.data != NULL)
+ OPENSSL_free(data->saved_message.data);
+ OPENSSL_free(data);
+ }
+
+ return (1);
+}
+
+# ifdef SCTP_AUTHENTICATION_EVENT
+void dgram_sctp_handle_auth_free_key_event(BIO *b,
+ union sctp_notification *snp)
+{
+ int ret;
+ struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
+
+ if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
+ struct sctp_authkeyid authkeyid;
+
+ /* delete key */
+ authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ }
+}
+# endif
+
+static int dgram_sctp_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, n = 0, i, optval;
+ socklen_t optlen;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+ union sctp_notification *snp;
+ struct msghdr msg;
+ struct iovec iov;
+ struct cmsghdr *cmsg;
+ char cmsgbuf[512];
+
+ if (out != NULL) {
+ clear_socket_error();
+
+ do {
+ memset(&data->rcvinfo, 0x00,
+ sizeof(struct bio_dgram_sctp_rcvinfo));
+ iov.iov_base = out;
+ iov.iov_len = outl;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = 512;
+ msg.msg_flags = 0;
+ n = recvmsg(b->num, &msg, 0);
+
+ if (n <= 0) {
+ if (n < 0)
+ ret = n;
+ break;
+ }
+
+ if (msg.msg_controllen > 0) {
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level != IPPROTO_SCTP)
+ continue;
+# ifdef SCTP_RCVINFO
+ if (cmsg->cmsg_type == SCTP_RCVINFO) {
+ struct sctp_rcvinfo *rcvinfo;
+
+ rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
+ data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
+ data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
+ data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
+ data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
+ data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
+ data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
+ data->rcvinfo.rcv_context = rcvinfo->rcv_context;
+ }
+# endif
+# ifdef SCTP_SNDRCV
+ if (cmsg->cmsg_type == SCTP_SNDRCV) {
+ struct sctp_sndrcvinfo *sndrcvinfo;
+
+ sndrcvinfo =
+ (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
+ data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
+ data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
+ data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
+ data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
+ data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
+ data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
+ }
+# endif
+ }
+ }
+
+ if (msg.msg_flags & MSG_NOTIFICATION) {
+ snp = (union sctp_notification *)out;
+ if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+# ifdef SCTP_EVENT
+ struct sctp_event event;
+# else
+ struct sctp_event_subscribe event;
+ socklen_t eventsize;
+# endif
+ /*
+ * If a message has been delayed until the socket is dry,
+ * it can be sent now.
+ */
+ if (data->saved_message.length > 0) {
+ dgram_sctp_write(data->saved_message.bio,
+ data->saved_message.data,
+ data->saved_message.length);
+ OPENSSL_free(data->saved_message.data);
+ data->saved_message.data = NULL;
+ data->saved_message.length = 0;
+ }
+
+ /* disable sender dry event */
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 0;
+ i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+# else
+ eventsize = sizeof(struct sctp_event_subscribe);
+ i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ &eventsize);
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+
+ event.sctp_sender_dry_event = 0;
+
+ i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+# endif
+ }
+# ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, snp);
+# endif
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context,
+ (void *)out);
+
+ memset(out, 0, outl);
+ } else
+ ret += n;
+ }
+ while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
+ && (ret < outl));
+
+ if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
+ /* Partial message read, this should never happen! */
+
+ /*
+ * The buffer was too small, this means the peer sent a message
+ * that was larger than allowed.
+ */
+ if (ret == outl)
+ return -1;
+
+ /*
+ * Test if socket buffer can handle max record size (2^14 + 2048
+ * + 13)
+ */
+ optlen = (socklen_t) sizeof(int);
+ ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
+ if (ret >= 0)
+ OPENSSL_assert(optval >= 18445);
+
+ /*
+ * Test if SCTP doesn't partially deliver below max record size
+ * (2^14 + 2048 + 13)
+ */
+ optlen = (socklen_t) sizeof(int);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
+ &optval, &optlen);
+ if (ret >= 0)
+ OPENSSL_assert(optval >= 18445);
+
+ /*
+ * Partially delivered notification??? Probably a bug....
+ */
+ OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
+
+ /*
+ * Everything seems ok till now, so it's most likely a message
+ * dropped by PR-SCTP.
+ */
+ memset(out, 0, outl);
+ BIO_set_retry_read(b);
+ return -1;
+ }
+
+ BIO_clear_retry_flags(b);
+ if (ret < 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_read(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+
+ /* Test if peer uses SCTP-AUTH before continuing */
+ if (!data->peer_auth_tested) {
+ int ii, auth_data = 0, auth_forward = 0;
+ unsigned char *p;
+ struct sctp_authchunks *authchunks;
+
+ optlen =
+ (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+ authchunks = OPENSSL_malloc(optlen);
+ if (!authchunks) {
+ BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ memset(authchunks, 0, sizeof(optlen));
+ ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
+ authchunks, &optlen);
+
+ if (ii >= 0)
+ for (p = (unsigned char *)authchunks->gauth_chunks;
+ p < (unsigned char *)authchunks + optlen;
+ p += sizeof(uint8_t)) {
+ if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
+ auth_data = 1;
+ if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
+ auth_forward = 1;
+ }
+
+ OPENSSL_free(authchunks);
+
+ if (!auth_data || !auth_forward) {
+ BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
+ return -1;
+ }
+
+ data->peer_auth_tested = 1;
+ }
+ }
+ return (ret);
+}
+
+static int dgram_sctp_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+ struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
+ struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
+ struct bio_dgram_sctp_sndinfo handshake_sinfo;
+ struct iovec iov[1];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
+ CMSG_SPACE(sizeof(struct sctp_prinfo))];
+ struct sctp_sndinfo *sndinfo;
+ struct sctp_prinfo *prinfo;
+# else
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct sctp_sndrcvinfo *sndrcvinfo;
+# endif
+
+ clear_socket_error();
+
+ /*
+ * If we're send anything else than application data, disable all user
+ * parameters and flags.
+ */
+ if (in[0] != 23) {
+ memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
+# ifdef SCTP_SACK_IMMEDIATELY
+ handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
+# endif
+ sinfo = &handshake_sinfo;
+ }
+
+ /*
+ * If we have to send a shutdown alert message and the socket is not dry
+ * yet, we have to save it and send it as soon as the socket gets dry.
+ */
+ if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) {
+ char *tmp;
+ data->saved_message.bio = b;
+ if (!(tmp = OPENSSL_malloc(inl))) {
+ BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ if (data->saved_message.data)
+ OPENSSL_free(data->saved_message.data);
+ data->saved_message.data = tmp;
+ memcpy(data->saved_message.data, in, inl);
+ data->saved_message.length = inl;
+ return inl;
+ }
+
+ iov[0].iov_base = (char *)in;
+ iov[0].iov_len = inl;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t) cmsgbuf;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
+ sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
+ memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
+ sndinfo->snd_sid = sinfo->snd_sid;
+ sndinfo->snd_flags = sinfo->snd_flags;
+ sndinfo->snd_ppid = sinfo->snd_ppid;
+ sndinfo->snd_context = sinfo->snd_context;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
+
+ cmsg =
+ (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_PRINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
+ prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
+ memset(prinfo, 0, sizeof(struct sctp_prinfo));
+ prinfo->pr_policy = pinfo->pr_policy;
+ prinfo->pr_value = pinfo->pr_value;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
+# else
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
+ sndrcvinfo->sinfo_stream = sinfo->snd_sid;
+ sndrcvinfo->sinfo_flags = sinfo->snd_flags;
+# ifdef __FreeBSD__
+ sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
+# endif
+ sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
+ sndrcvinfo->sinfo_context = sinfo->snd_context;
+ sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
+# endif
+
+ ret = sendmsg(b->num, &msg, 0);
+
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_write(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+ return (ret);
+}
+
+static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ bio_dgram_sctp_data *data = NULL;
+ socklen_t sockopt_len = 0;
+ struct sctp_authkeyid authkeyid;
+ struct sctp_authkey *authkey = NULL;
+
+ data = (bio_dgram_sctp_data *) b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+ /*
+ * Set to maximum (2^14) and ignore user input to enable transport
+ * protocol fragmentation. Returns always 2^14.
+ */
+ data->mtu = 16384;
+ ret = data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ /*
+ * Set to maximum (2^14) and ignore input to enable transport
+ * protocol fragmentation. Returns always 2^14.
+ */
+ data->mtu = 16384;
+ ret = data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ case BIO_CTRL_DGRAM_CONNECT:
+ /* Returns always -1. */
+ ret = -1;
+ break;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ /*
+ * SCTP doesn't need the DTLS timer Returns always 1.
+ */
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ /*
+ * We allow transport protocol fragmentation so this is irrelevant
+ */
+ ret = 0;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
+ if (num > 0)
+ data->in_handshake = 1;
+ else
+ data->in_handshake = 0;
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
+ &data->in_handshake, sizeof(int));
+ break;
+ case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
+ /*
+ * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
+ */
+
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
+ &sockopt_len);
+ if (ret < 0)
+ break;
+
+ /* Add new key */
+ sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
+ authkey = OPENSSL_malloc(sockopt_len);
+ if (authkey == NULL) {
+ ret = -1;
+ break;
+ }
+ memset(authkey, 0x00, sockopt_len);
+ authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
+# ifndef __FreeBSD__
+ /*
+ * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
+ * and higher work without it.
+ */
+ authkey->sca_keylength = 64;
+# endif
+ memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
+ sockopt_len);
+ OPENSSL_free(authkey);
+ authkey = NULL;
+ if (ret < 0)
+ break;
+
+ /* Reset active key */
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0)
+ break;
+
+ break;
+ case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
+ /* Returns 0 on success, -1 otherwise. */
+
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
+ &sockopt_len);
+ if (ret < 0)
+ break;
+
+ /* Set active key */
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0)
+ break;
+
+ /*
+ * CCS has been sent, so remember that and fall through to check if
+ * we need to deactivate an old key
+ */
+ data->ccs_sent = 1;
+
+ case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
+ /* Returns 0 on success, -1 otherwise. */
+
+ /*
+ * Has this command really been called or is this just a
+ * fall-through?
+ */
+ if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
+ data->ccs_rcvd = 1;
+
+ /*
+ * CSS has been both, received and sent, so deactivate an old key
+ */
+ if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, &sockopt_len);
+ if (ret < 0)
+ break;
+
+ /*
+ * Deactivate key or delete second last key if
+ * SCTP_AUTHENTICATION_EVENT is not available.
+ */
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+# ifdef SCTP_AUTH_DEACTIVATE_KEY
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
+ &authkeyid, sockopt_len);
+ if (ret < 0)
+ break;
+# endif
+# ifndef SCTP_AUTHENTICATION_EVENT
+ if (authkeyid.scact_keynumber > 0) {
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0)
+ break;
+ }
+# endif
+
+ data->ccs_rcvd = 0;
+ data->ccs_sent = 0;
+ }
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
+ num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+ memcpy(ptr, &(data->sndinfo), num);
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
+ num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+ memcpy(&(data->sndinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
+ num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+ memcpy(ptr, &data->rcvinfo, num);
+
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
+ num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+ memcpy(&(data->rcvinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
+ num = sizeof(struct bio_dgram_sctp_prinfo);
+
+ memcpy(ptr, &(data->prinfo), num);
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
+ num = sizeof(struct bio_dgram_sctp_prinfo);
+
+ memcpy(&(data->prinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
+ /* Returns always 1. */
+ if (num > 0)
+ data->save_shutdown = 1;
+ else
+ data->save_shutdown = 0;
+ break;
+
+ default:
+ /*
+ * Pass to default ctrl function to process SCTP unspecific commands
+ */
+ ret = dgram_ctrl(b, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+int BIO_dgram_sctp_notification_cb(BIO *b,
+ void (*handle_notifications) (BIO *bio,
+ void
+ *context,
+ void *buf),
+ void *context)
+{
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ if (handle_notifications != NULL) {
+ data->handle_notifications = handle_notifications;
+ data->notification_context = context;
+ } else
+ return -1;
+
+ return 0;
+}
+
+int BIO_dgram_sctp_wait_for_dry(BIO *b)
+{
+ int is_dry = 0;
+ int n, sockflags, ret;
+ union sctp_notification snp;
+ struct msghdr msg;
+ struct iovec iov;
+# ifdef SCTP_EVENT
+ struct sctp_event event;
+# else
+ struct sctp_event_subscribe event;
+ socklen_t eventsize;
+# endif
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ /* set sender dry event */
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 1;
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+# else
+ eventsize = sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
+ if (ret < 0)
+ return -1;
+
+ event.sctp_sender_dry_event = 1;
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+# endif
+ if (ret < 0)
+ return -1;
+
+ /* peek for notification */
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+ if (n <= 0) {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN)
+ && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return 0;
+ }
+
+ /* if we find a notification, process it and try again if necessary */
+ while (msg.msg_flags & MSG_NOTIFICATION) {
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ n = recvmsg(b->num, &msg, 0);
+ if (n <= 0) {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN)
+ && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return is_dry;
+ }
+
+ if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+ is_dry = 1;
+
+ /* disable sender dry event */
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(struct sctp_event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 0;
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+# else
+ eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ &eventsize);
+ if (ret < 0)
+ return -1;
+
+ event.sctp_sender_dry_event = 0;
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+# endif
+ if (ret < 0)
+ return -1;
+ }
+# ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
+# endif
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context,
+ (void *)&snp);
+
+ /* found notification, peek again */
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ /* if we have seen the dry already, don't wait */
+ if (is_dry) {
+ sockflags = fcntl(b->num, F_GETFL, 0);
+ fcntl(b->num, F_SETFL, O_NONBLOCK);
+ }
+
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+
+ if (is_dry) {
+ fcntl(b->num, F_SETFL, sockflags);
+ }
+
+ if (n <= 0) {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN)
+ && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return is_dry;
+ }
+ }
+
+ /* read anything else */
+ return is_dry;
+}
+
+int BIO_dgram_sctp_msg_waiting(BIO *b)
+{
+ int n, sockflags;
+ union sctp_notification snp;
+ struct msghdr msg;
+ struct iovec iov;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ /* Check if there are any messages waiting to be read */
+ do {
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ sockflags = fcntl(b->num, F_GETFL, 0);
+ fcntl(b->num, F_SETFL, O_NONBLOCK);
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+ fcntl(b->num, F_SETFL, sockflags);
+
+ /* if notification, process and try again */
+ if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
+# ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
+# endif
+
+ memset(&snp, 0x00, sizeof(union sctp_notification));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ n = recvmsg(b->num, &msg, 0);
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context,
+ (void *)&snp);
+ }
+
+ } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
+
+ /* Return 1 if there is a message to be read, return 0 otherwise. */
+ if (n > 0)
+ return 1;
+ else
+ return 0;
+}
+
+static int dgram_sctp_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = dgram_sctp_write(bp, str, n);
+ return (ret);
+}
+# endif
+
+static int BIO_dgram_should_retry(int i)
+{
+ int err;
+
+ if ((i == 0) || (i == -1)) {
+ err = get_last_socket_error();
+
+# if defined(OPENSSL_SYS_WINDOWS)
+ /*
+ * If the socket return value (i) is -1 and err is unexpectedly 0 at
+ * this point, the error code was overwritten by another system call
+ * before this error handling is called.
+ */
+# endif
+
+ return (BIO_dgram_non_fatal_error(err));
+ }
+ return (0);
+}
+
+int BIO_dgram_non_fatal_error(int err)
+{
+ switch (err) {
+# if defined(OPENSSL_SYS_WINDOWS)
+# if defined(WSAEWOULDBLOCK)
+ case WSAEWOULDBLOCK:
+# endif
+
+# if 0 /* This appears to always be an error */
+# if defined(WSAENOTCONN)
+ case WSAENOTCONN:
+# endif
+# endif
+# endif
+
+# ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+# endif
+
+# ifdef EINTR
+ case EINTR:
+# endif
+
+# ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+# endif
+
+# ifdef EPROTO
+ case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+# endif
+
+ return (1);
+ /* break; */
+ default:
+ break;
+ }
+ return (0);
+}
+
+static void get_current_time(struct timeval *t)
+{
+# if defined(_WIN32)
+ SYSTEMTIME st;
+ union {
+ unsigned __int64 ul;
+ FILETIME ft;
+ } now;
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &now.ft);
+# ifdef __MINGW32__
+ now.ul -= 116444736000000000ULL;
+# else
+ now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
+# endif
+ t->tv_sec = (long)(now.ul / 10000000);
+ t->tv_usec = ((int)(now.ul % 10000000)) / 10;
+# elif defined(OPENSSL_SYS_VMS)
+ struct timeb tb;
+ ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+# else
+ gettimeofday(t, NULL);
+# endif
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_fd.c b/Cryptlib/OpenSSL/crypto/bio/bss_fd.c
new file mode 100644
index 00000000..5f4e3448
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_fd.c
@@ -0,0 +1,330 @@
+/* crypto/bio/bss_fd.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 <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#if defined(OPENSSL_NO_POSIX_IO)
+/*
+ * Dummy placeholder for BIO_s_fd...
+ */
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+ return NULL;
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+ return 0;
+}
+
+int BIO_fd_should_retry(int i)
+{
+ return 0;
+}
+
+BIO_METHOD *BIO_s_fd(void)
+{
+ return NULL;
+}
+#else
+/*
+ * As for unconditional usage of "UPLINK" interface in this module.
+ * Trouble is that unlike Unix file descriptors [which are indexes
+ * in kernel-side per-process table], corresponding descriptors on
+ * platforms which require "UPLINK" interface seem to be indexes
+ * in a user-land, non-global table. Well, in fact they are indexes
+ * in stdio _iob[], and recall that _iob[] was the very reason why
+ * "UPLINK" interface was introduced in first place. But one way on
+ * another. Neither libcrypto or libssl use this BIO meaning that
+ * file descriptors can only be provided by application. Therefore
+ * "UPLINK" calls are due...
+ */
+# include "bio_lcl.h"
+
+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);
+int BIO_fd_should_retry(int s);
+
+static BIO_METHOD methods_fdp = {
+ BIO_TYPE_FD, "file descriptor",
+ fd_write,
+ fd_read,
+ fd_puts,
+ fd_gets,
+ fd_ctrl,
+ fd_new,
+ fd_free,
+ NULL,
+};
+
+BIO_METHOD *BIO_s_fd(void)
+{
+ return (&methods_fdp);
+}
+
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+ BIO *ret;
+ ret = BIO_new(BIO_s_fd());
+ if (ret == NULL)
+ return (NULL);
+ BIO_set_fd(ret, fd, close_flag);
+ return (ret);
+}
+
+static int fd_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = -1;
+ bi->ptr = NULL;
+ bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
+ return (1);
+}
+
+static int fd_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ if (a->shutdown) {
+ if (a->init) {
+ UP_close(a->num);
+ }
+ a->init = 0;
+ a->flags = BIO_FLAGS_UPLINK;
+ }
+ return (1);
+}
+
+static int fd_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out != NULL) {
+ clear_sys_error();
+ ret = UP_read(b->num, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return (ret);
+}
+
+static int fd_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ clear_sys_error();
+ ret = UP_write(b->num, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return (ret);
+}
+
+static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ int *ip;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ case BIO_C_FILE_SEEK:
+ ret = (long)UP_lseek(b->num, num, 0);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret = (long)UP_lseek(b->num, 0, 1);
+ break;
+ case BIO_C_SET_FD:
+ fd_free(b);
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ 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;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int fd_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = fd_write(bp, str, n);
+ 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;
+
+ if ((i == 0) || (i == -1)) {
+ err = get_last_sys_error();
+
+# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps
+ * not? Ben 4/1/99 */
+ if ((i == -1) && (err == 0))
+ return (1);
+# endif
+
+ return (BIO_fd_non_fatal_error(err));
+ }
+ return (0);
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+ switch (err) {
+
+# ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+# endif
+
+# if defined(ENOTCONN)
+ case ENOTCONN:
+# endif
+
+# ifdef EINTR
+ case EINTR:
+# endif
+
+# ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+# endif
+
+# ifdef EPROTO
+ case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+# endif
+ return (1);
+ /* break; */
+ default:
+ break;
+ }
+ return (0);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_file.c b/Cryptlib/OpenSSL/crypto/bio/bss_file.c
new file mode 100644
index 00000000..bfba93e6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_file.c
@@ -0,0 +1,472 @@
+/* crypto/bio/bss_file.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.]
+ */
+
+/*-
+ * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout
+ * with binary data (e.g. asn1parse -inform DER < xxx) under
+ * Windows
+ */
+
+#ifndef HEADER_BSS_FILE_C
+# define HEADER_BSS_FILE_C
+
+# if defined(__linux) || defined(__sun) || defined(__hpux)
+/*
+ * Following definition aliases fopen to fopen64 on above mentioned
+ * platforms. This makes it possible to open and sequentially access files
+ * larger than 2GB from 32-bit application. It does not allow to traverse
+ * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit
+ * platform permits that, not with fseek/ftell. Not to mention that breaking
+ * 2GB limit for seeking would require surgery to *our* API. But sequential
+ * access suffices for practical cases when you can run into large files,
+ * such as fingerprinting, so we can let API alone. For reference, the list
+ * of 32-bit platforms which allow for sequential access of large files
+ * without extra "magic" comprise *BSD, Darwin, IRIX...
+ */
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# endif
+
+# include <stdio.h>
+# include <errno.h>
+# include "cryptlib.h"
+# include "bio_lcl.h"
+# include <openssl/err.h>
+
+# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+# include <nwfileio.h>
+# endif
+
+# if !defined(OPENSSL_NO_STDIO)
+
+static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
+static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
+static int MS_CALLBACK file_puts(BIO *h, const char *str);
+static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
+static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int MS_CALLBACK file_new(BIO *h);
+static int MS_CALLBACK file_free(BIO *data);
+static BIO_METHOD methods_filep = {
+ BIO_TYPE_FILE,
+ "FILE pointer",
+ file_write,
+ file_read,
+ file_puts,
+ file_gets,
+ file_ctrl,
+ file_new,
+ file_free,
+ NULL,
+};
+
+static FILE *file_fopen(const char *filename, const char *mode)
+{
+ FILE *file = NULL;
+
+# if defined(_WIN32) && defined(CP_UTF8)
+ int sz, len_0 = (int)strlen(filename) + 1;
+ DWORD flags;
+
+ /*
+ * 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, (flags = MB_ERR_INVALID_CHARS),
+ filename, len_0, NULL, 0)) > 0 ||
+ (GetLastError() == ERROR_INVALID_FLAGS &&
+ (sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
+ filename, len_0, NULL, 0)) > 0)
+ ) {
+ WCHAR wmode[8];
+ WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
+
+ if (MultiByteToWideChar(CP_UTF8, flags,
+ 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 || errno == EBADF)
+ ) {
+ /*
+ * 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
+ return (file);
+}
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+{
+ BIO *ret;
+ FILE *file = file_fopen(filename, mode);
+
+ if (file == NULL) {
+ SYSerr(SYS_F_FOPEN, get_last_sys_error());
+ ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
+ if (errno == ENOENT)
+ BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
+ else
+ BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
+ return (NULL);
+ }
+ if ((ret = BIO_new(BIO_s_file())) == NULL) {
+ fclose(file);
+ return (NULL);
+ }
+
+ BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
+ * UPLINK */
+ BIO_set_fp(ret, file, BIO_CLOSE);
+ return (ret);
+}
+
+BIO *BIO_new_fp(FILE *stream, int close_flag)
+{
+ BIO *ret;
+
+ if ((ret = BIO_new(BIO_s_file())) == NULL)
+ return (NULL);
+
+ BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for
+ * documentation puposes */
+ BIO_set_fp(ret, stream, close_flag);
+ return (ret);
+}
+
+BIO_METHOD *BIO_s_file(void)
+{
+ return (&methods_filep);
+}
+
+static int MS_CALLBACK file_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = 0;
+ bi->ptr = NULL;
+ bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
+ return (1);
+}
+
+static int MS_CALLBACK file_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ if (a->shutdown) {
+ if ((a->init) && (a->ptr != NULL)) {
+ if (a->flags & BIO_FLAGS_UPLINK)
+ UP_fclose(a->ptr);
+ else
+ fclose(a->ptr);
+ a->ptr = NULL;
+ a->flags = BIO_FLAGS_UPLINK;
+ }
+ a->init = 0;
+ }
+ return (1);
+}
+
+static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (b->init && (out != NULL)) {
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = UP_fread(out, 1, (int)outl, b->ptr);
+ else
+ ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
+ if (ret == 0
+ && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
+ ferror((FILE *)b->ptr)) {
+ SYSerr(SYS_F_FREAD, get_last_sys_error());
+ BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
+ ret = -1;
+ }
+ }
+ return (ret);
+}
+
+static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+
+ if (b->init && (in != NULL)) {
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = UP_fwrite(in, (int)inl, 1, b->ptr);
+ else
+ ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
+ if (ret)
+ ret = inl;
+ /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
+ /*
+ * according to Tim Hudson <tjh@cryptsoft.com>, the commented out
+ * version above can cause 'inl' write calls under some stupid stdio
+ * implementations (VMS)
+ */
+ }
+ return (ret);
+}
+
+static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ FILE *fp = (FILE *)b->ptr;
+ FILE **fpp;
+ char p[4];
+
+ switch (cmd) {
+ case BIO_C_FILE_SEEK:
+ case BIO_CTRL_RESET:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = (long)UP_fseek(b->ptr, num, 0);
+ else
+ ret = (long)fseek(fp, num, 0);
+ break;
+ case BIO_CTRL_EOF:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = (long)UP_feof(fp);
+ else
+ ret = (long)feof(fp);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = UP_ftell(b->ptr);
+ else
+ ret = ftell(fp);
+ break;
+ case BIO_C_SET_FILE_PTR:
+ file_free(b);
+ b->shutdown = (int)num & BIO_CLOSE;
+ b->ptr = ptr;
+ b->init = 1;
+# if BIO_FLAGS_UPLINK!=0
+# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
+# define _IOB_ENTRIES 20
+# endif
+# if defined(_IOB_ENTRIES)
+ /* Safety net to catch purely internal BIO_set_fp calls */
+ if ((size_t)ptr >= (size_t)stdin &&
+ (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+# endif
+# endif
+# ifdef UP_fsetmod
+ if (b->flags & BIO_FLAGS_UPLINK)
+ UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
+ else
+# endif
+ {
+# if defined(OPENSSL_SYS_WINDOWS)
+ int fd = _fileno((FILE *)ptr);
+ if (num & BIO_FP_TEXT)
+ _setmode(fd, _O_TEXT);
+ else
+ _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 */
+ if (num & BIO_FP_TEXT)
+ setmode(fd, O_TEXT);
+ else
+ setmode(fd, O_BINARY);
+# elif defined(OPENSSL_SYS_MSDOS)
+ int fd = fileno((FILE *)ptr);
+ /* Set correct text/binary mode */
+ if (num & BIO_FP_TEXT)
+ _setmode(fd, _O_TEXT);
+ /* Dangerous to set stdin/stdout to raw (unless redirected) */
+ else {
+ if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
+ if (isatty(fd) <= 0)
+ _setmode(fd, _O_BINARY);
+ } else
+ _setmode(fd, _O_BINARY);
+ }
+# elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+ int fd = fileno((FILE *)ptr);
+ if (num & BIO_FP_TEXT)
+ setmode(fd, O_TEXT);
+ else
+ setmode(fd, O_BINARY);
+# endif
+ }
+ break;
+ case BIO_C_SET_FILENAME:
+ file_free(b);
+ b->shutdown = (int)num & BIO_CLOSE;
+ if (num & BIO_FP_APPEND) {
+ if (num & BIO_FP_READ)
+ BUF_strlcpy(p, "a+", sizeof p);
+ else
+ BUF_strlcpy(p, "a", sizeof p);
+ } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+ BUF_strlcpy(p, "r+", sizeof p);
+ else if (num & BIO_FP_WRITE)
+ BUF_strlcpy(p, "w", sizeof p);
+ else if (num & BIO_FP_READ)
+ BUF_strlcpy(p, "r", sizeof p);
+ else {
+ BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
+ ret = 0;
+ break;
+ }
+# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+ if (!(num & BIO_FP_TEXT))
+ strcat(p, "b");
+ else
+ strcat(p, "t");
+# endif
+# if defined(OPENSSL_SYS_NETWARE)
+ if (!(num & BIO_FP_TEXT))
+ strcat(p, "b");
+ else
+ strcat(p, "t");
+# endif
+ fp = file_fopen(ptr, p);
+ if (fp == NULL) {
+ SYSerr(SYS_F_FOPEN, get_last_sys_error());
+ ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
+ BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+ ret = 0;
+ break;
+ }
+ b->ptr = fp;
+ b->init = 1;
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
+ * UPLINK */
+ break;
+ case BIO_C_GET_FILE_PTR:
+ /* the ptr parameter is actually a FILE ** in this case. */
+ if (ptr != NULL) {
+ fpp = (FILE **)ptr;
+ *fpp = (FILE *)b->ptr;
+ }
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = (long)b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_FLUSH:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ UP_fflush(b->ptr);
+ else
+ fflush((FILE *)b->ptr);
+ break;
+ case BIO_CTRL_DUP:
+ ret = 1;
+ break;
+
+ case BIO_CTRL_WPENDING:
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_PUSH:
+ case BIO_CTRL_POP:
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
+{
+ int ret = 0;
+
+ buf[0] = '\0';
+ if (bp->flags & BIO_FLAGS_UPLINK) {
+ if (!UP_fgets(buf, size, bp->ptr))
+ goto err;
+ } else {
+ if (!fgets(buf, size, (FILE *)bp->ptr))
+ goto err;
+ }
+ if (buf[0] != '\0')
+ ret = strlen(buf);
+ err:
+ return (ret);
+}
+
+static int MS_CALLBACK file_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = file_write(bp, str, n);
+ return (ret);
+}
+
+# endif /* OPENSSL_NO_STDIO */
+
+#endif /* HEADER_BSS_FILE_C */
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_log.c b/Cryptlib/OpenSSL/crypto/bio/bss_log.c
new file mode 100644
index 00000000..1283a525
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_log.c
@@ -0,0 +1,453 @@
+/* crypto/bio/bss_log.c */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+/*
+ * Why BIO_s_log?
+ *
+ * BIO_s_log is useful for system daemons (or services under NT). It is
+ * one-way BIO, it sends all stuff to syslogd (on system that commonly use
+ * that), or event log (on NT), or OPCOM (on OpenVMS).
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+
+#if defined(OPENSSL_SYS_WINCE)
+#elif defined(OPENSSL_SYS_WIN32)
+#elif defined(OPENSSL_SYS_VMS)
+# include <opcdef.h>
+# include <descrip.h>
+# include <lib$routines.h>
+# include <starlet.h>
+/* Some compiler options may mask the declaration of "_malloc32". */
+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+void *_malloc32(__size_t);
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+# endif /* __INITIAL_POINTER_SIZE && defined
+ * _ANSI_C_SOURCE */
+#elif defined(__ultrix)
+# include <sys/syslog.h>
+#elif defined(OPENSSL_SYS_NETWARE)
+# define NO_SYSLOG
+#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
+# include <syslog.h>
+#endif
+
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+#ifndef NO_SYSLOG
+
+# if defined(OPENSSL_SYS_WIN32)
+# define LOG_EMERG 0
+# define LOG_ALERT 1
+# define LOG_CRIT 2
+# define LOG_ERR 3
+# define LOG_WARNING 4
+# define LOG_NOTICE 5
+# define LOG_INFO 6
+# define LOG_DEBUG 7
+
+# define LOG_DAEMON (3<<3)
+# elif defined(OPENSSL_SYS_VMS)
+/* On VMS, we don't really care about these, but we need them to compile */
+# define LOG_EMERG 0
+# define LOG_ALERT 1
+# define LOG_CRIT 2
+# define LOG_ERR 3
+# define LOG_WARNING 4
+# define LOG_NOTICE 5
+# define LOG_INFO 6
+# define LOG_DEBUG 7
+
+# define LOG_DAEMON OPC$M_NM_NTWORK
+# endif
+
+static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num);
+static int MS_CALLBACK slg_puts(BIO *h, const char *str);
+static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int MS_CALLBACK slg_new(BIO *h);
+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);
+
+static BIO_METHOD methods_slg = {
+ BIO_TYPE_MEM, "syslog",
+ slg_write,
+ NULL,
+ slg_puts,
+ NULL,
+ slg_ctrl,
+ slg_new,
+ slg_free,
+ NULL,
+};
+
+BIO_METHOD *BIO_s_log(void)
+{
+ return (&methods_slg);
+}
+
+static int MS_CALLBACK slg_new(BIO *bi)
+{
+ bi->init = 1;
+ bi->num = 0;
+ bi->ptr = NULL;
+ xopenlog(bi, "application", LOG_DAEMON);
+ return (1);
+}
+
+static int MS_CALLBACK slg_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ xcloselog(a);
+ return (1);
+}
+
+static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl)
+{
+ int ret = inl;
+ char *buf;
+ char *pp;
+ int priority, i;
+ static const struct {
+ int strl;
+ char str[10];
+ int log_level;
+ } mapping[] = {
+ {
+ 6, "PANIC ", LOG_EMERG
+ },
+ {
+ 6, "EMERG ", LOG_EMERG
+ },
+ {
+ 4, "EMR ", LOG_EMERG
+ },
+ {
+ 6, "ALERT ", LOG_ALERT
+ },
+ {
+ 4, "ALR ", LOG_ALERT
+ },
+ {
+ 5, "CRIT ", LOG_CRIT
+ },
+ {
+ 4, "CRI ", LOG_CRIT
+ },
+ {
+ 6, "ERROR ", LOG_ERR
+ },
+ {
+ 4, "ERR ", LOG_ERR
+ },
+ {
+ 8, "WARNING ", LOG_WARNING
+ },
+ {
+ 5, "WARN ", LOG_WARNING
+ },
+ {
+ 4, "WAR ", LOG_WARNING
+ },
+ {
+ 7, "NOTICE ", LOG_NOTICE
+ },
+ {
+ 5, "NOTE ", LOG_NOTICE
+ },
+ {
+ 4, "NOT ", LOG_NOTICE
+ },
+ {
+ 5, "INFO ", LOG_INFO
+ },
+ {
+ 4, "INF ", LOG_INFO
+ },
+ {
+ 6, "DEBUG ", LOG_DEBUG
+ },
+ {
+ 4, "DBG ", LOG_DEBUG
+ },
+ {
+ 0, "", LOG_ERR
+ }
+ /* The default */
+ };
+
+ if ((buf = (char *)OPENSSL_malloc(inl + 1)) == NULL) {
+ return (0);
+ }
+ strncpy(buf, in, inl);
+ buf[inl] = '\0';
+
+ i = 0;
+ while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
+ i++;
+ priority = mapping[i].log_level;
+ pp = buf + mapping[i].strl;
+
+ xsyslog(b, priority, pp);
+
+ OPENSSL_free(buf);
+ return (ret);
+}
+
+static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ switch (cmd) {
+ case BIO_CTRL_SET:
+ xcloselog(b);
+ xopenlog(b, ptr, num);
+ break;
+ default:
+ break;
+ }
+ return (0);
+}
+
+static int MS_CALLBACK slg_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = slg_write(bp, str, n);
+ return (ret);
+}
+
+# if defined(OPENSSL_SYS_WIN32)
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+ if (check_winnt())
+ 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;
+ char pidbuf[DECIMAL_SIZE(DWORD) + 4];
+
+ if (bp->ptr == NULL)
+ return;
+
+ switch (priority) {
+ case LOG_EMERG:
+ case LOG_ALERT:
+ case LOG_CRIT:
+ case LOG_ERR:
+ evtype = EVENTLOG_ERROR_TYPE;
+ break;
+ case LOG_WARNING:
+ evtype = EVENTLOG_WARNING_TYPE;
+ break;
+ case LOG_NOTICE:
+ case LOG_INFO:
+ case LOG_DEBUG:
+ evtype = EVENTLOG_INFORMATION_TYPE;
+ break;
+ default:
+ /*
+ * Should never happen, but set it
+ * as error anyway.
+ */
+ evtype = EVENTLOG_ERROR_TYPE;
+ break;
+ }
+
+ sprintf(pidbuf, "[%u] ", GetCurrentProcessId());
+ lpszStrings[0] = pidbuf;
+ lpszStrings[1] = string;
+
+ ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL);
+}
+
+static void xcloselog(BIO *bp)
+{
+ if (bp->ptr)
+ DeregisterEventSource((HANDLE) (bp->ptr));
+ bp->ptr = NULL;
+}
+
+# elif defined(OPENSSL_SYS_VMS)
+
+static int VMS_OPC_target = LOG_DAEMON;
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+ VMS_OPC_target = level;
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+ struct dsc$descriptor_s opc_dsc;
+
+/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+# define OPCDEF_TYPE __char_ptr32
+# define OPCDEF_MALLOC _malloc32
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define OPCDEF_TYPE char *
+# define OPCDEF_MALLOC OPENSSL_malloc
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ struct opcdef *opcdef_p;
+
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+
+ char buf[10240];
+ unsigned int len;
+ struct dsc$descriptor_s buf_dsc;
+ $DESCRIPTOR(fao_cmd, "!AZ: !AZ");
+ char *priority_tag;
+
+ switch (priority) {
+ case LOG_EMERG:
+ priority_tag = "Emergency";
+ break;
+ case LOG_ALERT:
+ priority_tag = "Alert";
+ break;
+ case LOG_CRIT:
+ priority_tag = "Critical";
+ break;
+ case LOG_ERR:
+ priority_tag = "Error";
+ break;
+ case LOG_WARNING:
+ priority_tag = "Warning";
+ break;
+ case LOG_NOTICE:
+ priority_tag = "Notice";
+ break;
+ case LOG_INFO:
+ priority_tag = "Info";
+ break;
+ case LOG_DEBUG:
+ priority_tag = "DEBUG";
+ break;
+ }
+
+ buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ buf_dsc.dsc$b_class = DSC$K_CLASS_S;
+ buf_dsc.dsc$a_pointer = buf;
+ buf_dsc.dsc$w_length = sizeof(buf) - 1;
+
+ lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
+
+ /* We know there's an 8-byte header. That's documented. */
+ opcdef_p = OPCDEF_MALLOC(8 + len);
+ opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
+ memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
+ opcdef_p->opc$l_ms_rqstid = 0;
+ memcpy(&opcdef_p->opc$l_ms_text, buf, len);
+
+ opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ opc_dsc.dsc$b_class = DSC$K_CLASS_S;
+ opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
+ opc_dsc.dsc$w_length = len + 8;
+
+ sys$sndopr(opc_dsc, 0);
+
+ OPENSSL_free(opcdef_p);
+}
+
+static void xcloselog(BIO *bp)
+{
+}
+
+# else /* Unix/Watt32 */
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+# ifdef WATT32 /* djgpp/DOS */
+ openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level);
+# else
+ openlog(name, LOG_PID | LOG_CONS, level);
+# endif
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+ syslog(priority, "%s", string);
+}
+
+static void xcloselog(BIO *bp)
+{
+ closelog();
+}
+
+# endif /* Unix */
+
+#endif /* NO_SYSLOG */
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_mem.c b/Cryptlib/OpenSSL/crypto/bio/bss_mem.c
new file mode 100644
index 00000000..b0394a96
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_mem.c
@@ -0,0 +1,313 @@
+/* crypto/bio/bss_mem.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+static int mem_write(BIO *h, const char *buf, int num);
+static int mem_read(BIO *h, char *buf, int size);
+static int mem_puts(BIO *h, const char *str);
+static int mem_gets(BIO *h, char *str, int size);
+static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int mem_new(BIO *h);
+static int mem_free(BIO *data);
+static BIO_METHOD mem_method = {
+ BIO_TYPE_MEM,
+ "memory buffer",
+ mem_write,
+ mem_read,
+ mem_puts,
+ mem_gets,
+ mem_ctrl,
+ mem_new,
+ mem_free,
+ NULL,
+};
+
+/*
+ * bio->num is used to hold the value to return on 'empty', if it is 0,
+ * should_retry is not set
+ */
+
+BIO_METHOD *BIO_s_mem(void)
+{
+ return (&mem_method);
+}
+
+
+BIO *BIO_new_mem_buf(const 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;
+ }
+ sz = (len < 0) ? strlen(buf) : (size_t)len;
+ if (!(ret = BIO_new(BIO_s_mem())))
+ return NULL;
+ b = (BUF_MEM *)ret->ptr;
+ /* Cast away const and trust in the MEM_RDONLY flag. */
+ b->data = (void *)buf;
+ b->length = sz;
+ b->max = sz;
+ ret->flags |= BIO_FLAGS_MEM_RDONLY;
+ /* Since this is static data retrying wont help */
+ ret->num = 0;
+ return ret;
+}
+
+static int mem_new(BIO *bi)
+{
+ BUF_MEM *b;
+
+ if ((b = BUF_MEM_new()) == NULL)
+ return (0);
+ bi->shutdown = 1;
+ bi->init = 1;
+ bi->num = -1;
+ bi->ptr = (char *)b;
+ return (1);
+}
+
+static int mem_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ if (a->shutdown) {
+ if ((a->init) && (a->ptr != NULL)) {
+ BUF_MEM *b;
+ b = (BUF_MEM *)a->ptr;
+ if (a->flags & BIO_FLAGS_MEM_RDONLY)
+ b->data = NULL;
+ BUF_MEM_free(b);
+ a->ptr = NULL;
+ }
+ }
+ return (1);
+}
+
+static int mem_read(BIO *b, char *out, int outl)
+{
+ int ret = -1;
+ BUF_MEM *bm;
+
+ bm = (BUF_MEM *)b->ptr;
+ BIO_clear_retry_flags(b);
+ 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;
+ if (b->flags & BIO_FLAGS_MEM_RDONLY)
+ bm->data += ret;
+ else {
+ memmove(&(bm->data[0]), &(bm->data[ret]), bm->length);
+ }
+ } else if (bm->length == 0) {
+ ret = b->num;
+ if (ret != 0)
+ BIO_set_retry_read(b);
+ }
+ return (ret);
+}
+
+static int mem_write(BIO *b, const char *in, int inl)
+{
+ int ret = -1;
+ int blen;
+ BUF_MEM *bm;
+
+ bm = (BUF_MEM *)b->ptr;
+ if (in == NULL) {
+ BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
+ goto end;
+ }
+
+ if (b->flags & BIO_FLAGS_MEM_RDONLY) {
+ BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
+ goto end;
+ }
+
+ BIO_clear_retry_flags(b);
+ blen = bm->length;
+ if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl))
+ goto end;
+ memcpy(&(bm->data[blen]), in, inl);
+ ret = inl;
+ end:
+ return (ret);
+}
+
+static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ char **pptr;
+
+ BUF_MEM *bm = (BUF_MEM *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ if (bm->data != NULL) {
+ /* For read only case reset to the start again */
+ if (b->flags & BIO_FLAGS_MEM_RDONLY) {
+ bm->data -= bm->max - bm->length;
+ bm->length = bm->max;
+ } else {
+ memset(bm->data, 0, bm->max);
+ bm->length = 0;
+ }
+ }
+ break;
+ case BIO_CTRL_EOF:
+ ret = (long)(bm->length == 0);
+ break;
+ case BIO_C_SET_BUF_MEM_EOF_RETURN:
+ b->num = (int)num;
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)bm->length;
+ if (ptr != NULL) {
+ pptr = (char **)ptr;
+ *pptr = (char *)&(bm->data[0]);
+ }
+ break;
+ case BIO_C_SET_BUF_MEM:
+ mem_free(b);
+ b->shutdown = (int)num;
+ b->ptr = ptr;
+ break;
+ case BIO_C_GET_BUF_MEM_PTR:
+ if (ptr != NULL) {
+ pptr = (char **)ptr;
+ *pptr = (char *)bm;
+ }
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = (long)b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+
+ case BIO_CTRL_WPENDING:
+ ret = 0L;
+ break;
+ case BIO_CTRL_PENDING:
+ ret = (long)bm->length;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ case BIO_CTRL_PUSH:
+ case BIO_CTRL_POP:
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int mem_gets(BIO *bp, char *buf, int size)
+{
+ int i, j;
+ int ret = -1;
+ char *p;
+ BUF_MEM *bm = (BUF_MEM *)bp->ptr;
+
+ BIO_clear_retry_flags(bp);
+ j = bm->length;
+ if ((size - 1) < j)
+ j = size - 1;
+ if (j <= 0) {
+ *buf = '\0';
+ return 0;
+ }
+ p = bm->data;
+ for (i = 0; i < j; i++) {
+ if (p[i] == '\n') {
+ i++;
+ break;
+ }
+ }
+
+ /*
+ * i is now the max num of bytes to copy, either j or up to
+ * and including the first newline
+ */
+
+ i = mem_read(bp, buf, i);
+ if (i > 0)
+ buf[i] = '\0';
+ ret = i;
+ return (ret);
+}
+
+static int mem_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = mem_write(bp, str, n);
+ /* memory semantics is that it will always work */
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_null.c b/Cryptlib/OpenSSL/crypto/bio/bss_null.c
new file mode 100644
index 00000000..6a03fa24
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_null.c
@@ -0,0 +1,149 @@
+/* crypto/bio/bss_null.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+static int null_write(BIO *h, const char *buf, int num);
+static int null_read(BIO *h, char *buf, int size);
+static int null_puts(BIO *h, const char *str);
+static int null_gets(BIO *h, char *str, int size);
+static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int null_new(BIO *h);
+static int null_free(BIO *data);
+static BIO_METHOD null_method = {
+ BIO_TYPE_NULL,
+ "NULL",
+ null_write,
+ null_read,
+ null_puts,
+ null_gets,
+ null_ctrl,
+ null_new,
+ null_free,
+ NULL,
+};
+
+BIO_METHOD *BIO_s_null(void)
+{
+ return (&null_method);
+}
+
+static int null_new(BIO *bi)
+{
+ bi->init = 1;
+ bi->num = 0;
+ bi->ptr = (NULL);
+ return (1);
+}
+
+static int null_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ return (1);
+}
+
+static int null_read(BIO *b, char *out, int outl)
+{
+ return (0);
+}
+
+static int null_write(BIO *b, const char *in, int inl)
+{
+ return (inl);
+}
+
+static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ case BIO_CTRL_EOF:
+ case BIO_CTRL_SET:
+ case BIO_CTRL_SET_CLOSE:
+ case BIO_CTRL_FLUSH:
+ case BIO_CTRL_DUP:
+ ret = 1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ case BIO_CTRL_INFO:
+ case BIO_CTRL_GET:
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int null_gets(BIO *bp, char *buf, int size)
+{
+ return (0);
+}
+
+static int null_puts(BIO *bp, const char *str)
+{
+ if (str == NULL)
+ return (0);
+ return (strlen(str));
+}
diff --git a/Cryptlib/OpenSSL/crypto/bio/bss_sock.c b/Cryptlib/OpenSSL/crypto/bio/bss_sock.c
new file mode 100644
index 00000000..6194d2c0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bio/bss_sock.c
@@ -0,0 +1,287 @@
+/* crypto/bio/bss_sock.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 <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SOCK
+
+# include <openssl/bio.h>
+
+# ifdef WATT32
+# define sock_write SockWrite /* Watt-32 uses same names */
+# define sock_read SockRead
+# define sock_puts SockPuts
+# endif
+
+static int sock_write(BIO *h, const char *buf, int num);
+static int sock_read(BIO *h, char *buf, int size);
+static int sock_puts(BIO *h, const char *str);
+static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int sock_new(BIO *h);
+static int sock_free(BIO *data);
+int BIO_sock_should_retry(int s);
+
+static BIO_METHOD methods_sockp = {
+ BIO_TYPE_SOCKET,
+ "socket",
+ sock_write,
+ sock_read,
+ sock_puts,
+ NULL, /* sock_gets, */
+ sock_ctrl,
+ sock_new,
+ sock_free,
+ NULL,
+};
+
+BIO_METHOD *BIO_s_socket(void)
+{
+ return (&methods_sockp);
+}
+
+BIO *BIO_new_socket(int fd, int close_flag)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_socket());
+ if (ret == NULL)
+ return (NULL);
+ BIO_set_fd(ret, fd, close_flag);
+ return (ret);
+}
+
+static int sock_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = 0;
+ bi->ptr = NULL;
+ bi->flags = 0;
+ return (1);
+}
+
+static int sock_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ if (a->shutdown) {
+ if (a->init) {
+ SHUTDOWN2(a->num);
+ }
+ a->init = 0;
+ a->flags = 0;
+ }
+ return (1);
+}
+
+static int sock_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out != NULL) {
+ clear_socket_error();
+ ret = readsocket(b->num, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return (ret);
+}
+
+static int sock_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+
+ clear_socket_error();
+ ret = writesocket(b->num, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return (ret);
+}
+
+static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ int *ip;
+
+ switch (cmd) {
+ case BIO_C_SET_FD:
+ sock_free(b);
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int sock_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = sock_write(bp, str, n);
+ return (ret);
+}
+
+int BIO_sock_should_retry(int i)
+{
+ int err;
+
+ if ((i == 0) || (i == -1)) {
+ err = get_last_socket_error();
+
+# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps
+ * not? Ben 4/1/99 */
+ if ((i == -1) && (err == 0))
+ return (1);
+# endif
+
+ return (BIO_sock_non_fatal_error(err));
+ }
+ return (0);
+}
+
+int BIO_sock_non_fatal_error(int err)
+{
+ switch (err) {
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
+# if defined(WSAEWOULDBLOCK)
+ case WSAEWOULDBLOCK:
+# endif
+
+# if 0 /* This appears to always be an error */
+# if defined(WSAENOTCONN)
+ case WSAENOTCONN:
+# endif
+# endif
+# endif
+
+# ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+# endif
+
+# if defined(ENOTCONN)
+ case ENOTCONN:
+# endif
+
+# ifdef EINTR
+ case EINTR:
+# endif
+
+# ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+# endif
+
+# ifdef EPROTO
+ case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+# endif
+ return (1);
+ /* break; */
+ default:
+ break;
+ }
+ return (0);
+}
+
+#endif /* #ifndef OPENSSL_NO_SOCK */
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn.h b/Cryptlib/OpenSSL/crypto/bn/bn.h
new file mode 100644
index 00000000..86264ae6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn.h
@@ -0,0 +1,949 @@
+/* crypto/bn/bn.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.]
+ */
+/* ====================================================================
+ * 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.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_BN_H
+# define HEADER_BN_H
+
+# include <limits.h>
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h> /* FILE */
+# endif
+# include <openssl/ossl_typ.h>
+# include <openssl/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These preprocessor symbols control various aspects of the bignum headers
+ * and library code. They're not defined by any "normal" configuration, as
+ * they are intended for development and testing purposes. NB: defining all
+ * three can be useful for debugging application code as well as openssl
+ * itself. BN_DEBUG - turn on various debugging alterations to the bignum
+ * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up
+ * mismanagement of bignum internals. You must also define BN_DEBUG.
+ */
+/* #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). The reason for this
+ * flag is that when the particular C compiler library routine is used, and
+ * the library is linked with a different compiler, the library is missing.
+ * This mostly happens when the library is built with gcc and then linked
+ * using normal cc. This would be a common occurrence because gcc normally
+ * produces code that is 2 times faster than system compilers for the big
+ * number stuff. For machines with only one compiler (or shared libraries),
+ * this should be on. Again this in only really a problem on machines using
+ * "long long's", are 32bit, and are not using my assembler code.
+ */
+# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+ defined(OPENSSL_SYS_WIN32) || defined(linux)
+# ifndef BN_DIV2W
+# define BN_DIV2W
+# endif
+# endif
+
+/*
+ * assuming long is 64bit - this is the DEC Alpha unsigned long long is only
+ * 64 bits :-(, don't define BN_LLONG for the DEC Alpha
+ */
+# ifdef SIXTY_FOUR_BIT_LONG
+# define BN_ULLONG unsigned long long
+# define BN_ULONG unsigned long
+# define BN_LONG long
+# define BN_BITS 128
+# define BN_BYTES 8
+# define BN_BITS2 64
+# define BN_BITS4 32
+# define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
+# define BN_MASK2 (0xffffffffffffffffL)
+# define BN_MASK2l (0xffffffffL)
+# define BN_MASK2h (0xffffffff00000000L)
+# define BN_MASK2h1 (0xffffffff80000000L)
+# define BN_TBIT (0x8000000000000000L)
+# define BN_DEC_CONV (10000000000000000000UL)
+# 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. For
+ * machines where there are 64bit registers, this is the mode to use. IRIX,
+ * on R4000 and above should use this mode, along with the relevant assembler
+ * code :-). Do NOT define BN_LLONG.
+ */
+# ifdef SIXTY_FOUR_BIT
+# undef BN_LLONG
+# undef BN_ULLONG
+# define BN_ULONG unsigned long long
+# define BN_LONG long long
+# define BN_BITS 128
+# define BN_BYTES 8
+# define BN_BITS2 64
+# define BN_BITS4 32
+# define BN_MASK2 (0xffffffffffffffffLL)
+# define BN_MASK2l (0xffffffffL)
+# define BN_MASK2h (0xffffffff00000000LL)
+# define BN_MASK2h1 (0xffffffff80000000LL)
+# define BN_TBIT (0x8000000000000000LL)
+# define BN_DEC_CONV (10000000000000000000ULL)
+# 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(_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 int
+# define BN_LONG int
+# define BN_BITS 64
+# define BN_BYTES 4
+# define BN_BITS2 32
+# define BN_BITS4 16
+# 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 "%u"
+# 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
+
+# define BN_FLG_MALLOCED 0x01
+# define BN_FLG_STATIC_DATA 0x02
+
+/*
+ * avoid leaking exponent information through timing,
+ * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
+ * BN_div() will call BN_div_no_branch,
+ * BN_mod_inverse() will call BN_mod_inverse_no_branch.
+ */
+# define BN_FLG_CONSTTIME 0x04
+
+# ifdef OPENSSL_NO_DEPRECATED
+/* deprecated name for the flag */
+# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME
+/*
+ * avoid leaking exponent information through timings
+ * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime)
+ */
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED
+# define BN_FLG_FREE 0x8000
+ /* used for debuging */
+# endif
+# define BN_set_flags(b,n) ((b)->flags|=(n))
+# define BN_get_flags(b,n) ((b)->flags&(n))
+
+/*
+ * get a clone of a BIGNUM with changed flags, for *temporary* use only (the
+ * two BIGNUMs cannot not be used in parallel!)
+ */
+# define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \
+ (dest)->top=(b)->top, \
+ (dest)->dmax=(b)->dmax, \
+ (dest)->neg=(b)->neg, \
+ (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
+ | ((b)->flags & ~BN_FLG_MALLOCED) \
+ | BN_FLG_STATIC_DATA \
+ | (n)))
+
+/* Already declared in ossl_typ.h */
+# if 0
+typedef struct bignum_st BIGNUM;
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+# endif
+
+struct bignum_st {
+ BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit
+ * chunks. */
+ int top; /* Index of last used d +1. */
+ /* The next are internal book keeping for bn_expand. */
+ int dmax; /* Size of the d array. */
+ int neg; /* one if the number is negative */
+ int flags;
+};
+
+/* Used for montgomery multiplication */
+struct bn_mont_ctx_st {
+ int ri; /* number of bits in R */
+ BIGNUM RR; /* used to convert to montgomery form */
+ BIGNUM N; /* The modulus */
+ BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only
+ * stored for bignum algorithm) */
+ BN_ULONG n0[2]; /* least significant word(s) of Ni; (type
+ * changed with 0.9.9, was "BN_ULONG n0;"
+ * before) */
+ int flags;
+};
+
+/*
+ * Used for reciprocal division/mod functions It cannot be shared between
+ * threads
+ */
+struct bn_recp_ctx_st {
+ BIGNUM N; /* the divisor */
+ BIGNUM Nr; /* the reciprocal */
+ int num_bits;
+ int shift;
+ int flags;
+};
+
+/* Used for slow "generation" functions. */
+struct bn_gencb_st {
+ unsigned int ver; /* To handle binary (in)compatibility */
+ void *arg; /* callback-specific data */
+ union {
+ /* if(ver==1) - handles old style callbacks */
+ void (*cb_1) (int, int, void *);
+ /* if(ver==2) - new callback style */
+ int (*cb_2) (int, int, BN_GENCB *);
+ } cb;
+};
+/* Wrapper function to make using BN_GENCB easier, */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+/* Macro to populate a BN_GENCB structure with an "old"-style callback */
+# define BN_GENCB_set_old(gencb, callback, cb_arg) { \
+ BN_GENCB *tmp_gencb = (gencb); \
+ tmp_gencb->ver = 1; \
+ tmp_gencb->arg = (cb_arg); \
+ tmp_gencb->cb.cb_1 = (callback); }
+/* Macro to populate a BN_GENCB structure with a "new"-style callback */
+# define BN_GENCB_set(gencb, callback, cb_arg) { \
+ BN_GENCB *tmp_gencb = (gencb); \
+ tmp_gencb->ver = 2; \
+ tmp_gencb->arg = (cb_arg); \
+ tmp_gencb->cb.cb_2 = (callback); }
+
+# define BN_prime_checks 0 /* default: select number of iterations based
+ * on the size of the number */
+
+/*
+ * number of Miller-Rabin iterations for an error rate of less than 2^-80 for
+ * random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook of
+ * Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error
+ * estimates for the strong probable prime test. -- Math. Comp. 61 (1993)
+ * 177-194)
+ */
+# define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \
+ (b) >= 850 ? 3 : \
+ (b) >= 650 ? 4 : \
+ (b) >= 550 ? 5 : \
+ (b) >= 450 ? 6 : \
+ (b) >= 400 ? 7 : \
+ (b) >= 350 ? 8 : \
+ (b) >= 300 ? 9 : \
+ (b) >= 250 ? 12 : \
+ (b) >= 200 ? 15 : \
+ (b) >= 150 ? 18 : \
+ /* b >= 100 */ 27)
+
+# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+
+/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
+# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
+ (((w) == 0) && ((a)->top == 0)))
+# define BN_is_zero(a) ((a)->top == 0)
+# define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg)
+# define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
+# define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
+
+# define BN_one(a) (BN_set_word((a),1))
+# define BN_zero_ex(a) \
+ do { \
+ BIGNUM *_tmp_bn = (a); \
+ _tmp_bn->top = 0; \
+ _tmp_bn->neg = 0; \
+ } while(0)
+# ifdef OPENSSL_NO_DEPRECATED
+# define BN_zero(a) BN_zero_ex(a)
+# else
+# define BN_zero(a) (BN_set_word((a),0))
+# endif
+
+const BIGNUM *BN_value_one(void);
+char *BN_options(void);
+BN_CTX *BN_CTX_new(void);
+# ifndef OPENSSL_NO_DEPRECATED
+void BN_CTX_init(BN_CTX *c);
+# endif
+void BN_CTX_free(BN_CTX *c);
+void BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void BN_CTX_end(BN_CTX *ctx);
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_num_bits(const BIGNUM *a);
+int BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void BN_init(BIGNUM *);
+void BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+void BN_swap(BIGNUM *a, BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
+/** BN_set_negative sets sign of a BIGNUM
+ * \param b pointer to the BIGNUM object
+ * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise
+ */
+void BN_set_negative(BIGNUM *b, int n);
+/** BN_is_negative returns 1 if the BIGNUM is negative
+ * \param a pointer to the BIGNUM object
+ * \return 1 if a < 0 and 0 otherwise
+ */
+# define BN_is_negative(a) ((a)->neg != 0)
+
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx);
+# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m);
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m);
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int BN_mul_word(BIGNUM *a, BN_ULONG w);
+int BN_add_word(BIGNUM *a, BN_ULONG w);
+int BN_sub_word(BIGNUM *a, BN_ULONG w);
+int BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void BN_free(BIGNUM *a);
+int BN_is_bit_set(const BIGNUM *a, int n);
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont);
+int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+ const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+int BN_mask_bits(BIGNUM *a, int n);
+# ifndef OPENSSL_NO_FP_API
+int BN_print_fp(FILE *fp, const BIGNUM *a);
+# endif
+# ifdef HEADER_BIO_H
+int BN_print(BIO *fp, const BIGNUM *a);
+# else
+int BN_print(void *fp, const BIGNUM *a);
+# endif
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int BN_set_bit(BIGNUM *a, int n);
+int BN_clear_bit(BIGNUM *a, int n);
+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,
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
+void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
+/* Deprecated versions */
+# ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+ const BIGNUM *add, const BIGNUM *rem,
+ void (*callback) (int, int, void *), void *cb_arg);
+int BN_is_prime(const BIGNUM *p, int nchecks,
+ void (*callback) (int, int, void *),
+ BN_CTX *ctx, void *cb_arg);
+int BN_is_prime_fasttest(const BIGNUM *p, int nchecks,
+ void (*callback) (int, int, void *), BN_CTX *ctx,
+ void *cb_arg, int do_trial_division);
+# endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* Newer versions */
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
+ const BIGNUM *rem, BN_GENCB *cb);
+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,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+# define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
+ (r),(a),&((mont)->RR),(mont),(ctx))
+int BN_from_montgomery(BIGNUM *r, const BIGNUM *a,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+ const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+# define BN_BLINDING_NO_UPDATE 0x00000001
+# define BN_BLINDING_NO_RECREATE 0x00000002
+
+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, 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);
+
+# ifndef OPENSSL_NO_DEPRECATED
+void BN_set_params(int mul, int high, int low, int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+# endif
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx);
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+
+/*
+ * Functions for arithmetic over binary polynomials represented by BIGNUMs.
+ * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
+ * ignored. Note that input arguments are not const so that their bit arrays
+ * can be expanded to the appropriate size if needed.
+ */
+
+/*
+ * r = a + b
+ */
+int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+/*
+ * r=a mod p
+ */
+int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *p, BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *p, BN_CTX *ctx);
+/* r = (a ^ b) mod p */
+int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *p, BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ BN_CTX *ctx);
+# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
+/*-
+ * Some functions allow for representation of the irreducible polynomials
+ * as an unsigned int[], say p. The irreducible f(t) is then of the form:
+ * t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+/* r = a mod p */
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const int p[], BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+ BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
+ BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ 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 int p[], BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+ const int p[], BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+ const int p[], BN_CTX *ctx);
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a);
+
+# endif
+
+/*
+ * faster mod functions for the 'NIST primes' 0 <= a < p^2
+ */
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+const BIGNUM *BN_get0_nist_prime_192(void);
+const BIGNUM *BN_get0_nist_prime_224(void);
+const BIGNUM *BN_get0_nist_prime_256(void);
+const BIGNUM *BN_get0_nist_prime_384(void);
+const BIGNUM *BN_get0_nist_prime_521(void);
+
+/* library internal functions */
+
+# define bn_expand(a,bits) \
+ ( \
+ bits > (INT_MAX - BN_BITS2 + 1) ? \
+ NULL \
+ : \
+ (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
+ (a) \
+ : \
+ bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
+ )
+
+# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+# ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
+# endif
+
+/*-
+ * Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ * bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ * - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ * consistent. (ed: only if BN_DEBUG_RAND is defined)
+ * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+
+# ifdef BN_DEBUG
+
+/* We only need assert() when debugging */
+# include <assert.h>
+
+# ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+# ifndef RAND_pseudo_bytes
+int RAND_pseudo_bytes(unsigned char *buf, int num);
+# define BN_DEBUG_TRIX
+# endif
+# define bn_pollute(a) \
+ do { \
+ const BIGNUM *_bnum1 = (a); \
+ if(_bnum1->top < _bnum1->dmax) { \
+ unsigned char _tmp_char; \
+ /* We cast away const without the compiler knowing, any \
+ * *genuinely* constant variables that aren't mutable \
+ * wouldn't be constructed with top!=dmax. */ \
+ BN_ULONG *_not_const; \
+ memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
+ /* Debug only - safe to ignore error return */ \
+ RAND_pseudo_bytes(&_tmp_char, 1); \
+ memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
+ (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
+ } \
+ } while(0)
+# ifdef BN_DEBUG_TRIX
+# undef RAND_pseudo_bytes
+# endif
+# else
+# define bn_pollute(a)
+# endif
+# define bn_check_top(a) \
+ do { \
+ const BIGNUM *_bnum2 = (a); \
+ if (_bnum2 != NULL) { \
+ assert((_bnum2->top == 0) || \
+ (_bnum2->d[_bnum2->top - 1] != 0)); \
+ bn_pollute(_bnum2); \
+ } \
+ } while(0)
+
+# define bn_fix_top(a) bn_check_top(a)
+
+# define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
+# define bn_wcheck_size(bn, words) \
+ do { \
+ const BIGNUM *_bnum2 = (bn); \
+ assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \
+ /* avoid unused variable warning with NDEBUG */ \
+ (void)(_bnum2); \
+ } while(0)
+
+# else /* !BN_DEBUG */
+
+# define bn_pollute(a)
+# define bn_check_top(a)
+# define bn_fix_top(a) bn_correct_top(a)
+# define bn_check_size(bn, bits)
+# define bn_wcheck_size(bn, words)
+
+# endif
+
+# define bn_correct_top(a) \
+ { \
+ BN_ULONG *ftl; \
+ int tmp_top = (a)->top; \
+ if (tmp_top > 0) \
+ { \
+ for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
+ if (*(ftl--)) break; \
+ (a)->top = tmp_top; \
+ } \
+ bn_pollute(a); \
+ }
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ int num);
+
+/* Primes from RFC 2409 */
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);
+
+/* Primes from RFC 3526 */
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+/* 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_BN_strings(void);
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+# define BN_F_BNRAND 127
+# define BN_F_BN_BLINDING_CONVERT_EX 100
+# define BN_F_BN_BLINDING_CREATE_PARAM 128
+# define BN_F_BN_BLINDING_INVERT_EX 101
+# define BN_F_BN_BLINDING_NEW 102
+# define BN_F_BN_BLINDING_UPDATE 103
+# define BN_F_BN_BN2DEC 104
+# define BN_F_BN_BN2HEX 105
+# define BN_F_BN_CTX_GET 116
+# define BN_F_BN_CTX_NEW 106
+# define BN_F_BN_CTX_START 129
+# define BN_F_BN_DIV 107
+# define BN_F_BN_DIV_NO_BRANCH 138
+# define BN_F_BN_DIV_RECP 130
+# define BN_F_BN_EXP 123
+# define BN_F_BN_EXPAND2 108
+# define BN_F_BN_EXPAND_INTERNAL 120
+# define BN_F_BN_GF2M_MOD 131
+# define BN_F_BN_GF2M_MOD_EXP 132
+# define BN_F_BN_GF2M_MOD_MUL 133
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135
+# define BN_F_BN_GF2M_MOD_SQR 136
+# define BN_F_BN_GF2M_MOD_SQRT 137
+# define BN_F_BN_LSHIFT 145
+# define BN_F_BN_MOD_EXP2_MONT 118
+# define BN_F_BN_MOD_EXP_MONT 109
+# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124
+# define BN_F_BN_MOD_EXP_MONT_WORD 117
+# define BN_F_BN_MOD_EXP_RECP 125
+# define BN_F_BN_MOD_EXP_SIMPLE 126
+# define BN_F_BN_MOD_INVERSE 110
+# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139
+# define BN_F_BN_MOD_LSHIFT_QUICK 119
+# define BN_F_BN_MOD_MUL_RECIPROCAL 111
+# define BN_F_BN_MOD_SQRT 121
+# define BN_F_BN_MPI2BN 112
+# define BN_F_BN_NEW 113
+# define BN_F_BN_RAND 114
+# define BN_F_BN_RAND_RANGE 122
+# define BN_F_BN_RSHIFT 146
+# define BN_F_BN_USUB 115
+
+/* Reason codes. */
+# define BN_R_ARG2_LT_ARG3 100
+# define BN_R_BAD_RECIPROCAL 101
+# define BN_R_BIGNUM_TOO_LONG 114
+# define BN_R_BITS_TOO_SMALL 118
+# define BN_R_CALLED_WITH_EVEN_MODULUS 102
+# define BN_R_DIV_BY_ZERO 103
+# define BN_R_ENCODING_ERROR 104
+# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105
+# define BN_R_INPUT_NOT_REDUCED 110
+# define BN_R_INVALID_LENGTH 106
+# define BN_R_INVALID_RANGE 115
+# define BN_R_INVALID_SHIFT 119
+# define BN_R_NOT_A_SQUARE 111
+# define BN_R_NOT_INITIALIZED 107
+# define BN_R_NO_INVERSE 108
+# define BN_R_NO_SOLUTION 116
+# define BN_R_P_IS_NOT_PRIME 112
+# define BN_R_TOO_MANY_ITERATIONS 113
+# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_add.c b/Cryptlib/OpenSSL/crypto/bn/bn_add.c
new file mode 100644
index 00000000..2f3d1104
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_add.c
@@ -0,0 +1,313 @@
+/* crypto/bn/bn_add.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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ const BIGNUM *tmp;
+ int a_neg = a->neg, ret;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /*-
+ * a + b a+b
+ * a + -b a-b
+ * -a + b b-a
+ * -a + -b -(a+b)
+ */
+ if (a_neg ^ b->neg) {
+ /* only one is negative */
+ if (a_neg) {
+ tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+ /* we are now a - b */
+
+ if (BN_ucmp(a, b) < 0) {
+ if (!BN_usub(r, b, a))
+ return (0);
+ r->neg = 1;
+ } else {
+ if (!BN_usub(r, a, b))
+ return (0);
+ r->neg = 0;
+ }
+ return (1);
+ }
+
+ ret = BN_uadd(r, a, b);
+ r->neg = a_neg;
+ bn_check_top(r);
+ return ret;
+}
+
+/* unsigned add of b to a */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int max, min, dif;
+ BN_ULONG *ap, *bp, *rp, carry, t1, t2;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top) {
+ tmp = a;
+ a = b;
+ b = tmp;
+ }
+ max = a->top;
+ min = b->top;
+ dif = max - min;
+
+ if (bn_wexpand(r, max + 1) == NULL)
+ return 0;
+
+ r->top = max;
+
+ ap = a->d;
+ bp = b->d;
+ rp = r->d;
+
+ carry = bn_add_words(rp, ap, bp, min);
+ rp += min;
+ ap += min;
+ bp += min;
+
+ if (carry) {
+ while (dif) {
+ dif--;
+ t1 = *(ap++);
+ t2 = (t1 + 1) & BN_MASK2;
+ *(rp++) = t2;
+ if (t2) {
+ carry = 0;
+ break;
+ }
+ }
+ if (carry) {
+ /* carry != 0 => dif == 0 */
+ *rp = 1;
+ r->top++;
+ }
+ }
+ if (dif && rp != ap)
+ while (dif--)
+ /* copy remaining words if ap != rp */
+ *(rp++) = *(ap++);
+ r->neg = 0;
+ bn_check_top(r);
+ return 1;
+}
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int max, min, dif;
+ register BN_ULONG t1, t2, *ap, *bp, *rp;
+ int i, carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+ int dummy;
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ max = a->top;
+ min = b->top;
+ dif = max - min;
+
+ if (dif < 0) { /* hmm... should not be happening */
+ BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
+ return (0);
+ }
+
+ if (bn_wexpand(r, max) == NULL)
+ return (0);
+
+ ap = a->d;
+ bp = b->d;
+ rp = r->d;
+
+#if 1
+ carry = 0;
+ for (i = min; i != 0; i--) {
+ t1 = *(ap++);
+ t2 = *(bp++);
+ if (carry) {
+ carry = (t1 <= t2);
+ t1 = (t1 - t2 - 1) & BN_MASK2;
+ } else {
+ carry = (t1 < t2);
+ t1 = (t1 - t2) & BN_MASK2;
+ }
+# if defined(IRIX_CC_BUG) && !defined(LINT)
+ dummy = t1;
+# endif
+ *(rp++) = t1 & BN_MASK2;
+ }
+#else
+ carry = bn_sub_words(rp, ap, bp, min);
+ ap += min;
+ bp += min;
+ rp += min;
+#endif
+ if (carry) { /* subtracted */
+ if (!dif)
+ /* error: a < b */
+ return 0;
+ while (dif) {
+ dif--;
+ t1 = *(ap++);
+ t2 = (t1 - 1) & BN_MASK2;
+ *(rp++) = t2;
+ if (t1)
+ break;
+ }
+ }
+#if 0
+ memcpy(rp, ap, sizeof(*rp) * (max - i));
+#else
+ if (rp != ap) {
+ for (;;) {
+ if (!dif--)
+ break;
+ rp[0] = ap[0];
+ if (!dif--)
+ break;
+ rp[1] = ap[1];
+ if (!dif--)
+ break;
+ rp[2] = ap[2];
+ if (!dif--)
+ break;
+ rp[3] = ap[3];
+ rp += 4;
+ ap += 4;
+ }
+ }
+#endif
+
+ r->top = max;
+ r->neg = 0;
+ bn_correct_top(r);
+ return (1);
+}
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int max;
+ int add = 0, neg = 0;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /*-
+ * a - b a-b
+ * a - -b a+b
+ * -a - b -(a+b)
+ * -a - -b b-a
+ */
+ if (a->neg) {
+ if (b->neg) {
+ tmp = a;
+ a = b;
+ b = tmp;
+ } else {
+ add = 1;
+ neg = 1;
+ }
+ } else {
+ if (b->neg) {
+ add = 1;
+ neg = 0;
+ }
+ }
+
+ if (add) {
+ if (!BN_uadd(r, a, b))
+ return (0);
+ r->neg = neg;
+ return (1);
+ }
+
+ /* We are actually doing a - b :-) */
+
+ max = (a->top > b->top) ? a->top : b->top;
+ if (bn_wexpand(r, max) == NULL)
+ return (0);
+ if (BN_ucmp(a, b) < 0) {
+ if (!BN_usub(r, b, a))
+ return (0);
+ r->neg = 1;
+ } else {
+ if (!BN_usub(r, a, b))
+ return (0);
+ r->neg = 0;
+ }
+ bn_check_top(r);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_asm.c b/Cryptlib/OpenSSL/crypto/bn/bn_asm.c
new file mode 100644
index 00000000..03a33cff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_asm.c
@@ -0,0 +1,1093 @@
+/* crypto/bn/bn_asm.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 <stdio.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w)
+{
+ BN_ULONG c1 = 0;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return (c1);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (num & ~3) {
+ mul_add(rp[0], ap[0], w, c1);
+ mul_add(rp[1], ap[1], w, c1);
+ mul_add(rp[2], ap[2], w, c1);
+ mul_add(rp[3], ap[3], w, c1);
+ ap += 4;
+ rp += 4;
+ num -= 4;
+ }
+# endif
+ while (num) {
+ mul_add(rp[0], ap[0], w, c1);
+ ap++;
+ rp++;
+ num--;
+ }
+
+ return (c1);
+}
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+ BN_ULONG c1 = 0;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return (c1);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (num & ~3) {
+ mul(rp[0], ap[0], w, c1);
+ mul(rp[1], ap[1], w, c1);
+ mul(rp[2], ap[2], w, c1);
+ mul(rp[3], ap[3], w, c1);
+ ap += 4;
+ rp += 4;
+ num -= 4;
+ }
+# endif
+ while (num) {
+ mul(rp[0], ap[0], w, c1);
+ ap++;
+ rp++;
+ num--;
+ }
+ return (c1);
+}
+
+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]);
+ sqr(r[2], r[3], a[1]);
+ sqr(r[4], r[5], a[2]);
+ sqr(r[6], r[7], a[3]);
+ a += 4;
+ r += 8;
+ n -= 4;
+ }
+# endif
+ while (n) {
+ sqr(r[0], r[1], a[0]);
+ a++;
+ r += 2;
+ n--;
+ }
+}
+
+#else /* !(defined(BN_LLONG) ||
+ * defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w)
+{
+ BN_ULONG c = 0;
+ BN_ULONG bl, bh;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return ((BN_ULONG)0);
+
+ bl = LBITS(w);
+ bh = HBITS(w);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (num & ~3) {
+ mul_add(rp[0], ap[0], bl, bh, c);
+ mul_add(rp[1], ap[1], bl, bh, c);
+ mul_add(rp[2], ap[2], bl, bh, c);
+ mul_add(rp[3], ap[3], bl, bh, c);
+ ap += 4;
+ rp += 4;
+ num -= 4;
+ }
+# endif
+ while (num) {
+ mul_add(rp[0], ap[0], bl, bh, c);
+ ap++;
+ rp++;
+ num--;
+ }
+ return (c);
+}
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+ BN_ULONG carry = 0;
+ BN_ULONG bl, bh;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return ((BN_ULONG)0);
+
+ bl = LBITS(w);
+ bh = HBITS(w);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (num & ~3) {
+ mul(rp[0], ap[0], bl, bh, carry);
+ mul(rp[1], ap[1], bl, bh, carry);
+ mul(rp[2], ap[2], bl, bh, carry);
+ mul(rp[3], ap[3], bl, bh, carry);
+ ap += 4;
+ rp += 4;
+ num -= 4;
+ }
+# endif
+ while (num) {
+ mul(rp[0], ap[0], bl, bh, carry);
+ ap++;
+ rp++;
+ num--;
+ }
+ return (carry);
+}
+
+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) {
+ sqr64(r[0], r[1], a[0]);
+ sqr64(r[2], r[3], a[1]);
+ sqr64(r[4], r[5], a[2]);
+ sqr64(r[6], r[7], a[3]);
+ a += 4;
+ r += 8;
+ n -= 4;
+ }
+# endif
+ while (n) {
+ sqr64(r[0], r[1], a[0]);
+ a++;
+ r += 2;
+ n--;
+ }
+}
+
+#endif /* !(defined(BN_LLONG) ||
+ * defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+ return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d));
+}
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+ BN_ULONG dh, dl, q, ret = 0, th, tl, t;
+ int i, count = 2;
+
+ if (d == 0)
+ return (BN_MASK2);
+
+ i = BN_num_bits_word(d);
+ assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
+
+ i = BN_BITS2 - i;
+ if (h >= d)
+ h -= d;
+
+ if (i) {
+ d <<= i;
+ h = (h << i) | (l >> (BN_BITS2 - i));
+ l <<= i;
+ }
+ dh = (d & BN_MASK2h) >> BN_BITS4;
+ dl = (d & BN_MASK2l);
+ for (;;) {
+ if ((h >> BN_BITS4) == dh)
+ q = BN_MASK2l;
+ else
+ q = h / dh;
+
+ th = q * dh;
+ tl = dl * q;
+ for (;;) {
+ t = h - th;
+ if ((t & BN_MASK2h) ||
+ ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4))))
+ break;
+ q--;
+ th -= dh;
+ tl -= dl;
+ }
+ t = (tl >> BN_BITS4);
+ tl = (tl << BN_BITS4) & BN_MASK2h;
+ th += t;
+
+ if (l < tl)
+ th++;
+ l -= tl;
+ if (h < th) {
+ h += d;
+ q--;
+ }
+ h -= th;
+
+ if (--count == 0)
+ break;
+
+ ret = q << BN_BITS4;
+ h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+ l = (l & BN_MASK2l) << BN_BITS4;
+ }
+ ret |= q;
+ return (ret);
+}
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int n)
+{
+ BN_ULLONG ll = 0;
+
+ assert(n >= 0);
+ if (n <= 0)
+ return ((BN_ULONG)0);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (n & ~3) {
+ ll += (BN_ULLONG) a[0] + b[0];
+ r[0] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ ll += (BN_ULLONG) a[1] + b[1];
+ r[1] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ ll += (BN_ULLONG) a[2] + b[2];
+ r[2] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ ll += (BN_ULLONG) a[3] + b[3];
+ r[3] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ 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);
+}
+#else /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int n)
+{
+ BN_ULONG c, l, t;
+
+ assert(n >= 0);
+ if (n <= 0)
+ return ((BN_ULONG)0);
+
+ c = 0;
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (n & ~3) {
+ t = a[0];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[0]) & BN_MASK2;
+ c += (l < t);
+ r[0] = l;
+ t = a[1];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[1]) & BN_MASK2;
+ c += (l < t);
+ r[1] = l;
+ t = a[2];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[2]) & BN_MASK2;
+ c += (l < t);
+ r[2] = l;
+ t = a[3];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[3]) & BN_MASK2;
+ c += (l < t);
+ r[3] = l;
+ 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);
+}
+#endif /* !BN_LLONG */
+
+BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int n)
+{
+ BN_ULONG t1, t2;
+ int c = 0;
+
+ assert(n >= 0);
+ if (n <= 0)
+ return ((BN_ULONG)0);
+
+#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);
+ t1 = a[1];
+ t2 = b[1];
+ r[1] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ t1 = a[2];
+ t2 = b[2];
+ r[2] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ t1 = a[3];
+ t2 = b[3];
+ r[3] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ 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);
+}
+
+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
+
+# undef bn_mul_comba8
+# undef bn_mul_comba4
+# undef bn_sqr_comba8
+# undef bn_sqr_comba4
+
+/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/*
+ * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number
+ * c=(c2,c1,c0)
+ */
+
+# ifdef BN_LLONG
+/*
+ * Keep in mind that additions to multiplication result can not
+ * overflow, because its high half cannot be all-ones.
+ */
+# define mul_add_c(a,b,c0,c1,c2) do { \
+ BN_ULONG hi; \
+ BN_ULLONG t = (BN_ULLONG)(a)*(b); \
+ t += c0; /* no carry */ \
+ c0 = (BN_ULONG)Lw(t); \
+ hi = (BN_ULONG)Hw(t); \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ } while(0)
+
+# define mul_add_c2(a,b,c0,c1,c2) do { \
+ BN_ULONG hi; \
+ BN_ULLONG t = (BN_ULLONG)(a)*(b); \
+ BN_ULLONG tt = t+c0; /* no carry */ \
+ c0 = (BN_ULONG)Lw(tt); \
+ hi = (BN_ULONG)Hw(tt); \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ t += c0; /* no carry */ \
+ c0 = (BN_ULONG)Lw(t); \
+ hi = (BN_ULONG)Hw(t); \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ } while(0)
+
+# define sqr_add_c(a,i,c0,c1,c2) do { \
+ BN_ULONG hi; \
+ BN_ULLONG t = (BN_ULLONG)a[i]*a[i]; \
+ t += c0; /* no carry */ \
+ c0 = (BN_ULONG)Lw(t); \
+ hi = (BN_ULONG)Hw(t); \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ } while(0)
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# elif defined(BN_UMULT_LOHI)
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+# define mul_add_c(a,b,c0,c1,c2) do { \
+ BN_ULONG ta = (a), tb = (b); \
+ BN_ULONG lo, hi; \
+ BN_UMULT_LOHI(lo,hi,ta,tb); \
+ c0 += lo; hi += (c0<lo)?1:0; \
+ c1 += hi; c2 += (c1<hi)?1:0; \
+ } while(0)
+
+# define mul_add_c2(a,b,c0,c1,c2) do { \
+ BN_ULONG ta = (a), tb = (b); \
+ BN_ULONG lo, hi, tt; \
+ BN_UMULT_LOHI(lo,hi,ta,tb); \
+ c0 += lo; tt = hi+((c0<lo)?1:0); \
+ c1 += tt; c2 += (c1<tt)?1:0; \
+ c0 += lo; hi += (c0<lo)?1:0; \
+ c1 += hi; c2 += (c1<hi)?1:0; \
+ } while(0)
+
+# define sqr_add_c(a,i,c0,c1,c2) do { \
+ BN_ULONG ta = (a)[i]; \
+ BN_ULONG lo, hi; \
+ BN_UMULT_LOHI(lo,hi,ta,ta); \
+ c0 += lo; hi += (c0<lo)?1:0; \
+ c1 += hi; c2 += (c1<hi)?1:0; \
+ } while(0)
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# elif defined(BN_UMULT_HIGH)
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+# define mul_add_c(a,b,c0,c1,c2) do { \
+ BN_ULONG ta = (a), tb = (b); \
+ BN_ULONG lo = ta * tb; \
+ BN_ULONG hi = BN_UMULT_HIGH(ta,tb); \
+ c0 += lo; hi += (c0<lo)?1:0; \
+ c1 += hi; c2 += (c1<hi)?1:0; \
+ } while(0)
+
+# define mul_add_c2(a,b,c0,c1,c2) do { \
+ BN_ULONG ta = (a), tb = (b), tt; \
+ BN_ULONG lo = ta * tb; \
+ BN_ULONG hi = BN_UMULT_HIGH(ta,tb); \
+ c0 += lo; tt = hi + ((c0<lo)?1:0); \
+ c1 += tt; c2 += (c1<tt)?1:0; \
+ c0 += lo; hi += (c0<lo)?1:0; \
+ c1 += hi; c2 += (c1<hi)?1:0; \
+ } while(0)
+
+# define sqr_add_c(a,i,c0,c1,c2) do { \
+ BN_ULONG ta = (a)[i]; \
+ BN_ULONG lo = ta * ta; \
+ BN_ULONG hi = BN_UMULT_HIGH(ta,ta); \
+ c0 += lo; hi += (c0<lo)?1:0; \
+ c1 += hi; c2 += (c1<hi)?1:0; \
+ } while(0)
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# else /* !BN_LLONG */
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+# define mul_add_c(a,b,c0,c1,c2) do { \
+ BN_ULONG lo = LBITS(a), hi = HBITS(a); \
+ BN_ULONG bl = LBITS(b), bh = HBITS(b); \
+ mul64(lo,hi,bl,bh); \
+ c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ } while(0)
+
+# define mul_add_c2(a,b,c0,c1,c2) do { \
+ BN_ULONG tt; \
+ BN_ULONG lo = LBITS(a), hi = HBITS(a); \
+ BN_ULONG bl = LBITS(b), bh = HBITS(b); \
+ mul64(lo,hi,bl,bh); \
+ tt = hi; \
+ c0 = (c0+lo)&BN_MASK2; if (c0<lo) tt++; \
+ c1 = (c1+tt)&BN_MASK2; if (c1<tt) c2++; \
+ c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ } while(0)
+
+# define sqr_add_c(a,i,c0,c1,c2) do { \
+ BN_ULONG lo, hi; \
+ sqr64(lo,hi,(a)[i]); \
+ c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+ c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+ } while(0)
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+# endif /* !BN_LLONG */
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+ BN_ULONG c1, c2, c3;
+
+ c1 = 0;
+ c2 = 0;
+ c3 = 0;
+ mul_add_c(a[0], b[0], c1, c2, c3);
+ r[0] = c1;
+ c1 = 0;
+ mul_add_c(a[0], b[1], c2, c3, c1);
+ mul_add_c(a[1], b[0], c2, c3, c1);
+ r[1] = c2;
+ c2 = 0;
+ mul_add_c(a[2], b[0], c3, c1, c2);
+ mul_add_c(a[1], b[1], c3, c1, c2);
+ mul_add_c(a[0], b[2], c3, c1, c2);
+ r[2] = c3;
+ c3 = 0;
+ mul_add_c(a[0], b[3], c1, c2, c3);
+ mul_add_c(a[1], b[2], c1, c2, c3);
+ mul_add_c(a[2], b[1], c1, c2, c3);
+ mul_add_c(a[3], b[0], c1, c2, c3);
+ r[3] = c1;
+ c1 = 0;
+ mul_add_c(a[4], b[0], c2, c3, c1);
+ mul_add_c(a[3], b[1], c2, c3, c1);
+ mul_add_c(a[2], b[2], c2, c3, c1);
+ mul_add_c(a[1], b[3], c2, c3, c1);
+ mul_add_c(a[0], b[4], c2, c3, c1);
+ r[4] = c2;
+ c2 = 0;
+ mul_add_c(a[0], b[5], c3, c1, c2);
+ mul_add_c(a[1], b[4], c3, c1, c2);
+ mul_add_c(a[2], b[3], c3, c1, c2);
+ mul_add_c(a[3], b[2], c3, c1, c2);
+ mul_add_c(a[4], b[1], c3, c1, c2);
+ mul_add_c(a[5], b[0], c3, c1, c2);
+ r[5] = c3;
+ c3 = 0;
+ mul_add_c(a[6], b[0], c1, c2, c3);
+ mul_add_c(a[5], b[1], c1, c2, c3);
+ mul_add_c(a[4], b[2], c1, c2, c3);
+ mul_add_c(a[3], b[3], c1, c2, c3);
+ mul_add_c(a[2], b[4], c1, c2, c3);
+ mul_add_c(a[1], b[5], c1, c2, c3);
+ mul_add_c(a[0], b[6], c1, c2, c3);
+ r[6] = c1;
+ c1 = 0;
+ mul_add_c(a[0], b[7], c2, c3, c1);
+ mul_add_c(a[1], b[6], c2, c3, c1);
+ mul_add_c(a[2], b[5], c2, c3, c1);
+ mul_add_c(a[3], b[4], c2, c3, c1);
+ mul_add_c(a[4], b[3], c2, c3, c1);
+ mul_add_c(a[5], b[2], c2, c3, c1);
+ mul_add_c(a[6], b[1], c2, c3, c1);
+ mul_add_c(a[7], b[0], c2, c3, c1);
+ r[7] = c2;
+ c2 = 0;
+ mul_add_c(a[7], b[1], c3, c1, c2);
+ mul_add_c(a[6], b[2], c3, c1, c2);
+ mul_add_c(a[5], b[3], c3, c1, c2);
+ mul_add_c(a[4], b[4], c3, c1, c2);
+ mul_add_c(a[3], b[5], c3, c1, c2);
+ mul_add_c(a[2], b[6], c3, c1, c2);
+ mul_add_c(a[1], b[7], c3, c1, c2);
+ r[8] = c3;
+ c3 = 0;
+ mul_add_c(a[2], b[7], c1, c2, c3);
+ mul_add_c(a[3], b[6], c1, c2, c3);
+ mul_add_c(a[4], b[5], c1, c2, c3);
+ mul_add_c(a[5], b[4], c1, c2, c3);
+ mul_add_c(a[6], b[3], c1, c2, c3);
+ mul_add_c(a[7], b[2], c1, c2, c3);
+ r[9] = c1;
+ c1 = 0;
+ mul_add_c(a[7], b[3], c2, c3, c1);
+ mul_add_c(a[6], b[4], c2, c3, c1);
+ mul_add_c(a[5], b[5], c2, c3, c1);
+ mul_add_c(a[4], b[6], c2, c3, c1);
+ mul_add_c(a[3], b[7], c2, c3, c1);
+ r[10] = c2;
+ c2 = 0;
+ mul_add_c(a[4], b[7], c3, c1, c2);
+ mul_add_c(a[5], b[6], c3, c1, c2);
+ mul_add_c(a[6], b[5], c3, c1, c2);
+ mul_add_c(a[7], b[4], c3, c1, c2);
+ r[11] = c3;
+ c3 = 0;
+ mul_add_c(a[7], b[5], c1, c2, c3);
+ mul_add_c(a[6], b[6], c1, c2, c3);
+ mul_add_c(a[5], b[7], c1, c2, c3);
+ r[12] = c1;
+ c1 = 0;
+ mul_add_c(a[6], b[7], c2, c3, c1);
+ mul_add_c(a[7], b[6], c2, c3, c1);
+ r[13] = c2;
+ c2 = 0;
+ mul_add_c(a[7], b[7], c3, c1, c2);
+ r[14] = c3;
+ r[15] = c1;
+}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+ BN_ULONG c1, c2, c3;
+
+ c1 = 0;
+ c2 = 0;
+ c3 = 0;
+ mul_add_c(a[0], b[0], c1, c2, c3);
+ r[0] = c1;
+ c1 = 0;
+ mul_add_c(a[0], b[1], c2, c3, c1);
+ mul_add_c(a[1], b[0], c2, c3, c1);
+ r[1] = c2;
+ c2 = 0;
+ mul_add_c(a[2], b[0], c3, c1, c2);
+ mul_add_c(a[1], b[1], c3, c1, c2);
+ mul_add_c(a[0], b[2], c3, c1, c2);
+ r[2] = c3;
+ c3 = 0;
+ mul_add_c(a[0], b[3], c1, c2, c3);
+ mul_add_c(a[1], b[2], c1, c2, c3);
+ mul_add_c(a[2], b[1], c1, c2, c3);
+ mul_add_c(a[3], b[0], c1, c2, c3);
+ r[3] = c1;
+ c1 = 0;
+ mul_add_c(a[3], b[1], c2, c3, c1);
+ mul_add_c(a[2], b[2], c2, c3, c1);
+ mul_add_c(a[1], b[3], c2, c3, c1);
+ r[4] = c2;
+ c2 = 0;
+ mul_add_c(a[2], b[3], c3, c1, c2);
+ mul_add_c(a[3], b[2], c3, c1, c2);
+ r[5] = c3;
+ c3 = 0;
+ mul_add_c(a[3], b[3], c1, c2, c3);
+ r[6] = c1;
+ r[7] = c2;
+}
+
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+{
+ BN_ULONG c1, c2, c3;
+
+ c1 = 0;
+ c2 = 0;
+ c3 = 0;
+ sqr_add_c(a, 0, c1, c2, c3);
+ r[0] = c1;
+ c1 = 0;
+ sqr_add_c2(a, 1, 0, c2, c3, c1);
+ r[1] = c2;
+ c2 = 0;
+ sqr_add_c(a, 1, c3, c1, c2);
+ sqr_add_c2(a, 2, 0, c3, c1, c2);
+ r[2] = c3;
+ c3 = 0;
+ sqr_add_c2(a, 3, 0, c1, c2, c3);
+ sqr_add_c2(a, 2, 1, c1, c2, c3);
+ r[3] = c1;
+ c1 = 0;
+ sqr_add_c(a, 2, c2, c3, c1);
+ sqr_add_c2(a, 3, 1, c2, c3, c1);
+ sqr_add_c2(a, 4, 0, c2, c3, c1);
+ r[4] = c2;
+ c2 = 0;
+ sqr_add_c2(a, 5, 0, c3, c1, c2);
+ sqr_add_c2(a, 4, 1, c3, c1, c2);
+ sqr_add_c2(a, 3, 2, c3, c1, c2);
+ r[5] = c3;
+ c3 = 0;
+ sqr_add_c(a, 3, c1, c2, c3);
+ sqr_add_c2(a, 4, 2, c1, c2, c3);
+ sqr_add_c2(a, 5, 1, c1, c2, c3);
+ sqr_add_c2(a, 6, 0, c1, c2, c3);
+ r[6] = c1;
+ c1 = 0;
+ sqr_add_c2(a, 7, 0, c2, c3, c1);
+ sqr_add_c2(a, 6, 1, c2, c3, c1);
+ sqr_add_c2(a, 5, 2, c2, c3, c1);
+ sqr_add_c2(a, 4, 3, c2, c3, c1);
+ r[7] = c2;
+ c2 = 0;
+ sqr_add_c(a, 4, c3, c1, c2);
+ sqr_add_c2(a, 5, 3, c3, c1, c2);
+ sqr_add_c2(a, 6, 2, c3, c1, c2);
+ sqr_add_c2(a, 7, 1, c3, c1, c2);
+ r[8] = c3;
+ c3 = 0;
+ sqr_add_c2(a, 7, 2, c1, c2, c3);
+ sqr_add_c2(a, 6, 3, c1, c2, c3);
+ sqr_add_c2(a, 5, 4, c1, c2, c3);
+ r[9] = c1;
+ c1 = 0;
+ sqr_add_c(a, 5, c2, c3, c1);
+ sqr_add_c2(a, 6, 4, c2, c3, c1);
+ sqr_add_c2(a, 7, 3, c2, c3, c1);
+ r[10] = c2;
+ c2 = 0;
+ sqr_add_c2(a, 7, 4, c3, c1, c2);
+ sqr_add_c2(a, 6, 5, c3, c1, c2);
+ r[11] = c3;
+ c3 = 0;
+ sqr_add_c(a, 6, c1, c2, c3);
+ sqr_add_c2(a, 7, 5, c1, c2, c3);
+ r[12] = c1;
+ c1 = 0;
+ sqr_add_c2(a, 7, 6, c2, c3, c1);
+ r[13] = c2;
+ c2 = 0;
+ sqr_add_c(a, 7, c3, c1, c2);
+ r[14] = c3;
+ r[15] = c1;
+}
+
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+{
+ BN_ULONG c1, c2, c3;
+
+ c1 = 0;
+ c2 = 0;
+ c3 = 0;
+ sqr_add_c(a, 0, c1, c2, c3);
+ r[0] = c1;
+ c1 = 0;
+ sqr_add_c2(a, 1, 0, c2, c3, c1);
+ r[1] = c2;
+ c2 = 0;
+ sqr_add_c(a, 1, c3, c1, c2);
+ sqr_add_c2(a, 2, 0, c3, c1, c2);
+ r[2] = c3;
+ c3 = 0;
+ sqr_add_c2(a, 3, 0, c1, c2, c3);
+ sqr_add_c2(a, 2, 1, c1, c2, c3);
+ r[3] = c1;
+ c1 = 0;
+ sqr_add_c(a, 2, c2, c3, c1);
+ sqr_add_c2(a, 3, 1, c2, c3, c1);
+ r[4] = c2;
+ c2 = 0;
+ sqr_add_c2(a, 3, 2, c3, c1, c2);
+ r[5] = c3;
+ c3 = 0;
+ sqr_add_c(a, 3, c1, c2, c3);
+ r[6] = c1;
+ r[7] = c2;
+}
+
+# ifdef OPENSSL_NO_ASM
+# ifdef OPENSSL_BN_ASM_MONT
+# include <alloca.h>
+/*
+ * 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 < num; ++j)
+ mul(tp[j], ap[j], ml, mh, c0);
+# else
+ for (j = 0; j < num; ++j)
+ mul(tp[j], ap[j], ml, c0);
+# endif
+
+ tp[num] = c0;
+ tp[num + 1] = 0;
+ goto enter;
+
+ for (i = 0; i < num; i++) {
+ c0 = 0;
+ ml = bp[i];
+# ifdef mul64
+ mh = HBITS(ml);
+ ml = LBITS(ml);
+ for (j = 0; j < num; ++j)
+ mul_add(tp[j], ap[j], ml, mh, c0);
+# else
+ for (j = 0; j < num; ++j)
+ mul_add(tp[j], ap[j], ml, c0);
+# endif
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num] = c1;
+ tp[num + 1] = (c1 < c0 ? 1 : 0);
+ enter:
+ c1 = tp[0];
+ ml = (c1 * n0) & BN_MASK2;
+ c0 = 0;
+# ifdef mul64
+ mh = HBITS(ml);
+ ml = LBITS(ml);
+ mul_add(c1, np[0], ml, mh, c0);
+# else
+ mul_add(c1, ml, np[0], c0);
+# endif
+ for (j = 1; j < num; j++) {
+ c1 = tp[j];
+# ifdef mul64
+ mul_add(c1, np[j], ml, mh, c0);
+# else
+ mul_add(c1, ml, np[j], c0);
+# endif
+ tp[j - 1] = c1 & BN_MASK2;
+ }
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num - 1] = c1;
+ tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0);
+ }
+
+ if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+ c0 = bn_sub_words(rp, tp, np, num);
+ if (tp[num] != 0 || c0 == 0) {
+ for (i = 0; i < num + 2; i++)
+ vp[i] = 0;
+ return 1;
+ }
+ }
+ for (i = 0; i < num; i++)
+ rp[i] = tp[i], vp[i] = 0;
+ vp[num] = 0;
+ vp[num + 1] = 0;
+ return 1;
+}
+# else
+/*
+ * Return value of 0 indicates that multiplication/convolution was not
+ * performed to signal the caller to fall down to alternative/original
+ * code-path.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+ return 0;
+}
+# endif /* OPENSSL_BN_ASM_MONT */
+# endif
+
+#else /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+# undef bn_sqr_comba4
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+{
+ BN_ULONG t[8];
+ bn_sqr_normal(r, a, 4, t);
+}
+
+# undef bn_sqr_comba8
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+{
+ BN_ULONG t[16];
+ bn_sqr_normal(r, a, 8, t);
+}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+ r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
+ r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
+ r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]);
+ r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
+}
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+ r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
+ r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);
+ r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]);
+ r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]);
+ r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]);
+ r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]);
+ r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]);
+ r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]);
+}
+
+# ifdef OPENSSL_NO_ASM
+# ifdef OPENSSL_BN_ASM_MONT
+# include <alloca.h>
+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 < num; i++) {
+ c0 = bn_mul_add_words(tp, ap, num, bp[i]);
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num] = c1;
+ tp[num + 1] = (c1 < c0 ? 1 : 0);
+
+ c0 = bn_mul_add_words(tp, np, num, tp[0] * n0);
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num] = c1;
+ tp[num + 1] += (c1 < c0 ? 1 : 0);
+ for (j = 0; j <= num; j++)
+ tp[j] = tp[j + 1];
+ }
+
+ if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+ c0 = bn_sub_words(rp, tp, np, num);
+ if (tp[num] != 0 || c0 == 0) {
+ for (i = 0; i < num + 2; i++)
+ vp[i] = 0;
+ return 1;
+ }
+ }
+ for (i = 0; i < num; i++)
+ rp[i] = tp[i], vp[i] = 0;
+ vp[num] = 0;
+ vp[num + 1] = 0;
+ return 1;
+}
+# else
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+ return 0;
+}
+# endif /* OPENSSL_BN_ASM_MONT */
+# endif
+
+#endif /* !BN_MUL_COMBA */
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_blind.c b/Cryptlib/OpenSSL/crypto/bn/bn_blind.c
new file mode 100644
index 00000000..d448daa3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_blind.c
@@ -0,0 +1,385 @@
+/* crypto/bn/bn_blind.c */
+/* ====================================================================
+ * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define BN_BLINDING_COUNTER 32
+
+struct bn_blinding_st {
+ BIGNUM *A;
+ BIGNUM *Ai;
+ BIGNUM *e;
+ BIGNUM *mod; /* just a reference */
+#ifndef OPENSSL_NO_DEPRECATED
+ unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; used
+ * only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+#endif
+ CRYPTO_THREADID tid;
+ int counter;
+ unsigned long flags;
+ BN_MONT_CTX *m_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_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+{
+ BN_BLINDING *ret = NULL;
+
+ bn_check_top(mod);
+
+ if ((ret = (BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) {
+ BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(BN_BLINDING));
+ if (A != NULL) {
+ if ((ret->A = BN_dup(A)) == NULL)
+ goto err;
+ }
+ if (Ai != NULL) {
+ if ((ret->Ai = BN_dup(Ai)) == NULL)
+ goto err;
+ }
+
+ /* save a copy of mod in the BN_BLINDING structure */
+ if ((ret->mod = BN_dup(mod)) == NULL)
+ goto err;
+ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+ BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+ /*
+ * Set the counter to the special value -1 to indicate that this is
+ * never-used fresh blinding that does not need updating before first
+ * use.
+ */
+ ret->counter = -1;
+ CRYPTO_THREADID_current(&ret->tid);
+ return (ret);
+ err:
+ if (ret != NULL)
+ BN_BLINDING_free(ret);
+ return (NULL);
+}
+
+void BN_BLINDING_free(BN_BLINDING *r)
+{
+ if (r == NULL)
+ return;
+
+ if (r->A != NULL)
+ BN_free(r->A);
+ if (r->Ai != NULL)
+ BN_free(r->Ai);
+ if (r->e != NULL)
+ BN_free(r->e);
+ if (r->mod != NULL)
+ BN_free(r->mod);
+ OPENSSL_free(r);
+}
+
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
+{
+ int ret = 0;
+
+ if ((b->A == NULL) || (b->Ai == NULL)) {
+ BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED);
+ goto err;
+ }
+
+ if (b->counter == -1)
+ b->counter = 0;
+
+ if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
+ !(b->flags & BN_BLINDING_NO_RECREATE)) {
+ /* re-create blinding parameters */
+ if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
+ goto err;
+ } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
+ if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
+ goto err;
+ if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
+ goto err;
+ }
+
+ ret = 1;
+ err:
+ if (b->counter == BN_BLINDING_COUNTER)
+ b->counter = 0;
+ return (ret);
+}
+
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+ return BN_BLINDING_convert_ex(n, NULL, b, ctx);
+}
+
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+{
+ int ret = 1;
+
+ bn_check_top(n);
+
+ if ((b->A == NULL) || (b->Ai == NULL)) {
+ BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED);
+ return (0);
+ }
+
+ if (b->counter == -1)
+ /* Fresh blinding, doesn't need updating. */
+ b->counter = 0;
+ else if (!BN_BLINDING_update(b, ctx))
+ return (0);
+
+ if (r != NULL) {
+ if (!BN_copy(r, b->Ai))
+ ret = 0;
+ }
+
+ if (!BN_mod_mul(n, n, b->A, b->mod, ctx))
+ ret = 0;
+
+ return ret;
+}
+
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+ return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+}
+
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+ BN_CTX *ctx)
+{
+ int ret;
+
+ bn_check_top(n);
+
+ if (r != NULL)
+ ret = BN_mod_mul(n, n, r, b->mod, ctx);
+ else {
+ if (b->Ai == NULL) {
+ BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
+ return (0);
+ }
+ ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
+ }
+
+ bn_check_top(n);
+ return (ret);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
+{
+ return b->thread_id;
+}
+
+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)
+{
+ return b->flags;
+}
+
+void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
+{
+ b->flags = flags;
+}
+
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+ 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)
+{
+ int retry_counter = 32;
+ BN_BLINDING *ret = NULL;
+
+ if (b == NULL)
+ ret = BN_BLINDING_new(NULL, NULL, m);
+ else
+ ret = b;
+
+ if (ret == NULL)
+ goto err;
+
+ if (ret->A == NULL && (ret->A = BN_new()) == NULL)
+ goto err;
+ if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
+ goto err;
+
+ if (e != NULL) {
+ if (ret->e != NULL)
+ BN_free(ret->e);
+ ret->e = BN_dup(e);
+ }
+ if (ret->e == NULL)
+ goto err;
+
+ if (bn_mod_exp != NULL)
+ ret->bn_mod_exp = bn_mod_exp;
+ if (m_ctx != NULL)
+ ret->m_ctx = m_ctx;
+
+ do {
+ if (!BN_rand_range(ret->A, ret->mod))
+ goto err;
+ if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) {
+ /*
+ * this should almost never happen for good RSA keys
+ */
+ unsigned long error = ERR_peek_last_error();
+ if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ if (retry_counter-- == 0) {
+ BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
+ BN_R_TOO_MANY_ITERATIONS);
+ goto err;
+ }
+ ERR_clear_error();
+ } else
+ goto err;
+ } else
+ break;
+ } while (1);
+
+ if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
+ if (!ret->bn_mod_exp
+ (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
+ goto err;
+ } else {
+ if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
+ goto err;
+ }
+
+ return ret;
+ err:
+ if (b == NULL && ret != NULL) {
+ BN_BLINDING_free(ret);
+ ret = NULL;
+ }
+
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_const.c b/Cryptlib/OpenSSL/crypto/bn/bn_const.c
new file mode 100644
index 00000000..12c3208c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_const.c
@@ -0,0 +1,547 @@
+/* crypto/bn/knownprimes.c */
+/* Insert boilerplate */
+
+#include "bn.h"
+
+/*-
+ * "First Oakley Default Group" from RFC2409, section 6.1.
+ *
+ * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of of 22.
+ */
+
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn)
+{
+ static const unsigned char RFC2409_PRIME_768[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn);
+}
+
+/*-
+ * "Second Oakley Default Group" from RFC2409, section 6.2.
+ *
+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of 22.
+ */
+
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn)
+{
+ static const unsigned char RFC2409_PRIME_1024[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn);
+}
+
+/*-
+ * "1536-bit MODP Group" from RFC3526, Section 2.
+ *
+ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
+ *
+ * RFC3526 specifies a generator of 2.
+ * RFC2312 specifies a generator of 22.
+ */
+
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_1536[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn);
+}
+
+/*-
+ * "2048-bit MODP Group" from RFC3526, Section 3.
+ *
+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_2048[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn);
+}
+
+/*-
+ * "3072-bit MODP Group" from RFC3526, Section 4.
+ *
+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_3072[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn);
+}
+
+/*-
+ * "4096-bit MODP Group" from RFC3526, Section 5.
+ *
+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_4096[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn);
+}
+
+/*-
+ * "6144-bit MODP Group" from RFC3526, Section 6.
+ *
+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_6144[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+ 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+ 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+ 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+ 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+ 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+ 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+ 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+ 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+ 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+ 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+ 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+ 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+ 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+ 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+ 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+ 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+ 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+ 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+ 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+ 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+ 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+ 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+ 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+ 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+ 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+ 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+ 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+ 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+ 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+ 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+ 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+ 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn);
+}
+
+/*-
+ * "8192-bit MODP Group" from RFC3526, Section 7.
+ *
+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_8192[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+ 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+ 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+ 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+ 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+ 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+ 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+ 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+ 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+ 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+ 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+ 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+ 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+ 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+ 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+ 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+ 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+ 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+ 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+ 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+ 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+ 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+ 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+ 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+ 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+ 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+ 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+ 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+ 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+ 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+ 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+ 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+ 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59,
+ 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
+ 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C,
+ 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA,
+ 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
+ 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED,
+ 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66,
+ 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
+ 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78,
+ 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D,
+ 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
+ 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07,
+ 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7,
+ 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
+ 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD,
+ 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8,
+ 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
+ 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6,
+ 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D,
+ 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
+ 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1,
+ 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D,
+ 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
+ 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73,
+ 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68,
+ 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
+ 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7,
+ 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B,
+ 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
+ 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA,
+ 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF,
+ 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
+ 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_ctx.c b/Cryptlib/OpenSSL/crypto/bn/bn_ctx.c
new file mode 100644
index 00000000..526c6a04
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_ctx.c
@@ -0,0 +1,448 @@
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2004 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).
+ *
+ */
+
+#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/*-
+ * TODO list
+ *
+ * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
+ * check they can be safely removed.
+ * - Check +1 and other ugliness in BN_from_montgomery()
+ *
+ * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
+ * appropriate 'block' size that will be honoured by bn_expand_internal() to
+ * prevent piddly little reallocations. OTOH, profiling bignum expansions in
+ * BN_CTX doesn't show this to be a big issue.
+ */
+
+/* How many bignums are in each "pool item"; */
+#define BN_CTX_POOL_SIZE 16
+/* The stack frame info is resizing, set a first-time expansion size; */
+#define BN_CTX_START_FRAMES 32
+
+/***********/
+/* BN_POOL */
+/***********/
+
+/* A bundle of bignums that can be linked with other bundles */
+typedef struct bignum_pool_item {
+ /* The bignum values */
+ BIGNUM vals[BN_CTX_POOL_SIZE];
+ /* Linked-list admin */
+ struct bignum_pool_item *prev, *next;
+} BN_POOL_ITEM;
+/* A linked-list of bignums grouped in bundles */
+typedef struct bignum_pool {
+ /* Linked-list admin */
+ BN_POOL_ITEM *head, *current, *tail;
+ /* Stack depth and allocation size */
+ unsigned used, size;
+} BN_POOL;
+static void BN_POOL_init(BN_POOL *);
+static void BN_POOL_finish(BN_POOL *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_POOL_reset(BN_POOL *);
+#endif
+static BIGNUM *BN_POOL_get(BN_POOL *);
+static void BN_POOL_release(BN_POOL *, unsigned int);
+
+/************/
+/* BN_STACK */
+/************/
+
+/* A wrapper to manage the "stack frames" */
+typedef struct bignum_ctx_stack {
+ /* Array of indexes into the bignum stack */
+ unsigned int *indexes;
+ /* Number of stack frames, and the size of the allocated array */
+ unsigned int depth, size;
+} BN_STACK;
+static void BN_STACK_init(BN_STACK *);
+static void BN_STACK_finish(BN_STACK *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_STACK_reset(BN_STACK *);
+#endif
+static int BN_STACK_push(BN_STACK *, unsigned int);
+static unsigned int BN_STACK_pop(BN_STACK *);
+
+/**********/
+/* BN_CTX */
+/**********/
+
+/* The opaque BN_CTX type */
+struct bignum_ctx {
+ /* The bignum bundles */
+ BN_POOL pool;
+ /* The "stack frames", if you will */
+ BN_STACK stack;
+ /* The number of bignums currently assigned */
+ unsigned int used;
+ /* Depth of stack overflow */
+ int err_stack;
+ /* Block "gets" until an "end" (compatibility behaviour) */
+ int too_many;
+};
+
+/* Enable this to find BN_CTX bugs */
+#ifdef BN_CTX_DEBUG
+static const char *ctxdbg_cur = NULL;
+static void ctxdbg(BN_CTX *ctx)
+{
+ unsigned int bnidx = 0, fpidx = 0;
+ BN_POOL_ITEM *item = ctx->pool.head;
+ BN_STACK *stack = &ctx->stack;
+ fprintf(stderr, "(%16p): ", ctx);
+ while (bnidx < ctx->used) {
+ fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
+ if (!(bnidx % BN_CTX_POOL_SIZE))
+ item = item->next;
+ }
+ fprintf(stderr, "\n");
+ bnidx = 0;
+ fprintf(stderr, " : ");
+ while (fpidx < stack->depth) {
+ while (bnidx++ < stack->indexes[fpidx])
+ fprintf(stderr, " ");
+ fprintf(stderr, "^^^ ");
+ bnidx++;
+ fpidx++;
+ }
+ fprintf(stderr, "\n");
+}
+
+# define CTXDBG_ENTRY(str, ctx) do { \
+ ctxdbg_cur = (str); \
+ fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
+ ctxdbg(ctx); \
+ } while(0)
+# define CTXDBG_EXIT(ctx) do { \
+ fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
+ ctxdbg(ctx); \
+ } while(0)
+# define CTXDBG_RET(ctx,ret)
+#else
+# define CTXDBG_ENTRY(str, ctx)
+# define CTXDBG_EXIT(ctx)
+# define CTXDBG_RET(ctx,ret)
+#endif
+
+/*
+ * This function is an evil legacy and should not be used. This
+ * implementation is WYSIWYG, though I've done my best.
+ */
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_CTX_init(BN_CTX *ctx)
+{
+ /*
+ * Assume the caller obtained the context via BN_CTX_new() and so is
+ * trying to reset it for use. Nothing else makes sense, least of all
+ * binary compatibility from a time when they could declare a static
+ * variable.
+ */
+ BN_POOL_reset(&ctx->pool);
+ BN_STACK_reset(&ctx->stack);
+ ctx->used = 0;
+ ctx->err_stack = 0;
+ ctx->too_many = 0;
+}
+#endif
+
+BN_CTX *BN_CTX_new(void)
+{
+ BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
+ if (!ret) {
+ BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ /* Initialise the structure */
+ BN_POOL_init(&ret->pool);
+ BN_STACK_init(&ret->stack);
+ ret->used = 0;
+ ret->err_stack = 0;
+ ret->too_many = 0;
+ return ret;
+}
+
+void BN_CTX_free(BN_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+#ifdef BN_CTX_DEBUG
+ {
+ BN_POOL_ITEM *pool = ctx->pool.head;
+ fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
+ ctx->stack.size, ctx->pool.size);
+ fprintf(stderr, "dmaxs: ");
+ while (pool) {
+ unsigned loop = 0;
+ while (loop < BN_CTX_POOL_SIZE)
+ fprintf(stderr, "%02x ", pool->vals[loop++].dmax);
+ pool = pool->next;
+ }
+ fprintf(stderr, "\n");
+ }
+#endif
+ BN_STACK_finish(&ctx->stack);
+ BN_POOL_finish(&ctx->pool);
+ OPENSSL_free(ctx);
+}
+
+void BN_CTX_start(BN_CTX *ctx)
+{
+ CTXDBG_ENTRY("BN_CTX_start", ctx);
+ /* If we're already overflowing ... */
+ if (ctx->err_stack || ctx->too_many)
+ ctx->err_stack++;
+ /* (Try to) get a new frame pointer */
+ else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
+ BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ ctx->err_stack++;
+ }
+ CTXDBG_EXIT(ctx);
+}
+
+void BN_CTX_end(BN_CTX *ctx)
+{
+ CTXDBG_ENTRY("BN_CTX_end", ctx);
+ if (ctx->err_stack)
+ ctx->err_stack--;
+ else {
+ unsigned int fp = BN_STACK_pop(&ctx->stack);
+ /* Does this stack frame have anything to release? */
+ if (fp < ctx->used)
+ BN_POOL_release(&ctx->pool, ctx->used - fp);
+ ctx->used = fp;
+ /* Unjam "too_many" in case "get" had failed */
+ ctx->too_many = 0;
+ }
+ CTXDBG_EXIT(ctx);
+}
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+{
+ BIGNUM *ret;
+ CTXDBG_ENTRY("BN_CTX_get", ctx);
+ if (ctx->err_stack || ctx->too_many)
+ return NULL;
+ if ((ret = BN_POOL_get(&ctx->pool)) == NULL) {
+ /*
+ * Setting too_many prevents repeated "get" attempts from cluttering
+ * the error stack.
+ */
+ ctx->too_many = 1;
+ BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ return NULL;
+ }
+ /* OK, make sure the returned bignum is "zero" */
+ BN_zero(ret);
+ ctx->used++;
+ CTXDBG_RET(ctx, ret);
+ return ret;
+}
+
+/************/
+/* BN_STACK */
+/************/
+
+static void BN_STACK_init(BN_STACK *st)
+{
+ st->indexes = NULL;
+ st->depth = st->size = 0;
+}
+
+static void BN_STACK_finish(BN_STACK *st)
+{
+ if (st->size)
+ OPENSSL_free(st->indexes);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_STACK_reset(BN_STACK *st)
+{
+ st->depth = 0;
+}
+#endif
+
+static int BN_STACK_push(BN_STACK *st, unsigned int idx)
+{
+ if (st->depth == st->size)
+ /* Need to expand */
+ {
+ unsigned int newsize = (st->size ?
+ (st->size * 3 / 2) : BN_CTX_START_FRAMES);
+ unsigned int *newitems = OPENSSL_malloc(newsize *
+ sizeof(unsigned int));
+ if (!newitems)
+ return 0;
+ if (st->depth)
+ memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int));
+ if (st->size)
+ OPENSSL_free(st->indexes);
+ st->indexes = newitems;
+ st->size = newsize;
+ }
+ st->indexes[(st->depth)++] = idx;
+ return 1;
+}
+
+static unsigned int BN_STACK_pop(BN_STACK *st)
+{
+ return st->indexes[--(st->depth)];
+}
+
+/***********/
+/* BN_POOL */
+/***********/
+
+static void BN_POOL_init(BN_POOL *p)
+{
+ p->head = p->current = p->tail = NULL;
+ p->used = p->size = 0;
+}
+
+static void BN_POOL_finish(BN_POOL *p)
+{
+ while (p->head) {
+ unsigned int loop = 0;
+ BIGNUM *bn = p->head->vals;
+ while (loop++ < BN_CTX_POOL_SIZE) {
+ if (bn->d)
+ BN_clear_free(bn);
+ bn++;
+ }
+ p->current = p->head->next;
+ OPENSSL_free(p->head);
+ p->head = p->current;
+ }
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_POOL_reset(BN_POOL *p)
+{
+ BN_POOL_ITEM *item = p->head;
+ while (item) {
+ unsigned int loop = 0;
+ BIGNUM *bn = item->vals;
+ while (loop++ < BN_CTX_POOL_SIZE) {
+ if (bn->d)
+ BN_clear(bn);
+ bn++;
+ }
+ item = item->next;
+ }
+ p->current = p->head;
+ p->used = 0;
+}
+#endif
+
+static BIGNUM *BN_POOL_get(BN_POOL *p)
+{
+ if (p->used == p->size) {
+ BIGNUM *bn;
+ unsigned int loop = 0;
+ BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
+ if (!item)
+ return NULL;
+ /* Initialise the structure */
+ bn = item->vals;
+ while (loop++ < BN_CTX_POOL_SIZE)
+ BN_init(bn++);
+ item->prev = p->tail;
+ item->next = NULL;
+ /* Link it in */
+ if (!p->head)
+ p->head = p->current = p->tail = item;
+ else {
+ p->tail->next = item;
+ p->tail = item;
+ p->current = item;
+ }
+ p->size += BN_CTX_POOL_SIZE;
+ p->used++;
+ /* Return the first bignum from the new pool */
+ return item->vals;
+ }
+ if (!p->used)
+ p->current = p->head;
+ else if ((p->used % BN_CTX_POOL_SIZE) == 0)
+ p->current = p->current->next;
+ return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
+}
+
+static void BN_POOL_release(BN_POOL *p, unsigned int num)
+{
+ unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
+ p->used -= num;
+ while (num--) {
+ bn_check_top(p->current->vals + offset);
+ if (!offset) {
+ offset = BN_CTX_POOL_SIZE - 1;
+ p->current = p->current->prev;
+ } else
+ offset--;
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_depr.c b/Cryptlib/OpenSSL/crypto/bn/bn_depr.c
new file mode 100644
index 00000000..34895f59
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_depr.c
@@ -0,0 +1,115 @@
+/* crypto/bn/bn_depr.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/*
+ * Support for deprecated functions goes here - static linkage will only
+ * slurp this code if applications are using them directly.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static void *dummy = &dummy;
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+ const BIGNUM *add, const BIGNUM *rem,
+ void (*callback) (int, int, void *), void *cb_arg)
+{
+ BN_GENCB cb;
+ BIGNUM *rnd = NULL;
+ int found = 0;
+
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+
+ if (ret == NULL) {
+ if ((rnd = BN_new()) == NULL)
+ goto err;
+ } else
+ rnd = ret;
+ if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
+ goto err;
+
+ /* we have a prime :-) */
+ found = 1;
+ err:
+ if (!found && (ret == NULL) && (rnd != NULL))
+ BN_free(rnd);
+ return (found ? rnd : NULL);
+}
+
+int BN_is_prime(const BIGNUM *a, int checks,
+ void (*callback) (int, int, void *), BN_CTX *ctx_passed,
+ void *cb_arg)
+{
+ BN_GENCB cb;
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+ return BN_is_prime_ex(a, checks, ctx_passed, &cb);
+}
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+ void (*callback) (int, int, void *),
+ BN_CTX *ctx_passed, void *cb_arg,
+ int do_trial_division)
+{
+ BN_GENCB cb;
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+ return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
+ do_trial_division, &cb);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_div.c b/Cryptlib/OpenSSL/crypto/bn/bn_div.c
new file mode 100644
index 00000000..72e6ce3f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_div.c
@@ -0,0 +1,477 @@
+/* crypto/bn/bn_div.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 <stdio.h>
+#include <openssl/bn.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx)
+{
+ int i, nm, nd;
+ int ret = 0;
+ BIGNUM *D;
+
+ bn_check_top(m);
+ bn_check_top(d);
+ if (BN_is_zero(d)) {
+ BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+ return (0);
+ }
+
+ if (BN_ucmp(m, d) < 0) {
+ if (rem != NULL) {
+ if (BN_copy(rem, m) == NULL)
+ return (0);
+ }
+ if (dv != NULL)
+ BN_zero(dv);
+ return (1);
+ }
+
+ BN_CTX_start(ctx);
+ D = BN_CTX_get(ctx);
+ if (dv == NULL)
+ dv = BN_CTX_get(ctx);
+ if (rem == NULL)
+ rem = BN_CTX_get(ctx);
+ if (D == NULL || dv == NULL || rem == NULL)
+ goto end;
+
+ nd = BN_num_bits(d);
+ nm = BN_num_bits(m);
+ if (BN_copy(D, d) == NULL)
+ goto end;
+ if (BN_copy(rem, m) == NULL)
+ goto end;
+
+ /*
+ * The next 2 are needed so we can do a dv->d[0]|=1 later since
+ * BN_lshift1 will only work once there is a value :-)
+ */
+ BN_zero(dv);
+ if (bn_wexpand(dv, 1) == NULL)
+ goto end;
+ dv->top = 1;
+
+ if (!BN_lshift(D, D, nm - nd))
+ goto end;
+ for (i = nm - nd; i >= 0; i--) {
+ if (!BN_lshift1(dv, dv))
+ goto end;
+ if (BN_ucmp(rem, D) >= 0) {
+ dv->d[0] |= 1;
+ if (!BN_usub(rem, rem, D))
+ goto end;
+ }
+/* CAN IMPROVE (and have now :=) */
+ if (!BN_rshift1(D, D))
+ goto end;
+ }
+ rem->neg = BN_is_zero(rem) ? 0 : m->neg;
+ dv->neg = m->neg ^ d->neg;
+ ret = 1;
+ end:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+#else
+
+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
+ && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386) || defined (__i386__)
+ /*-
+ * There were two reasons for implementing this template:
+ * - GNU C generates a call to a function (__udivdi3 to be exact)
+ * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+ * understand why...);
+ * - divl doesn't only calculate quotient, but also leaves
+ * remainder in %edx which we can definitely use here:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# undef bn_div_words
+# define bn_div_words(n0,n1,d0) \
+ ({ asm volatile ( \
+ "divl %4" \
+ : "=a"(q), "=d"(rem) \
+ : "a"(n1), "d"(n0), "g"(d0) \
+ : "cc"); \
+ q; \
+ })
+# define REMAINDER_IS_ALREADY_CALCULATED
+# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
+ /*
+ * Same story here, but it's 128-bit by 64-bit division. Wow!
+ * <appro@fy.chalmers.se>
+ */
+# undef bn_div_words
+# define bn_div_words(n0,n1,d0) \
+ ({ asm volatile ( \
+ "divq %4" \
+ : "=a"(q), "=d"(rem) \
+ : "a"(n1), "d"(n0), "g"(d0) \
+ : "cc"); \
+ q; \
+ })
+# define REMAINDER_IS_ALREADY_CALCULATED
+# endif /* __<cpu> */
+# endif /* __GNUC__ */
+# endif /* OPENSSL_NO_ASM */
+
+/*-
+ * BN_div computes dv := num / divisor, rounding towards
+ * zero, and sets up rm such that dv*divisor + rm = num holds.
+ * Thus:
+ * dv->neg == num->neg ^ divisor->neg (unless the result is zero)
+ * rm->neg == num->neg (unless the remainder is zero)
+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
+ */
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+ BN_CTX *ctx)
+{
+ int norm_shift, i, loop;
+ BIGNUM *tmp, wnum, *snum, *sdiv, *res;
+ BN_ULONG *resp, *wnump;
+ BN_ULONG d0, d1;
+ int num_n, div_n;
+ int no_branch = 0;
+
+ /*
+ * Invalid zero-padding would have particularly bad consequences so don't
+ * just rely on bn_check_top() here (bn_check_top() works only for
+ * BN_DEBUG builds)
+ */
+ if ((num->top > 0 && num->d[num->top - 1] == 0) ||
+ (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
+ BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ bn_check_top(num);
+ bn_check_top(divisor);
+
+ if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0)
+ || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) {
+ no_branch = 1;
+ }
+
+ bn_check_top(dv);
+ bn_check_top(rm);
+ /*- bn_check_top(num); *//*
+ * 'num' has been checked already
+ */
+ /*- bn_check_top(divisor); *//*
+ * 'divisor' has been checked already
+ */
+
+ if (BN_is_zero(divisor)) {
+ BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+ return (0);
+ }
+
+ if (!no_branch && BN_ucmp(num, divisor) < 0) {
+ if (rm != NULL) {
+ if (BN_copy(rm, num) == NULL)
+ return (0);
+ }
+ if (dv != NULL)
+ BN_zero(dv);
+ return (1);
+ }
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ snum = BN_CTX_get(ctx);
+ sdiv = BN_CTX_get(ctx);
+ if (dv == NULL)
+ res = BN_CTX_get(ctx);
+ else
+ res = dv;
+ if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
+ goto err;
+
+ /* First we normalise the numbers */
+ norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
+ if (!(BN_lshift(sdiv, divisor, norm_shift)))
+ goto err;
+ sdiv->neg = 0;
+ norm_shift += BN_BITS2;
+ if (!(BN_lshift(snum, num, norm_shift)))
+ goto err;
+ snum->neg = 0;
+
+ if (no_branch) {
+ /*
+ * Since we don't know whether snum is larger than sdiv, we pad snum
+ * with enough zeroes without changing its value.
+ */
+ if (snum->top <= sdiv->top + 1) {
+ if (bn_wexpand(snum, sdiv->top + 2) == NULL)
+ goto err;
+ for (i = snum->top; i < sdiv->top + 2; i++)
+ snum->d[i] = 0;
+ snum->top = sdiv->top + 2;
+ } else {
+ if (bn_wexpand(snum, snum->top + 1) == NULL)
+ goto err;
+ snum->d[snum->top] = 0;
+ snum->top++;
+ }
+ }
+
+ div_n = sdiv->top;
+ num_n = snum->top;
+ loop = num_n - div_n;
+ /*
+ * Lets setup a 'window' into snum This is the part that corresponds to
+ * the current 'area' being divided
+ */
+ wnum.neg = 0;
+ wnum.d = &(snum->d[loop]);
+ wnum.top = div_n;
+ /*
+ * only needed when BN_ucmp messes up the values between top and max
+ */
+ wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
+
+ /* Get the top 2 words of sdiv */
+ /* div_n=sdiv->top; */
+ d0 = sdiv->d[div_n - 1];
+ d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
+
+ /* pointer to the 'top' of snum */
+ wnump = &(snum->d[num_n - 1]);
+
+ /* Setup to 'res' */
+ res->neg = (num->neg ^ divisor->neg);
+ if (!bn_wexpand(res, (loop + 1)))
+ goto err;
+ res->top = loop - no_branch;
+ resp = &(res->d[loop - 1]);
+
+ /* space for temp */
+ if (!bn_wexpand(tmp, (div_n + 1)))
+ goto err;
+
+ if (!no_branch) {
+ if (BN_ucmp(&wnum, sdiv) >= 0) {
+ /*
+ * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute)
+ * the const bignum arguments => clean the values between top and
+ * max again
+ */
+ bn_clear_top2max(&wnum);
+ bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
+ *resp = 1;
+ } else
+ res->top--;
+ }
+
+ /*
+ * if res->top == 0 then clear the neg value otherwise decrease the resp
+ * pointer
+ */
+ if (res->top == 0)
+ res->neg = 0;
+ else
+ resp--;
+
+ for (i = 0; i < loop - 1; i++, wnump--, resp--) {
+ BN_ULONG q, l0;
+ /*
+ * the first part of the loop uses the top two words of snum and sdiv
+ * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv
+ */
+# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+ BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG);
+ q = bn_div_3_words(wnump, d1, d0);
+# else
+ BN_ULONG n0, n1, rem = 0;
+
+ n0 = wnump[0];
+ n1 = wnump[-1];
+ if (n0 == d0)
+ q = BN_MASK2;
+ else { /* n0 < d0 */
+
+# ifdef BN_LLONG
+ BN_ULLONG t2;
+
+# if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+ q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0);
+# else
+ q = bn_div_words(n0, n1, d0);
+# ifdef BN_DEBUG_LEVITTE
+ fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n", n0, n1, d0, q);
+# endif
+# endif
+
+# ifndef REMAINDER_IS_ALREADY_CALCULATED
+ /*
+ * rem doesn't have to be BN_ULLONG. The least we
+ * know it's less that d0, isn't it?
+ */
+ rem = (n1 - q * d0) & BN_MASK2;
+# endif
+ t2 = (BN_ULLONG) d1 *q;
+
+ for (;;) {
+ if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2]))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0)
+ break; /* don't let rem overflow */
+ t2 -= d1;
+ }
+# else /* !BN_LLONG */
+ BN_ULONG t2l, t2h;
+
+ q = bn_div_words(n0, n1, d0);
+# ifdef BN_DEBUG_LEVITTE
+ fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n", n0, n1, d0, q);
+# endif
+# ifndef REMAINDER_IS_ALREADY_CALCULATED
+ rem = (n1 - q * d0) & BN_MASK2;
+# endif
+
+# if defined(BN_UMULT_LOHI)
+ BN_UMULT_LOHI(t2l, t2h, d1, q);
+# elif defined(BN_UMULT_HIGH)
+ 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 (;;) {
+ if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0)
+ break; /* don't let rem overflow */
+ if (t2l < d1)
+ t2h--;
+ t2l -= d1;
+ }
+# endif /* !BN_LLONG */
+ }
+# endif /* !BN_DIV3W */
+
+ l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
+ tmp->d[div_n] = l0;
+ wnum.d--;
+ /*
+ * ingore top values of the bignums just sub the two BN_ULONG arrays
+ * with bn_sub_words
+ */
+ if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
+ /*
+ * Note: As we have considered only the leading two BN_ULONGs in
+ * the calculation of q, sdiv * q might be greater than wnum (but
+ * then (q-1) * sdiv is less or equal than wnum)
+ */
+ q--;
+ if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+ /*
+ * we can't have an overflow here (assuming that q != 0, but
+ * if q == 0 then tmp is zero anyway)
+ */
+ (*wnump)++;
+ }
+ /* store part of the result */
+ *resp = q;
+ }
+ bn_correct_top(snum);
+ if (rm != NULL) {
+ /*
+ * Keep a copy of the neg flag in num because if rm==num BN_rshift()
+ * will overwrite it.
+ */
+ int neg = num->neg;
+ BN_rshift(rm, snum, norm_shift);
+ if (!BN_is_zero(rm))
+ rm->neg = neg;
+ bn_check_top(rm);
+ }
+ if (no_branch)
+ bn_correct_top(res);
+ BN_CTX_end(ctx);
+ return (1);
+ err:
+ bn_check_top(rm);
+ BN_CTX_end(ctx);
+ return (0);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_err.c b/Cryptlib/OpenSSL/crypto/bn/bn_err.c
new file mode 100644
index 00000000..e7a70382
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_err.c
@@ -0,0 +1,154 @@
+/* crypto/bn/bn_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2015 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
+
+static ERR_STRING_DATA BN_str_functs[] = {
+ {ERR_FUNC(BN_F_BNRAND), "BNRAND"},
+ {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"},
+ {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"},
+ {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"},
+ {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"},
+ {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"},
+ {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"},
+ {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"},
+ {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"},
+ {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"},
+ {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"},
+ {ERR_FUNC(BN_F_BN_DIV), "BN_div"},
+ {ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"},
+ {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"},
+ {ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
+ {ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"},
+ {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
+ {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"},
+ {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"},
+ {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"},
+ {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"},
+ {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"},
+ {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"},
+ {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"},
+ {ERR_FUNC(BN_F_BN_NEW), "BN_new"},
+ {ERR_FUNC(BN_F_BN_RAND), "BN_rand"},
+ {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"},
+ {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"},
+ {ERR_FUNC(BN_F_BN_USUB), "BN_usub"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA BN_str_reasons[] = {
+ {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"},
+ {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"},
+ {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"},
+ {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"},
+ {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
+ {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"},
+ {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"},
+ {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA),
+ "expand on static bignum data"},
+ {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"},
+ {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"},
+ {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"},
+ {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"},
+ {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"},
+ {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"},
+ {ERR_REASON(BN_R_NO_INVERSE), "no inverse"},
+ {ERR_REASON(BN_R_NO_SOLUTION), "no solution"},
+ {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"},
+ {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"},
+ {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),
+ "too many temporary variables"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_BN_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(BN_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, BN_str_functs);
+ ERR_load_strings(0, BN_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_exp.c b/Cryptlib/OpenSSL/crypto/bn/bn_exp.c
new file mode 100644
index 00000000..1670f01d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_exp.c
@@ -0,0 +1,1457 @@
+/* crypto/bn/bn_exp.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-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).
+ *
+ */
+
+#include "cryptlib.h"
+#include "constant_time_locl.h"
+#include "bn_lcl.h"
+
+#include <stdlib.h>
+#ifdef _WIN32
+# include <malloc.h>
+# ifndef alloca
+# define alloca _alloca
+# endif
+#elif defined(__GNUC__)
+# ifndef alloca
+# define alloca(s) __builtin_alloca((s))
+# endif
+#elif defined(__sun)
+# include <alloca.h>
+#endif
+
+#include "rsaz_exp.h"
+
+#undef SPARC_T4_MONT
+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
+# include "sparc_arch.h"
+extern unsigned int OPENSSL_sparcv9cap_P[];
+# define SPARC_T4_MONT
+#endif
+
+/* maximum precomputation table size for *variable* sliding windows */
+#define TABLE_SIZE 32
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+ int i, bits, ret = 0;
+ BIGNUM *v, *rr;
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ if ((r == a) || (r == p))
+ rr = BN_CTX_get(ctx);
+ else
+ rr = r;
+ v = BN_CTX_get(ctx);
+ if (rr == NULL || v == NULL)
+ goto err;
+
+ if (BN_copy(v, a) == NULL)
+ goto err;
+ bits = BN_num_bits(p);
+
+ if (BN_is_odd(p)) {
+ if (BN_copy(rr, a) == NULL)
+ goto err;
+ } else {
+ if (!BN_one(rr))
+ goto err;
+ }
+
+ for (i = 1; i < bits; i++) {
+ if (!BN_sqr(v, v, ctx))
+ goto err;
+ if (BN_is_bit_set(p, i)) {
+ if (!BN_mul(rr, rr, v, ctx))
+ goto err;
+ }
+ }
+ if (r != rr)
+ BN_copy(r, rr);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ int ret;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ /*-
+ * For even modulus m = 2^k*m_odd, it might make sense to compute
+ * a^p mod m_odd and a^p mod 2^k separately (with Montgomery
+ * exponentiation for the odd part), using appropriate exponent
+ * reductions, and combine the results using the CRT.
+ *
+ * For now, we use Montgomery only if the modulus is odd; otherwise,
+ * exponentiation using the reciprocal-based quick remaindering
+ * algorithm is used.
+ *
+ * (Timing obtained with expspeed.c [computations a^p mod m
+ * where a, p, m are of the same length: 256, 512, 1024, 2048,
+ * 4096, 8192 bits], compared to the running time of the
+ * standard algorithm:
+ *
+ * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
+ * 55 .. 77 % [UltraSparc processor, but
+ * debug-solaris-sparcv8-gcc conf.]
+ *
+ * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
+ * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
+ *
+ * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
+ * at 2048 and more bits, but at 512 and 1024 bits, it was
+ * slower even than the standard algorithm!
+ *
+ * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
+ * should be obtained when the new Montgomery reduction code
+ * has been integrated into OpenSSL.)
+ */
+
+#define MONT_MUL_MOD
+#define MONT_EXP_WORD
+#define RECP_MUL_MOD
+
+#ifdef MONT_MUL_MOD
+ /*
+ * I have finally been able to take out this pre-condition of the top bit
+ * being set. It was caused by an error in BN_div with negatives. There
+ * was also another problem when for a^b%m a >= m. eay 07-May-97
+ */
+ /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+ if (BN_is_odd(m)) {
+# ifdef MONT_EXP_WORD
+ if (a->top == 1 && !a->neg
+ && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
+ BN_ULONG A = a->d[0];
+ ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
+ } else
+# endif
+ ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL);
+ } else
+#endif
+#ifdef RECP_MUL_MOD
+ {
+ ret = BN_mod_exp_recp(r, a, p, m, ctx);
+ }
+#else
+ {
+ ret = BN_mod_exp_simple(r, a, p, m, ctx);
+ }
+#endif
+
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+{
+ int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+ int start = 1;
+ BIGNUM *aa;
+ /* Table of variables obtained from 'ctx' */
+ BIGNUM *val[TABLE_SIZE];
+ BN_RECP_CTX recp;
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ ret = 1;
+ BN_zero(r);
+ } else {
+ ret = BN_one(r);
+ }
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ aa = BN_CTX_get(ctx);
+ val[0] = BN_CTX_get(ctx);
+ if (!aa || !val[0])
+ goto err;
+
+ BN_RECP_CTX_init(&recp);
+ if (m->neg) {
+ /* ignore sign of 'm' */
+ if (!BN_copy(aa, m))
+ goto err;
+ aa->neg = 0;
+ if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
+ goto err;
+ } else {
+ if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
+ goto err;
+ }
+
+ if (!BN_nnmod(val[0], a, m, ctx))
+ goto err; /* 1 */
+ if (BN_is_zero(val[0])) {
+ BN_zero(r);
+ ret = 1;
+ goto err;
+ }
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1) {
+ if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx))
+ goto err; /* 2 */
+ j = 1 << (window - 1);
+ for (i = 1; i < j; i++) {
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx))
+ goto err;
+ }
+ }
+
+ start = 1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue = 0; /* The 'value' of the window */
+ wstart = bits - 1; /* The top bit of the window */
+ wend = 0; /* The bottom bit of the window */
+
+ if (!BN_one(r))
+ goto err;
+
+ for (;;) {
+ if (BN_is_bit_set(p, wstart) == 0) {
+ if (!start)
+ if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
+ goto err;
+ if (wstart == 0)
+ break;
+ wstart--;
+ continue;
+ }
+ /*
+ * We now have wstart on a 'set' bit, we now need to work out how bit
+ * a window to do. To do this we need to scan forward until the last
+ * set bit before the end of the window
+ */
+ j = wstart;
+ wvalue = 1;
+ wend = 0;
+ for (i = 1; i < window; i++) {
+ if (wstart - i < 0)
+ break;
+ if (BN_is_bit_set(p, wstart - i)) {
+ wvalue <<= (i - wend);
+ wvalue |= 1;
+ wend = i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j = wend + 1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i = 0; i < j; i++) {
+ if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart -= wend + 1;
+ wvalue = 0;
+ start = 0;
+ if (wstart < 0)
+ break;
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ BN_RECP_CTX_free(&recp);
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+ int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+ int start = 1;
+ BIGNUM *d, *r;
+ const BIGNUM *aa;
+ /* Table of variables obtained from 'ctx' */
+ BIGNUM *val[TABLE_SIZE];
+ BN_MONT_CTX *mont = NULL;
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+ }
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!BN_is_odd(m)) {
+ BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ ret = 1;
+ BN_zero(rr);
+ } else {
+ ret = BN_one(rr);
+ }
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ val[0] = BN_CTX_get(ctx);
+ if (!d || !r || !val[0])
+ goto err;
+
+ /*
+ * If this is not done, things will break in the montgomery part
+ */
+
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ if (a->neg || BN_ucmp(a, m) >= 0) {
+ if (!BN_nnmod(val[0], a, m, ctx))
+ goto err;
+ aa = val[0];
+ } else
+ aa = a;
+ if (BN_is_zero(aa)) {
+ BN_zero(rr);
+ ret = 1;
+ goto err;
+ }
+ if (!BN_to_montgomery(val[0], aa, mont, ctx))
+ goto err; /* 1 */
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1) {
+ if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
+ goto err; /* 2 */
+ j = 1 << (window - 1);
+ for (i = 1; i < j; i++) {
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
+ goto err;
+ }
+ }
+
+ start = 1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue = 0; /* The 'value' of the window */
+ wstart = bits - 1; /* The top bit of the window */
+ wend = 0; /* The bottom bit of the window */
+
+#if 1 /* by Shay Gueron's suggestion */
+ j = m->top; /* borrow j */
+ if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+ if (bn_wexpand(r, j) == NULL)
+ goto err;
+ /* 2^(top*BN_BITS2) - m */
+ r->d[0] = (0 - m->d[0]) & BN_MASK2;
+ for (i = 1; i < j; i++)
+ r->d[i] = (~m->d[i]) & BN_MASK2;
+ r->top = j;
+ /*
+ * Upper words will be zero if the corresponding words of 'm' were
+ * 0xfff[...], so decrement r->top accordingly.
+ */
+ bn_correct_top(r);
+ } else
+#endif
+ if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+ goto err;
+ for (;;) {
+ if (BN_is_bit_set(p, wstart) == 0) {
+ if (!start) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+ if (wstart == 0)
+ break;
+ wstart--;
+ continue;
+ }
+ /*
+ * We now have wstart on a 'set' bit, we now need to work out how bit
+ * a window to do. To do this we need to scan forward until the last
+ * set bit before the end of the window
+ */
+ j = wstart;
+ wvalue = 1;
+ wend = 0;
+ for (i = 1; i < window; i++) {
+ if (wstart - i < 0)
+ break;
+ if (BN_is_bit_set(p, wstart - i)) {
+ wvalue <<= (i - wend);
+ wvalue |= 1;
+ wend = i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j = wend + 1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i = 0; i < j; i++) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart -= wend + 1;
+ wvalue = 0;
+ start = 0;
+ if (wstart < 0)
+ break;
+ }
+#if defined(SPARC_T4_MONT)
+ if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
+ j = mont->N.top; /* borrow j */
+ val[0]->d[0] = 1; /* borrow val[0] */
+ for (i = 1; i < j; i++)
+ val[0]->d[i] = 0;
+ val[0]->top = j;
+ if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))
+ goto err;
+ } else
+#endif
+ if (!BN_from_montgomery(rr, r, mont, ctx))
+ goto err;
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ bn_check_top(rr);
+ return (ret);
+}
+
+#if defined(SPARC_T4_MONT)
+static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos)
+{
+ BN_ULONG ret = 0;
+ int wordpos;
+
+ wordpos = bitpos / BN_BITS2;
+ bitpos %= BN_BITS2;
+ if (wordpos >= 0 && wordpos < a->top) {
+ ret = a->d[wordpos] & BN_MASK2;
+ if (bitpos) {
+ ret >>= bitpos;
+ if (++wordpos < a->top)
+ ret |= a->d[wordpos] << (BN_BITS2 - bitpos);
+ }
+ }
+
+ return ret & BN_MASK2;
+}
+#endif
+
+/*
+ * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
+ * layout so that accessing any of these table values shows the same access
+ * pattern as far as cache lines are concerned. The following functions are
+ * used to transfer a BIGNUM from/to that table.
+ */
+
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top,
+ unsigned char *buf, int idx,
+ int window)
+{
+ int i, j;
+ int width = 1 << window;
+ BN_ULONG *table = (BN_ULONG *)buf;
+
+ if (top > b->top)
+ top = b->top; /* this works because 'buf' is explicitly
+ * zeroed */
+ for (i = 0, j = idx; i < top; i++, j += width) {
+ table[j] = b->d[i];
+ }
+
+ return 1;
+}
+
+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
+ unsigned char *buf, int idx,
+ int window)
+{
+ int i, j;
+ int width = 1 << window;
+ volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
+
+ if (bn_wexpand(b, top) == NULL)
+ return 0;
+
+ if (window <= 3) {
+ for (i = 0; i < top; i++, table += width) {
+ BN_ULONG acc = 0;
+
+ for (j = 0; j < width; j++) {
+ acc |= table[j] &
+ ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
+ }
+
+ b->d[i] = acc;
+ }
+ } else {
+ int xstride = 1 << (window - 2);
+ BN_ULONG y0, y1, y2, y3;
+
+ i = idx >> (window - 2); /* equivalent of idx / xstride */
+ idx &= xstride - 1; /* equivalent of idx % xstride */
+
+ y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
+ y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
+ y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
+ y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
+
+ for (i = 0; i < top; i++, table += width) {
+ BN_ULONG acc = 0;
+
+ for (j = 0; j < xstride; j++) {
+ acc |= ( (table[j + 0 * xstride] & y0) |
+ (table[j + 1 * xstride] & y1) |
+ (table[j + 2 * xstride] & y2) |
+ (table[j + 3 * xstride] & y3) )
+ & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
+ }
+
+ b->d[i] = acc;
+ }
+ }
+
+ b->top = top;
+ bn_correct_top(b);
+ return 1;
+}
+
+/*
+ * Given a pointer value, compute the next address that is a cache line
+ * multiple.
+ */
+#define MOD_EXP_CTIME_ALIGN(x_) \
+ ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+
+/*
+ * This variant of BN_mod_exp_mont() uses fixed windows and the special
+ * precomputation memory layout to limit data-dependency to a minimum to
+ * protect secret exponents (cf. the hyper-threading timing attacks pointed
+ * out by Colin Percival,
+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
+ */
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont)
+{
+ int i, bits, ret = 0, window, wvalue;
+ int top;
+ BN_MONT_CTX *mont = NULL;
+
+ int numPowers;
+ unsigned char *powerbufFree = NULL;
+ int powerbufLen = 0;
+ unsigned char *powerbuf = NULL;
+ BIGNUM tmp, am;
+#if defined(SPARC_T4_MONT)
+ unsigned int t4 = 0;
+#endif
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!BN_is_odd(m)) {
+ BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+
+ top = m->top;
+
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ ret = 1;
+ BN_zero(rr);
+ } else {
+ ret = BN_one(rr);
+ }
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+
+ /*
+ * Allocate a montgomery context if it was not supplied by the caller. If
+ * this is not done, things will break in the montgomery part.
+ */
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+#ifdef RSAZ_ENABLED
+ /*
+ * If the size of the operands allow it, perform the optimized
+ * RSAZ exponentiation. For further information see
+ * crypto/bn/rsaz_exp.c and accompanying assembly modules.
+ */
+ if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024)
+ && rsaz_avx2_eligible()) {
+ if (NULL == bn_wexpand(rr, 16))
+ goto err;
+ RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d,
+ mont->n0[0]);
+ rr->top = 16;
+ rr->neg = 0;
+ bn_correct_top(rr);
+ ret = 1;
+ goto err;
+ } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {
+ if (NULL == bn_wexpand(rr, 8))
+ goto err;
+ RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
+ rr->top = 8;
+ rr->neg = 0;
+ bn_correct_top(rr);
+ ret = 1;
+ goto err;
+ }
+#endif
+
+ /* Get the window size to use with size of p. */
+ window = BN_window_bits_for_ctime_exponent_size(bits);
+#if defined(SPARC_T4_MONT)
+ if (window >= 5 && (top & 15) == 0 && top <= 64 &&
+ (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) ==
+ (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0]))
+ window = 5;
+ else
+#endif
+#if defined(OPENSSL_BN_ASM_MONT5)
+ if (window >= 5) {
+ window = 5; /* ~5% improvement for RSA2048 sign, and even
+ * for RSA4096 */
+ /* reserve space for mont->N.d[] copy */
+ powerbufLen += top * sizeof(mont->N.d[0]);
+ }
+#endif
+ (void)0;
+
+ /*
+ * Allocate a buffer large enough to hold all of the pre-computed powers
+ * of am, am itself and tmp.
+ */
+ numPowers = 1 << window;
+ powerbufLen += sizeof(m->d[0]) * (top * numPowers +
+ ((2 * top) >
+ numPowers ? (2 * top) : numPowers));
+#ifdef alloca
+ if (powerbufLen < 3072)
+ powerbufFree =
+ alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
+ else
+#endif
+ if ((powerbufFree =
+ (unsigned char *)OPENSSL_malloc(powerbufLen +
+ MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH))
+ == NULL)
+ goto err;
+
+ powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
+ memset(powerbuf, 0, powerbufLen);
+
+#ifdef alloca
+ if (powerbufLen < 3072)
+ powerbufFree = NULL;
+#endif
+
+ /* lay down tmp and am right after powers table */
+ tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
+ am.d = tmp.d + top;
+ tmp.top = am.top = 0;
+ tmp.dmax = am.dmax = top;
+ tmp.neg = am.neg = 0;
+ tmp.flags = am.flags = BN_FLG_STATIC_DATA;
+
+ /* prepare a^0 in Montgomery domain */
+#if 1 /* by Shay Gueron's suggestion */
+ if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+ /* 2^(top*BN_BITS2) - m */
+ tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
+ for (i = 1; i < top; i++)
+ tmp.d[i] = (~m->d[i]) & BN_MASK2;
+ tmp.top = top;
+ } else
+#endif
+ if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
+ goto err;
+
+ /* prepare a^1 in Montgomery domain */
+ if (a->neg || BN_ucmp(a, m) >= 0) {
+ if (!BN_mod(&am, a, m, ctx))
+ goto err;
+ if (!BN_to_montgomery(&am, &am, mont, ctx))
+ goto err;
+ } else if (!BN_to_montgomery(&am, a, mont, ctx))
+ goto err;
+
+#if defined(SPARC_T4_MONT)
+ if (t4) {
+ typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np,
+ const BN_ULONG *n0, const void *table,
+ int power, int bits);
+ int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np,
+ const BN_ULONG *n0, const void *table,
+ int power, int bits);
+ int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np,
+ const BN_ULONG *n0, const void *table,
+ int power, int bits);
+ int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np,
+ const BN_ULONG *n0, const void *table,
+ int power, int bits);
+ int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np,
+ const BN_ULONG *n0, const void *table,
+ int power, int bits);
+ static const bn_pwr5_mont_f pwr5_funcs[4] = {
+ bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16,
+ bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32
+ };
+ bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1];
+
+ typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap,
+ const void *bp, const BN_ULONG *np,
+ const BN_ULONG *n0);
+ int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+ int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *bp, const BN_ULONG *np,
+ const BN_ULONG *n0);
+ int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *bp, const BN_ULONG *np,
+ const BN_ULONG *n0);
+ int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *bp, const BN_ULONG *np,
+ const BN_ULONG *n0);
+ static const bn_mul_mont_f mul_funcs[4] = {
+ bn_mul_mont_t4_8, bn_mul_mont_t4_16,
+ bn_mul_mont_t4_24, bn_mul_mont_t4_32
+ };
+ bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1];
+
+ void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *bp, const BN_ULONG *np,
+ const BN_ULONG *n0, int num);
+ void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *bp, const BN_ULONG *np,
+ const BN_ULONG *n0, int num);
+ void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *table, const BN_ULONG *np,
+ const BN_ULONG *n0, int num, int power);
+ void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num,
+ void *table, size_t power);
+ void bn_gather5_t4(BN_ULONG *out, size_t num,
+ void *table, size_t power);
+ void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num);
+
+ BN_ULONG *np = mont->N.d, *n0 = mont->n0;
+ int stride = 5 * (6 - (top / 16 - 1)); /* multiple of 5, but less
+ * than 32 */
+
+ /*
+ * BN_to_montgomery can contaminate words above .top [in
+ * BN_DEBUG[_DEBUG] build]...
+ */
+ for (i = am.top; i < top; i++)
+ am.d[i] = 0;
+ for (i = tmp.top; i < top; i++)
+ tmp.d[i] = 0;
+
+ bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0);
+ bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1);
+ if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) &&
+ !(*mul_worker) (tmp.d, am.d, am.d, np, n0))
+ bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top);
+ bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2);
+
+ for (i = 3; i < 32; i++) {
+ /* Calculate a^i = a^(i-1) * a */
+ if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) &&
+ !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0))
+ bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top);
+ bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i);
+ }
+
+ /* switch to 64-bit domain */
+ np = alloca(top * sizeof(BN_ULONG));
+ top /= 2;
+ bn_flip_t4(np, mont->N.d, top);
+
+ bits--;
+ for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ bn_gather5_t4(tmp.d, top, powerbuf, wvalue);
+
+ /*
+ * Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ while (bits >= 0) {
+ if (bits < stride)
+ stride = bits + 1;
+ bits -= stride;
+ wvalue = bn_get_bits(p, bits + 1);
+
+ if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
+ continue;
+ /* retry once and fall back */
+ if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
+ continue;
+
+ bits += stride - 5;
+ wvalue >>= stride - 5;
+ wvalue &= 31;
+ bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top,
+ wvalue);
+ }
+
+ bn_flip_t4(tmp.d, tmp.d, top);
+ top *= 2;
+ /* back to 32-bit domain */
+ tmp.top = top;
+ bn_correct_top(&tmp);
+ OPENSSL_cleanse(np, top * sizeof(BN_ULONG));
+ } else
+#endif
+#if defined(OPENSSL_BN_ASM_MONT5)
+ if (window == 5 && top > 1) {
+ /*
+ * This optimization uses ideas from http://eprint.iacr.org/2011/239,
+ * specifically optimization of cache-timing attack countermeasures
+ * and pre-computation optimization.
+ */
+
+ /*
+ * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
+ * 512-bit RSA is hardly relevant, we omit it to spare size...
+ */
+ void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *table, const BN_ULONG *np,
+ const BN_ULONG *n0, int num, int power);
+ void bn_scatter5(const BN_ULONG *inp, size_t num,
+ void *table, size_t power);
+ void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
+ void bn_power5(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *table, const BN_ULONG *np,
+ const BN_ULONG *n0, int num, int power);
+ int bn_get_bits5(const BN_ULONG *ap, int off);
+ int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
+ const BN_ULONG *not_used, const BN_ULONG *np,
+ const BN_ULONG *n0, int num);
+
+ BN_ULONG *n0 = mont->n0, *np;
+
+ /*
+ * BN_to_montgomery can contaminate words above .top [in
+ * BN_DEBUG[_DEBUG] build]...
+ */
+ for (i = am.top; i < top; i++)
+ am.d[i] = 0;
+ for (i = tmp.top; i < top; i++)
+ tmp.d[i] = 0;
+
+ /*
+ * copy mont->N.d[] to improve cache locality
+ */
+ for (np = am.d + top, i = 0; i < top; i++)
+ np[i] = mont->N.d[i];
+
+ bn_scatter5(tmp.d, top, powerbuf, 0);
+ bn_scatter5(am.d, am.top, powerbuf, 1);
+ bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, 2);
+
+# if 0
+ for (i = 3; i < 32; i++) {
+ /* Calculate a^i = a^(i-1) * a */
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ }
+# else
+ /* same as above, but uses squaring for 1/2 of operations */
+ for (i = 4; i < 32; i *= 2) {
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ }
+ for (i = 3; i < 8; i += 2) {
+ int j;
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ for (j = 2 * i; j < 32; j *= 2) {
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, j);
+ }
+ }
+ for (; i < 16; i += 2) {
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, 2 * i);
+ }
+ for (; i < 32; i += 2) {
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ }
+# endif
+ bits--;
+ for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ bn_gather5(tmp.d, top, powerbuf, wvalue);
+
+ /*
+ * Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ if (top & 7)
+ while (bits >= 0) {
+ for (wvalue = 0, i = 0; i < 5; i++, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top,
+ wvalue);
+ } else {
+ while (bits >= 0) {
+ wvalue = bn_get_bits5(p->d, bits - 4);
+ bits -= 5;
+ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+ }
+ }
+
+ ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);
+ tmp.top = top;
+ bn_correct_top(&tmp);
+ if (ret) {
+ if (!BN_copy(rr, &tmp))
+ ret = 0;
+ goto err; /* non-zero ret means it's not error */
+ }
+ } else
+#endif
+ {
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window))
+ goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window))
+ goto err;
+
+ /*
+ * If the window size is greater than 1, then calculate
+ * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even
+ * powers could instead be computed as (a^(i/2))^2 to use the slight
+ * performance advantage of sqr over mul).
+ */
+ if (window > 1) {
+ if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
+ goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
+ window))
+ goto err;
+ for (i = 3; i < numPowers; i++) {
+ /* Calculate a^i = a^(i-1) * a */
+ if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
+ goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
+ window))
+ goto err;
+ }
+ }
+
+ bits--;
+ for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,
+ window))
+ goto err;
+
+ /*
+ * Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ while (bits >= 0) {
+ wvalue = 0; /* The 'value' of the window */
+
+ /* Scan the window, squaring the result as we go */
+ for (i = 0; i < window; i++, bits--) {
+ if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
+ goto err;
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ }
+
+ /*
+ * Fetch the appropriate pre-computed value from the pre-buf
+ */
+ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue,
+ window))
+ goto err;
+
+ /* Multiply the result into the intermediate result */
+ if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
+ goto err;
+ }
+ }
+
+ /* Convert the final result from montgomery to standard format */
+#if defined(SPARC_T4_MONT)
+ if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
+ am.d[0] = 1; /* borrow am */
+ for (i = 1; i < top; i++)
+ am.d[i] = 0;
+ if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx))
+ goto err;
+ } else
+#endif
+ if (!BN_from_montgomery(rr, &tmp, mont, ctx))
+ goto err;
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ if (powerbuf != NULL) {
+ OPENSSL_cleanse(powerbuf, powerbufLen);
+ if (powerbufFree)
+ OPENSSL_free(powerbufFree);
+ }
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+ BN_MONT_CTX *mont = NULL;
+ int b, bits, ret = 0;
+ int r_is_one;
+ BN_ULONG w, next_w;
+ BIGNUM *d, *r, *t;
+ BIGNUM *swap_tmp;
+#define BN_MOD_MUL_WORD(r, w, m) \
+ (BN_mul_word(r, (w)) && \
+ (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
+ (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
+ /*
+ * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is
+ * probably more overhead than always using BN_mod (which uses BN_copy if
+ * a similar test returns true).
+ */
+ /*
+ * We can use BN_mod and do not need BN_nnmod because our accumulator is
+ * never negative (the result of BN_mod does not depend on the sign of
+ * the modulus).
+ */
+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
+ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!BN_is_odd(m)) {
+ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ if (m->top == 1)
+ a %= m->d[0]; /* make sure that 'a' is reduced */
+
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ ret = 1;
+ BN_zero(rr);
+ } else {
+ ret = BN_one(rr);
+ }
+ return ret;
+ }
+ if (a == 0) {
+ BN_zero(rr);
+ ret = 1;
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ t = BN_CTX_get(ctx);
+ if (d == NULL || r == NULL || t == NULL)
+ goto err;
+
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ r_is_one = 1; /* except for Montgomery factor */
+
+ /* bits-1 >= 0 */
+
+ /* The result is accumulated in the product r*w. */
+ w = a; /* bit 'bits-1' of 'p' is always set */
+ for (b = bits - 2; b >= 0; b--) {
+ /* First, square r*w. */
+ next_w = w * w;
+ if ((next_w / w) != w) { /* overflow */
+ if (r_is_one) {
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+ goto err;
+ r_is_one = 0;
+ } else {
+ if (!BN_MOD_MUL_WORD(r, w, m))
+ goto err;
+ }
+ next_w = 1;
+ }
+ w = next_w;
+ if (!r_is_one) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+
+ /* Second, multiply r*w by 'a' if exponent bit is set. */
+ if (BN_is_bit_set(p, b)) {
+ next_w = w * a;
+ if ((next_w / a) != w) { /* overflow */
+ if (r_is_one) {
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+ goto err;
+ r_is_one = 0;
+ } else {
+ if (!BN_MOD_MUL_WORD(r, w, m))
+ goto err;
+ }
+ next_w = a;
+ }
+ w = next_w;
+ }
+ }
+
+ /* Finally, set r:=r*w. */
+ if (w != 1) {
+ if (r_is_one) {
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+ goto err;
+ r_is_one = 0;
+ } else {
+ if (!BN_MOD_MUL_WORD(r, w, m))
+ goto err;
+ }
+ }
+
+ if (r_is_one) { /* can happen only if a == 1 */
+ if (!BN_one(rr))
+ goto err;
+ } else {
+ if (!BN_from_montgomery(rr, r, mont, ctx))
+ goto err;
+ }
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ bn_check_top(rr);
+ return (ret);
+}
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+{
+ int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+ int start = 1;
+ BIGNUM *d;
+ /* Table of variables obtained from 'ctx' */
+ BIGNUM *val[TABLE_SIZE];
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ ret = 1;
+ BN_zero(r);
+ } else {
+ ret = BN_one(r);
+ }
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ val[0] = BN_CTX_get(ctx);
+ if (!d || !val[0])
+ goto err;
+
+ if (!BN_nnmod(val[0], a, m, ctx))
+ goto err; /* 1 */
+ if (BN_is_zero(val[0])) {
+ BN_zero(r);
+ ret = 1;
+ goto err;
+ }
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1) {
+ if (!BN_mod_mul(d, val[0], val[0], m, ctx))
+ goto err; /* 2 */
+ j = 1 << (window - 1);
+ for (i = 1; i < j; i++) {
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul(val[i], val[i - 1], d, m, ctx))
+ goto err;
+ }
+ }
+
+ start = 1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue = 0; /* The 'value' of the window */
+ wstart = bits - 1; /* The top bit of the window */
+ wend = 0; /* The bottom bit of the window */
+
+ if (!BN_one(r))
+ goto err;
+
+ for (;;) {
+ if (BN_is_bit_set(p, wstart) == 0) {
+ if (!start)
+ if (!BN_mod_mul(r, r, r, m, ctx))
+ goto err;
+ if (wstart == 0)
+ break;
+ wstart--;
+ continue;
+ }
+ /*
+ * We now have wstart on a 'set' bit, we now need to work out how bit
+ * a window to do. To do this we need to scan forward until the last
+ * set bit before the end of the window
+ */
+ j = wstart;
+ wvalue = 1;
+ wend = 0;
+ for (i = 1; i < window; i++) {
+ if (wstart - i < 0)
+ break;
+ if (BN_is_bit_set(p, wstart - i)) {
+ wvalue <<= (i - wend);
+ wvalue |= 1;
+ wend = i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j = wend + 1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i = 0; i < j; i++) {
+ if (!BN_mod_mul(r, r, r, m, ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart -= wend + 1;
+ wvalue = 0;
+ start = 0;
+ if (wstart < 0)
+ break;
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_exp2.c b/Cryptlib/OpenSSL/crypto/bn/bn_exp2.c
new file mode 100644
index 00000000..43fd2044
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_exp2.c
@@ -0,0 +1,303 @@
+/* crypto/bn/bn_exp2.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-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).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define TABLE_SIZE 32
+
+int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
+ const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+ int i, j, bits, b, bits1, bits2, ret =
+ 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2;
+ int r_is_one = 1;
+ BIGNUM *d, *r;
+ const BIGNUM *a_mod_m;
+ /* Tables of variables obtained from 'ctx' */
+ BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
+ BN_MONT_CTX *mont = NULL;
+
+ bn_check_top(a1);
+ bn_check_top(p1);
+ bn_check_top(a2);
+ bn_check_top(p2);
+ bn_check_top(m);
+
+ if (!(m->d[0] & 1)) {
+ BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ bits1 = BN_num_bits(p1);
+ bits2 = BN_num_bits(p2);
+ if ((bits1 == 0) && (bits2 == 0)) {
+ ret = BN_one(rr);
+ return ret;
+ }
+
+ bits = (bits1 > bits2) ? bits1 : bits2;
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ val1[0] = BN_CTX_get(ctx);
+ val2[0] = BN_CTX_get(ctx);
+ if (!d || !r || !val1[0] || !val2[0])
+ goto err;
+
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ window1 = BN_window_bits_for_exponent_size(bits1);
+ window2 = BN_window_bits_for_exponent_size(bits2);
+
+ /*
+ * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1)
+ */
+ if (a1->neg || BN_ucmp(a1, m) >= 0) {
+ if (!BN_mod(val1[0], a1, m, ctx))
+ goto err;
+ a_mod_m = val1[0];
+ } else
+ a_mod_m = a1;
+ if (BN_is_zero(a_mod_m)) {
+ BN_zero(rr);
+ ret = 1;
+ goto err;
+ }
+
+ if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx))
+ goto err;
+ if (window1 > 1) {
+ if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx))
+ goto err;
+
+ j = 1 << (window1 - 1);
+ for (i = 1; i < j; i++) {
+ if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx))
+ goto err;
+ }
+ }
+
+ /*
+ * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1)
+ */
+ if (a2->neg || BN_ucmp(a2, m) >= 0) {
+ if (!BN_mod(val2[0], a2, m, ctx))
+ goto err;
+ a_mod_m = val2[0];
+ } else
+ a_mod_m = a2;
+ if (BN_is_zero(a_mod_m)) {
+ BN_zero(rr);
+ ret = 1;
+ goto err;
+ }
+ if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx))
+ goto err;
+ if (window2 > 1) {
+ if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx))
+ goto err;
+
+ j = 1 << (window2 - 1);
+ for (i = 1; i < j; i++) {
+ if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx))
+ goto err;
+ }
+ }
+
+ /* Now compute the power product, using independent windows. */
+ r_is_one = 1;
+ wvalue1 = 0; /* The 'value' of the first window */
+ wvalue2 = 0; /* The 'value' of the second window */
+ wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the
+ * first window */
+ wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the
+ * second window */
+
+ if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+ goto err;
+ for (b = bits - 1; b >= 0; b--) {
+ if (!r_is_one) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+
+ if (!wvalue1)
+ if (BN_is_bit_set(p1, b)) {
+ /*
+ * consider bits b-window1+1 .. b for this window
+ */
+ i = b - window1 + 1;
+ while (!BN_is_bit_set(p1, i)) /* works for i<0 */
+ i++;
+ wpos1 = i;
+ wvalue1 = 1;
+ for (i = b - 1; i >= wpos1; i--) {
+ wvalue1 <<= 1;
+ if (BN_is_bit_set(p1, i))
+ wvalue1++;
+ }
+ }
+
+ if (!wvalue2)
+ if (BN_is_bit_set(p2, b)) {
+ /*
+ * consider bits b-window2+1 .. b for this window
+ */
+ i = b - window2 + 1;
+ while (!BN_is_bit_set(p2, i))
+ i++;
+ wpos2 = i;
+ wvalue2 = 1;
+ for (i = b - 1; i >= wpos2; i--) {
+ wvalue2 <<= 1;
+ if (BN_is_bit_set(p2, i))
+ wvalue2++;
+ }
+ }
+
+ if (wvalue1 && b == wpos1) {
+ /* wvalue1 is odd and < 2^window1 */
+ if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx))
+ goto err;
+ wvalue1 = 0;
+ r_is_one = 0;
+ }
+
+ if (wvalue2 && b == wpos2) {
+ /* wvalue2 is odd and < 2^window2 */
+ if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx))
+ goto err;
+ wvalue2 = 0;
+ r_is_one = 0;
+ }
+ }
+ if (!BN_from_montgomery(rr, r, mont, ctx))
+ goto err;
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ bn_check_top(rr);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_gcd.c b/Cryptlib/OpenSSL/crypto/bn/bn_gcd.c
new file mode 100644
index 00000000..ce59fe70
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_gcd.c
@@ -0,0 +1,702 @@
+/* crypto/bn/bn_gcd.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 "cryptlib.h"
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *t;
+ int ret = 0;
+
+ bn_check_top(in_a);
+ bn_check_top(in_b);
+
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ if (a == NULL || b == NULL)
+ goto err;
+
+ if (BN_copy(a, in_a) == NULL)
+ goto err;
+ if (BN_copy(b, in_b) == NULL)
+ goto err;
+ a->neg = 0;
+ b->neg = 0;
+
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ t = euclid(a, b);
+ if (t == NULL)
+ goto err;
+
+ if (BN_copy(r, t) == NULL)
+ goto err;
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+{
+ BIGNUM *t;
+ int shifts = 0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /* 0 <= b <= a */
+ while (!BN_is_zero(b)) {
+ /* 0 < b <= a */
+
+ if (BN_is_odd(a)) {
+ if (BN_is_odd(b)) {
+ if (!BN_sub(a, a, b))
+ goto err;
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ } else { /* a odd - b even */
+
+ if (!BN_rshift1(b, b))
+ goto err;
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ }
+ } else { /* a is even */
+
+ if (BN_is_odd(b)) {
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ } else { /* a even - b even */
+
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (!BN_rshift1(b, b))
+ goto err;
+ shifts++;
+ }
+ }
+ /* 0 <= b <= a */
+ }
+
+ if (shifts) {
+ if (!BN_lshift(a, a, shifts))
+ goto err;
+ }
+ bn_check_top(a);
+ return (a);
+ err:
+ return (NULL);
+}
+
+/* solves ax == 1 (mod n) */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
+
+BIGNUM *BN_mod_inverse(BIGNUM *in,
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+{
+ BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+ BIGNUM *ret = NULL;
+ int sign;
+
+ if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0)
+ || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
+ return BN_mod_inverse_no_branch(in, a, n, ctx);
+ }
+
+ bn_check_top(a);
+ bn_check_top(n);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ D = BN_CTX_get(ctx);
+ M = BN_CTX_get(ctx);
+ Y = BN_CTX_get(ctx);
+ T = BN_CTX_get(ctx);
+ if (T == NULL)
+ goto err;
+
+ if (in == NULL)
+ R = BN_new();
+ else
+ R = in;
+ if (R == NULL)
+ goto err;
+
+ BN_one(X);
+ BN_zero(Y);
+ if (BN_copy(B, a) == NULL)
+ goto err;
+ if (BN_copy(A, n) == NULL)
+ goto err;
+ A->neg = 0;
+ if (B->neg || (BN_ucmp(B, A) >= 0)) {
+ if (!BN_nnmod(B, B, A, ctx))
+ goto err;
+ }
+ sign = -1;
+ /*-
+ * From B = a mod |n|, A = |n| it follows that
+ *
+ * 0 <= B < A,
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ */
+
+ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
+ /*
+ * Binary inversion algorithm; requires odd modulus. This is faster
+ * than the general algorithm if the modulus is sufficiently small
+ * (about 400 .. 500 bits on 32-bit sytems, but much more on 64-bit
+ * systems)
+ */
+ int shift;
+
+ while (!BN_is_zero(B)) {
+ /*-
+ * 0 < B < |n|,
+ * 0 < A <= |n|,
+ * (1) -sign*X*a == B (mod |n|),
+ * (2) sign*Y*a == A (mod |n|)
+ */
+
+ /*
+ * Now divide B by the maximum possible power of two in the
+ * integers, and divide X by the same value mod |n|. When we're
+ * done, (1) still holds.
+ */
+ shift = 0;
+ while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */
+ shift++;
+
+ if (BN_is_odd(X)) {
+ if (!BN_uadd(X, X, n))
+ goto err;
+ }
+ /*
+ * now X is even, so we can easily divide it by two
+ */
+ if (!BN_rshift1(X, X))
+ goto err;
+ }
+ if (shift > 0) {
+ if (!BN_rshift(B, B, shift))
+ goto err;
+ }
+
+ /*
+ * Same for A and Y. Afterwards, (2) still holds.
+ */
+ shift = 0;
+ while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */
+ shift++;
+
+ if (BN_is_odd(Y)) {
+ if (!BN_uadd(Y, Y, n))
+ goto err;
+ }
+ /* now Y is even */
+ if (!BN_rshift1(Y, Y))
+ goto err;
+ }
+ if (shift > 0) {
+ if (!BN_rshift(A, A, shift))
+ goto err;
+ }
+
+ /*-
+ * We still have (1) and (2).
+ * Both A and B are odd.
+ * The following computations ensure that
+ *
+ * 0 <= B < |n|,
+ * 0 < A < |n|,
+ * (1) -sign*X*a == B (mod |n|),
+ * (2) sign*Y*a == A (mod |n|),
+ *
+ * and that either A or B is even in the next iteration.
+ */
+ if (BN_ucmp(B, A) >= 0) {
+ /* -sign*(X + Y)*a == B - A (mod |n|) */
+ if (!BN_uadd(X, X, Y))
+ goto err;
+ /*
+ * NB: we could use BN_mod_add_quick(X, X, Y, n), but that
+ * actually makes the algorithm slower
+ */
+ if (!BN_usub(B, B, A))
+ goto err;
+ } else {
+ /* sign*(X + Y)*a == A - B (mod |n|) */
+ if (!BN_uadd(Y, Y, X))
+ goto err;
+ /*
+ * as above, BN_mod_add_quick(Y, Y, X, n) would slow things
+ * down
+ */
+ if (!BN_usub(A, A, B))
+ goto err;
+ }
+ }
+ } else {
+ /* general inversion algorithm */
+
+ while (!BN_is_zero(B)) {
+ BIGNUM *tmp;
+
+ /*-
+ * 0 < B < A,
+ * (*) -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|)
+ */
+
+ /* (D, M) := (A/B, A%B) ... */
+ if (BN_num_bits(A) == BN_num_bits(B)) {
+ if (!BN_one(D))
+ goto err;
+ if (!BN_sub(M, A, B))
+ goto err;
+ } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
+ /* A/B is 1, 2, or 3 */
+ if (!BN_lshift1(T, B))
+ goto err;
+ if (BN_ucmp(A, T) < 0) {
+ /* A < 2*B, so D=1 */
+ if (!BN_one(D))
+ goto err;
+ if (!BN_sub(M, A, B))
+ goto err;
+ } else {
+ /* A >= 2*B, so D=2 or D=3 */
+ if (!BN_sub(M, A, T))
+ goto err;
+ if (!BN_add(D, T, B))
+ goto err; /* use D (:= 3*B) as temp */
+ if (BN_ucmp(A, D) < 0) {
+ /* A < 3*B, so D=2 */
+ if (!BN_set_word(D, 2))
+ goto err;
+ /*
+ * M (= A - 2*B) already has the correct value
+ */
+ } else {
+ /* only D=3 remains */
+ if (!BN_set_word(D, 3))
+ goto err;
+ /*
+ * currently M = A - 2*B, but we need M = A - 3*B
+ */
+ if (!BN_sub(M, M, B))
+ goto err;
+ }
+ }
+ } else {
+ if (!BN_div(D, M, A, B, ctx))
+ goto err;
+ }
+
+ /*-
+ * Now
+ * A = D*B + M;
+ * thus we have
+ * (**) sign*Y*a == D*B + M (mod |n|).
+ */
+
+ tmp = A; /* keep the BIGNUM object, the value does not
+ * matter */
+
+ /* (A, B) := (B, A mod B) ... */
+ A = B;
+ B = M;
+ /* ... so we have 0 <= B < A again */
+
+ /*-
+ * Since the former M is now B and the former B is now A,
+ * (**) translates into
+ * sign*Y*a == D*A + B (mod |n|),
+ * i.e.
+ * sign*Y*a - D*A == B (mod |n|).
+ * Similarly, (*) translates into
+ * -sign*X*a == A (mod |n|).
+ *
+ * Thus,
+ * sign*Y*a + D*sign*X*a == B (mod |n|),
+ * i.e.
+ * sign*(Y + D*X)*a == B (mod |n|).
+ *
+ * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ * Note that X and Y stay non-negative all the time.
+ */
+
+ /*
+ * most of the time D is very small, so we can optimize tmp :=
+ * D*X+Y
+ */
+ if (BN_is_one(D)) {
+ if (!BN_add(tmp, X, Y))
+ goto err;
+ } else {
+ if (BN_is_word(D, 2)) {
+ if (!BN_lshift1(tmp, X))
+ goto err;
+ } else if (BN_is_word(D, 4)) {
+ if (!BN_lshift(tmp, X, 2))
+ goto err;
+ } else if (D->top == 1) {
+ if (!BN_copy(tmp, X))
+ goto err;
+ if (!BN_mul_word(tmp, D->d[0]))
+ goto err;
+ } else {
+ if (!BN_mul(tmp, D, X, ctx))
+ goto err;
+ }
+ if (!BN_add(tmp, tmp, Y))
+ goto err;
+ }
+
+ M = Y; /* keep the BIGNUM object, the value does not
+ * matter */
+ Y = X;
+ X = tmp;
+ sign = -sign;
+ }
+ }
+
+ /*-
+ * The while loop (Euclid's algorithm) ends when
+ * A == gcd(a,n);
+ * we have
+ * sign*Y*a == A (mod |n|),
+ * where Y is non-negative.
+ */
+
+ if (sign < 0) {
+ if (!BN_sub(Y, n, Y))
+ goto err;
+ }
+ /* Now Y*a == A (mod |n|). */
+
+ if (BN_is_one(A)) {
+ /* Y*a == 1 (mod |n|) */
+ if (!Y->neg && BN_ucmp(Y, n) < 0) {
+ if (!BN_copy(R, Y))
+ goto err;
+ } else {
+ if (!BN_nnmod(R, Y, n, ctx))
+ goto err;
+ }
+ } else {
+ BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
+ goto err;
+ }
+ ret = R;
+ err:
+ if ((ret == NULL) && (in == NULL))
+ BN_free(R);
+ BN_CTX_end(ctx);
+ bn_check_top(ret);
+ return (ret);
+}
+
+/*
+ * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
+ * not contain branches that may leak sensitive information.
+ */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx)
+{
+ BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+ BIGNUM local_A, local_B;
+ BIGNUM *pA, *pB;
+ BIGNUM *ret = NULL;
+ int sign;
+
+ bn_check_top(a);
+ bn_check_top(n);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ D = BN_CTX_get(ctx);
+ M = BN_CTX_get(ctx);
+ Y = BN_CTX_get(ctx);
+ T = BN_CTX_get(ctx);
+ if (T == NULL)
+ goto err;
+
+ if (in == NULL)
+ R = BN_new();
+ else
+ R = in;
+ if (R == NULL)
+ goto err;
+
+ BN_one(X);
+ BN_zero(Y);
+ if (BN_copy(B, a) == NULL)
+ goto err;
+ if (BN_copy(A, n) == NULL)
+ goto err;
+ A->neg = 0;
+
+ if (B->neg || (BN_ucmp(B, A) >= 0)) {
+ /*
+ * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+ * BN_div_no_branch will be called eventually.
+ */
+ pB = &local_B;
+ local_B.flags = 0;
+ BN_with_flags(pB, B, BN_FLG_CONSTTIME);
+ if (!BN_nnmod(B, pB, A, ctx))
+ goto err;
+ }
+ sign = -1;
+ /*-
+ * From B = a mod |n|, A = |n| it follows that
+ *
+ * 0 <= B < A,
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ */
+
+ while (!BN_is_zero(B)) {
+ BIGNUM *tmp;
+
+ /*-
+ * 0 < B < A,
+ * (*) -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|)
+ */
+
+ /*
+ * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+ * BN_div_no_branch will be called eventually.
+ */
+ pA = &local_A;
+ local_A.flags = 0;
+ BN_with_flags(pA, A, BN_FLG_CONSTTIME);
+
+ /* (D, M) := (A/B, A%B) ... */
+ if (!BN_div(D, M, pA, B, ctx))
+ goto err;
+
+ /*-
+ * Now
+ * A = D*B + M;
+ * thus we have
+ * (**) sign*Y*a == D*B + M (mod |n|).
+ */
+
+ tmp = A; /* keep the BIGNUM object, the value does not
+ * matter */
+
+ /* (A, B) := (B, A mod B) ... */
+ A = B;
+ B = M;
+ /* ... so we have 0 <= B < A again */
+
+ /*-
+ * Since the former M is now B and the former B is now A,
+ * (**) translates into
+ * sign*Y*a == D*A + B (mod |n|),
+ * i.e.
+ * sign*Y*a - D*A == B (mod |n|).
+ * Similarly, (*) translates into
+ * -sign*X*a == A (mod |n|).
+ *
+ * Thus,
+ * sign*Y*a + D*sign*X*a == B (mod |n|),
+ * i.e.
+ * sign*(Y + D*X)*a == B (mod |n|).
+ *
+ * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ * Note that X and Y stay non-negative all the time.
+ */
+
+ if (!BN_mul(tmp, D, X, ctx))
+ goto err;
+ if (!BN_add(tmp, tmp, Y))
+ goto err;
+
+ M = Y; /* keep the BIGNUM object, the value does not
+ * matter */
+ Y = X;
+ X = tmp;
+ sign = -sign;
+ }
+
+ /*-
+ * The while loop (Euclid's algorithm) ends when
+ * A == gcd(a,n);
+ * we have
+ * sign*Y*a == A (mod |n|),
+ * where Y is non-negative.
+ */
+
+ if (sign < 0) {
+ if (!BN_sub(Y, n, Y))
+ goto err;
+ }
+ /* Now Y*a == A (mod |n|). */
+
+ if (BN_is_one(A)) {
+ /* Y*a == 1 (mod |n|) */
+ if (!Y->neg && BN_ucmp(Y, n) < 0) {
+ if (!BN_copy(R, Y))
+ goto err;
+ } else {
+ if (!BN_nnmod(R, Y, n, ctx))
+ goto err;
+ }
+ } else {
+ BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE);
+ goto err;
+ }
+ ret = R;
+ err:
+ if ((ret == NULL) && (in == NULL))
+ BN_free(R);
+ BN_CTX_end(ctx);
+ bn_check_top(ret);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_gf2m.c b/Cryptlib/OpenSSL/crypto/bn/bn_gf2m.c
new file mode 100644
index 00000000..2c61da11
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_gf2m.c
@@ -0,0 +1,1300 @@
+/* crypto/bn/bn_gf2m.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * In addition, Sun covenants to all licensees who provide a reciprocal
+ * covenant with respect to their own patents if any, not to sue under
+ * current and future patent claims necessarily infringed by the making,
+ * using, practicing, selling, offering for sale and/or otherwise
+ * disposing of the ECC Code as delivered hereunder (or portions thereof),
+ * provided that such covenant shall not apply:
+ * 1) for code that a licensee deletes from the ECC Code;
+ * 2) separates from the ECC Code; or
+ * 3) for infringements caused by:
+ * i) the modification of the ECC Code or
+ * ii) the combination of the ECC Code with other software or
+ * devices where such combination causes the infringement.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+/*
+ * NOTE: This file is licensed pursuant to the OpenSSL license below and may
+ * be modified; but after modifications, the above covenant may no longer
+ * apply! In such cases, the corresponding paragraph ["In addition, Sun
+ * covenants ... causes the infringement."] and this note can be edited out;
+ * but please keep the Sun copyright notice and attribution.
+ */
+
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*
+ * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should
+ * fail.
+ */
+# define MAX_ITERATIONS 50
+
+static const BN_ULONG SQR_tb[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
+ 64, 65, 68, 69, 80, 81, 84, 85
+};
+
+/* Platform-specific macros to accelerate squaring. */
+# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+# define SQR1(w) \
+ SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
+ SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
+ SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
+ SQR_tb[(w) >> 36 & 0xF] << 8 | SQR_tb[(w) >> 32 & 0xF]
+# define SQR0(w) \
+ SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
+ SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
+ SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
+ SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
+# endif
+# ifdef THIRTY_TWO_BIT
+# define SQR1(w) \
+ SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
+ SQR_tb[(w) >> 20 & 0xF] << 8 | SQR_tb[(w) >> 16 & 0xF]
+# define SQR0(w) \
+ SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
+ SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
+# endif
+
+# if !defined(OPENSSL_BN_ASM_GF2m)
+/*
+ * 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 THIRTY_TWO_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[8], top2b = a >> 30;
+ register BN_ULONG a1, a2, a4;
+
+ a1 = a & (0x3FFFFFFF);
+ a2 = a1 << 1;
+ a4 = a2 << 1;
+
+ tab[0] = 0;
+ tab[1] = a1;
+ tab[2] = a2;
+ tab[3] = a1 ^ a2;
+ tab[4] = a4;
+ tab[5] = a1 ^ a4;
+ tab[6] = a2 ^ a4;
+ tab[7] = a1 ^ a2 ^ a4;
+
+ s = tab[b & 0x7];
+ l = s;
+ s = tab[b >> 3 & 0x7];
+ l ^= s << 3;
+ h = s >> 29;
+ s = tab[b >> 6 & 0x7];
+ l ^= s << 6;
+ h ^= s >> 26;
+ s = tab[b >> 9 & 0x7];
+ l ^= s << 9;
+ h ^= s >> 23;
+ s = tab[b >> 12 & 0x7];
+ l ^= s << 12;
+ h ^= s >> 20;
+ s = tab[b >> 15 & 0x7];
+ l ^= s << 15;
+ h ^= s >> 17;
+ s = tab[b >> 18 & 0x7];
+ l ^= s << 18;
+ h ^= s >> 14;
+ s = tab[b >> 21 & 0x7];
+ l ^= s << 21;
+ h ^= s >> 11;
+ s = tab[b >> 24 & 0x7];
+ l ^= s << 24;
+ h ^= s >> 8;
+ s = tab[b >> 27 & 0x7];
+ l ^= s << 27;
+ h ^= s >> 5;
+ s = tab[b >> 30];
+ l ^= s << 30;
+ h ^= s >> 2;
+
+ /* compensate for the top two bits of a */
+
+ if (top2b & 01) {
+ l ^= b << 30;
+ h ^= b >> 2;
+ }
+ if (top2b & 02) {
+ l ^= b << 31;
+ h ^= b >> 1;
+ }
+
+ *r1 = h;
+ *r0 = l;
+}
+# endif
+# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+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[16], top3b = a >> 61;
+ register BN_ULONG a1, a2, a4, a8;
+
+ a1 = a & (0x1FFFFFFFFFFFFFFFULL);
+ a2 = a1 << 1;
+ a4 = a2 << 1;
+ a8 = a4 << 1;
+
+ tab[0] = 0;
+ tab[1] = a1;
+ tab[2] = a2;
+ tab[3] = a1 ^ a2;
+ tab[4] = a4;
+ tab[5] = a1 ^ a4;
+ tab[6] = a2 ^ a4;
+ tab[7] = a1 ^ a2 ^ a4;
+ tab[8] = a8;
+ tab[9] = a1 ^ a8;
+ tab[10] = a2 ^ a8;
+ tab[11] = a1 ^ a2 ^ a8;
+ tab[12] = a4 ^ a8;
+ tab[13] = a1 ^ a4 ^ a8;
+ tab[14] = a2 ^ a4 ^ a8;
+ tab[15] = a1 ^ a2 ^ a4 ^ a8;
+
+ s = tab[b & 0xF];
+ l = s;
+ s = tab[b >> 4 & 0xF];
+ l ^= s << 4;
+ h = s >> 60;
+ s = tab[b >> 8 & 0xF];
+ l ^= s << 8;
+ h ^= s >> 56;
+ s = tab[b >> 12 & 0xF];
+ l ^= s << 12;
+ h ^= s >> 52;
+ s = tab[b >> 16 & 0xF];
+ l ^= s << 16;
+ h ^= s >> 48;
+ s = tab[b >> 20 & 0xF];
+ l ^= s << 20;
+ h ^= s >> 44;
+ s = tab[b >> 24 & 0xF];
+ l ^= s << 24;
+ h ^= s >> 40;
+ s = tab[b >> 28 & 0xF];
+ l ^= s << 28;
+ h ^= s >> 36;
+ s = tab[b >> 32 & 0xF];
+ l ^= s << 32;
+ h ^= s >> 32;
+ s = tab[b >> 36 & 0xF];
+ l ^= s << 36;
+ h ^= s >> 28;
+ s = tab[b >> 40 & 0xF];
+ l ^= s << 40;
+ h ^= s >> 24;
+ s = tab[b >> 44 & 0xF];
+ l ^= s << 44;
+ h ^= s >> 20;
+ s = tab[b >> 48 & 0xF];
+ l ^= s << 48;
+ h ^= s >> 16;
+ s = tab[b >> 52 & 0xF];
+ l ^= s << 52;
+ h ^= s >> 12;
+ s = tab[b >> 56 & 0xF];
+ l ^= s << 56;
+ h ^= s >> 8;
+ s = tab[b >> 60];
+ l ^= s << 60;
+ h ^= s >> 4;
+
+ /* compensate for the top three bits of a */
+
+ if (top3b & 01) {
+ l ^= b << 61;
+ h ^= b >> 3;
+ }
+ if (top3b & 02) {
+ l ^= b << 62;
+ h ^= b >> 2;
+ }
+ if (top3b & 04) {
+ l ^= b << 63;
+ h ^= b >> 1;
+ }
+
+ *r1 = h;
+ *r0 = l;
+}
+# endif
+
+/*
+ * Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
+ * result is a polynomial r with degree < 4 * BN_BITS2 - 1 The caller MUST
+ * ensure that the variables have the right amount of space allocated.
+ */
+static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0,
+ const BN_ULONG b1, const BN_ULONG b0)
+{
+ BN_ULONG m1, m0;
+ /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
+ bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1);
+ bn_GF2m_mul_1x1(r + 1, r, a0, b0);
+ bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
+ /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
+ r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
+ r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
+}
+# else
+void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1,
+ BN_ULONG b0);
+# endif
+
+/*
+ * Add polynomials a and b and store result in r; r could be a or b, a and b
+ * could be equal; r is the bitwise XOR of a and b.
+ */
+int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ const BIGNUM *at, *bt;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top) {
+ at = b;
+ bt = a;
+ } else {
+ at = a;
+ bt = b;
+ }
+
+ if (bn_wexpand(r, at->top) == NULL)
+ return 0;
+
+ for (i = 0; i < bt->top; i++) {
+ r->d[i] = at->d[i] ^ bt->d[i];
+ }
+ for (; i < at->top; i++) {
+ r->d[i] = at->d[i];
+ }
+
+ r->top = at->top;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+/*-
+ * Some functions allow for representation of the irreducible polynomials
+ * as an int[], say p. The irreducible f(t) is then of the form:
+ * t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+
+/* 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 int p[])
+{
+ int j, k;
+ int n, dN, d0, d1;
+ BN_ULONG zz, *z;
+
+ bn_check_top(a);
+
+ if (!p[0]) {
+ /* reduction mod 1 => return 0 */
+ BN_zero(r);
+ return 1;
+ }
+
+ /*
+ * Since the algorithm does reduction in the r value, if a != r, copy the
+ * contents of a into r so we can do reduction in r.
+ */
+ if (a != r) {
+ if (!bn_wexpand(r, a->top))
+ return 0;
+ for (j = 0; j < a->top; j++) {
+ r->d[j] = a->d[j];
+ }
+ r->top = a->top;
+ }
+ z = r->d;
+
+ /* start reduction */
+ dN = p[0] / BN_BITS2;
+ for (j = r->top - 1; j > dN;) {
+ zz = z[j];
+ if (z[j] == 0) {
+ j--;
+ continue;
+ }
+ z[j] = 0;
+
+ for (k = 1; p[k] != 0; k++) {
+ /* reducing component t^p[k] */
+ n = p[0] - p[k];
+ d0 = n % BN_BITS2;
+ d1 = BN_BITS2 - d0;
+ n /= BN_BITS2;
+ z[j - n] ^= (zz >> d0);
+ if (d0)
+ z[j - n - 1] ^= (zz << d1);
+ }
+
+ /* reducing component t^0 */
+ n = dN;
+ d0 = p[0] % BN_BITS2;
+ d1 = BN_BITS2 - d0;
+ z[j - n] ^= (zz >> d0);
+ if (d0)
+ z[j - n - 1] ^= (zz << d1);
+ }
+
+ /* final round of reduction */
+ while (j == dN) {
+
+ d0 = p[0] % BN_BITS2;
+ zz = z[dN] >> d0;
+ if (zz == 0)
+ break;
+ d1 = BN_BITS2 - d0;
+
+ /* clear up the top d1 bits */
+ if (d0)
+ z[dN] = (z[dN] << d1) >> d1;
+ else
+ z[dN] = 0;
+ z[0] ^= zz; /* reduction t^0 component */
+
+ for (k = 1; p[k] != 0; k++) {
+ BN_ULONG tmp_ulong;
+
+ /* reducing component t^p[k] */
+ n = p[k] / BN_BITS2;
+ d0 = p[k] % BN_BITS2;
+ d1 = BN_BITS2 - d0;
+ z[n] ^= (zz << d0);
+ if (d0 && (tmp_ulong = zz >> d1))
+ z[n + 1] ^= tmp_ulong;
+ }
+
+ }
+
+ bn_correct_top(r);
+ return 1;
+}
+
+/*
+ * Performs modular reduction of a by p and store result in r. r could be a.
+ * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_arr function.
+ */
+int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
+{
+ int ret = 0;
+ int arr[6];
+ bn_check_top(a);
+ bn_check_top(p);
+ ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0]));
+ if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) {
+ BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH);
+ return 0;
+ }
+ ret = BN_GF2m_mod_arr(r, a, arr);
+ bn_check_top(r);
+ return ret;
+}
+
+/*
+ * 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 int p[], BN_CTX *ctx)
+{
+ int zlen, i, j, k, ret = 0;
+ BIGNUM *s;
+ BN_ULONG x1, x0, y1, y0, zz[4];
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a == b) {
+ return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
+ }
+
+ BN_CTX_start(ctx);
+ if ((s = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ zlen = a->top + b->top + 4;
+ if (!bn_wexpand(s, zlen))
+ goto err;
+ s->top = zlen;
+
+ for (i = 0; i < zlen; i++)
+ s->d[i] = 0;
+
+ for (j = 0; j < b->top; j += 2) {
+ y0 = b->d[j];
+ y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1];
+ for (i = 0; i < a->top; i += 2) {
+ x0 = a->d[i];
+ x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1];
+ bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
+ for (k = 0; k < 4; k++)
+ s->d[i + j + k] ^= zz[k];
+ }
+ }
+
+ bn_correct_top(s);
+ if (BN_GF2m_mod_arr(r, s, p))
+ ret = 1;
+ bn_check_top(r);
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * 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 equal b. This function calls
+ * down to the BN_GF2m_mod_mul_arr implementation; this wrapper function is
+ * only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_mul_arr function.
+ */
+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) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
+ bn_check_top(r);
+ err:
+ if (arr)
+ OPENSSL_free(arr);
+ return ret;
+}
+
+/* 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 int p[],
+ BN_CTX *ctx)
+{
+ int i, ret = 0;
+ BIGNUM *s;
+
+ bn_check_top(a);
+ BN_CTX_start(ctx);
+ if ((s = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (!bn_wexpand(s, 2 * a->top))
+ goto err;
+
+ for (i = a->top - 1; i >= 0; i--) {
+ s->d[2 * i + 1] = SQR1(a->d[i]);
+ s->d[2 * i] = SQR0(a->d[i]);
+ }
+
+ s->top = 2 * a->top;
+ bn_correct_top(s);
+ if (!BN_GF2m_mod_arr(r, s, p))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * Square a, reduce the result mod p, and store it in a. r could be a. This
+ * function calls down to the BN_GF2m_mod_sqr_arr implementation; this
+ * wrapper function is only provided for convenience; for best performance,
+ * use the BN_GF2m_mod_sqr_arr function.
+ */
+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) + 1;
+ int *arr = NULL;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
+ bn_check_top(r);
+ err:
+ if (arr)
+ OPENSSL_free(arr);
+ return ret;
+}
+
+/*
+ * Invert a, reduce modulo p, and store the result in r. r could be a. Uses
+ * Modified Almost Inverse Algorithm (Algorithm 10) from Hankerson, D.,
+ * Hernandez, J.L., and Menezes, A. "Software Implementation of Elliptic
+ * Curve Cryptography Over Binary Fields".
+ */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+ BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
+ int ret = 0;
+
+ bn_check_top(a);
+ bn_check_top(p);
+
+ BN_CTX_start(ctx);
+
+ if ((b = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if ((c = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if ((u = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if ((v = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_GF2m_mod(u, a, p))
+ goto err;
+ if (BN_is_zero(u))
+ goto err;
+
+ if (!BN_copy(v, p))
+ goto err;
+# if 0
+ if (!BN_one(b))
+ goto err;
+
+ while (1) {
+ while (!BN_is_odd(u)) {
+ if (BN_is_zero(u))
+ goto err;
+ if (!BN_rshift1(u, u))
+ goto err;
+ if (BN_is_odd(b)) {
+ if (!BN_GF2m_add(b, b, p))
+ goto err;
+ }
+ if (!BN_rshift1(b, b))
+ goto err;
+ }
+
+ if (BN_abs_is_word(u, 1))
+ break;
+
+ if (BN_num_bits(u) < BN_num_bits(v)) {
+ tmp = u;
+ u = v;
+ v = tmp;
+ tmp = b;
+ b = c;
+ c = tmp;
+ }
+
+ if (!BN_GF2m_add(u, u, v))
+ goto err;
+ if (!BN_GF2m_add(b, b, c))
+ goto err;
+ }
+# else
+ {
+ int i;
+ int ubits = BN_num_bits(u);
+ int vbits = BN_num_bits(v); /* v is copy of p */
+ int top = p->top;
+ BN_ULONG *udp, *bdp, *vdp, *cdp;
+
+ if (!bn_wexpand(u, top))
+ goto err;
+ udp = u->d;
+ for (i = u->top; i < top; i++)
+ udp[i] = 0;
+ u->top = top;
+ if (!bn_wexpand(b, top))
+ goto err;
+ bdp = b->d;
+ bdp[0] = 1;
+ for (i = 1; i < top; i++)
+ bdp[i] = 0;
+ b->top = top;
+ if (!bn_wexpand(c, top))
+ goto err;
+ cdp = c->d;
+ for (i = 0; i < top; i++)
+ cdp[i] = 0;
+ c->top = top;
+ vdp = v->d; /* It pays off to "cache" *->d pointers,
+ * because it allows optimizer to be more
+ * aggressive. But we don't have to "cache"
+ * p->d, because *p is declared 'const'... */
+ while (1) {
+ while (ubits && !(udp[0] & 1)) {
+ BN_ULONG u0, u1, b0, b1, mask;
+
+ u0 = udp[0];
+ b0 = bdp[0];
+ mask = (BN_ULONG)0 - (b0 & 1);
+ b0 ^= p->d[0] & mask;
+ for (i = 0; i < top - 1; i++) {
+ u1 = udp[i + 1];
+ udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2;
+ u0 = u1;
+ b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);
+ bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2;
+ b0 = b1;
+ }
+ udp[i] = u0 >> 1;
+ bdp[i] = b0 >> 1;
+ ubits--;
+ }
+
+ if (ubits <= BN_BITS2) {
+ if (udp[0] == 0) /* poly was reducible */
+ goto err;
+ if (udp[0] == 1)
+ break;
+ }
+
+ if (ubits < vbits) {
+ i = ubits;
+ ubits = vbits;
+ vbits = i;
+ tmp = u;
+ u = v;
+ v = tmp;
+ tmp = b;
+ b = c;
+ c = tmp;
+ udp = vdp;
+ vdp = v->d;
+ bdp = cdp;
+ cdp = c->d;
+ }
+ for (i = 0; i < top; i++) {
+ udp[i] ^= vdp[i];
+ bdp[i] ^= cdp[i];
+ }
+ if (ubits == vbits) {
+ BN_ULONG ul;
+ int utop = (ubits - 1) / BN_BITS2;
+
+ while ((ul = udp[utop]) == 0 && utop)
+ utop--;
+ ubits = utop * BN_BITS2 + BN_num_bits_word(ul);
+ }
+ }
+ bn_correct_top(b);
+ }
+# endif
+
+ if (!BN_copy(r, b))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+
+ err:
+# ifdef BN_DEBUG /* BN_CTX_end would complain about the
+ * expanded form */
+ bn_correct_top(c);
+ bn_correct_top(u);
+ bn_correct_top(v);
+# endif
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * Invert xx, reduce modulo p, and store the result in r. r could be xx.
+ * This function calls down to the BN_GF2m_mod_inv implementation; this
+ * wrapper 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 int p[],
+ BN_CTX *ctx)
+{
+ BIGNUM *field;
+ int ret = 0;
+
+ bn_check_top(xx);
+ BN_CTX_start(ctx);
+ if ((field = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (!BN_GF2m_arr2poly(p, field))
+ goto err;
+
+ ret = BN_GF2m_mod_inv(r, xx, field, ctx);
+ bn_check_top(r);
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+# ifndef OPENSSL_SUN_GF2M_DIV
+/*
+ * Divide y by x, reduce modulo p, and store the result in r. r could be x
+ * or y, x could equal y.
+ */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
+ const BIGNUM *p, BN_CTX *ctx)
+{
+ BIGNUM *xinv = NULL;
+ int ret = 0;
+
+ bn_check_top(y);
+ bn_check_top(x);
+ bn_check_top(p);
+
+ BN_CTX_start(ctx);
+ xinv = BN_CTX_get(ctx);
+ if (xinv == NULL)
+ goto err;
+
+ if (!BN_GF2m_mod_inv(xinv, x, p, ctx))
+ goto err;
+ if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+# else
+/*
+ * Divide y by x, reduce modulo p, and store the result in r. r could be x
+ * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from
+ * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to the
+ * Great Divide".
+ */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
+ const BIGNUM *p, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *u, *v;
+ int ret = 0;
+
+ bn_check_top(y);
+ bn_check_top(x);
+ bn_check_top(p);
+
+ BN_CTX_start(ctx);
+
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ u = BN_CTX_get(ctx);
+ v = BN_CTX_get(ctx);
+ if (v == NULL)
+ goto err;
+
+ /* reduce x and y mod p */
+ if (!BN_GF2m_mod(u, y, p))
+ goto err;
+ if (!BN_GF2m_mod(a, x, p))
+ goto err;
+ if (!BN_copy(b, p))
+ goto err;
+
+ while (!BN_is_odd(a)) {
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (BN_is_odd(u))
+ if (!BN_GF2m_add(u, u, p))
+ goto err;
+ if (!BN_rshift1(u, u))
+ goto err;
+ }
+
+ do {
+ if (BN_GF2m_cmp(b, a) > 0) {
+ if (!BN_GF2m_add(b, b, a))
+ goto err;
+ if (!BN_GF2m_add(v, v, u))
+ goto err;
+ do {
+ if (!BN_rshift1(b, b))
+ goto err;
+ if (BN_is_odd(v))
+ if (!BN_GF2m_add(v, v, p))
+ goto err;
+ if (!BN_rshift1(v, v))
+ goto err;
+ } while (!BN_is_odd(b));
+ } else if (BN_abs_is_word(a, 1))
+ break;
+ else {
+ if (!BN_GF2m_add(a, a, b))
+ goto err;
+ if (!BN_GF2m_add(u, u, v))
+ goto err;
+ do {
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (BN_is_odd(u))
+ if (!BN_GF2m_add(u, u, p))
+ goto err;
+ if (!BN_rshift1(u, u))
+ goto err;
+ } while (!BN_is_odd(a));
+ }
+ } while (1);
+
+ if (!BN_copy(r, u))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+# endif
+
+/*
+ * Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
+ * * or yy, xx could equal yy. This function calls down to the
+ * BN_GF2m_mod_div implementation; this wrapper 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 int p[], BN_CTX *ctx)
+{
+ BIGNUM *field;
+ int ret = 0;
+
+ bn_check_top(yy);
+ bn_check_top(xx);
+
+ BN_CTX_start(ctx);
+ if ((field = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (!BN_GF2m_arr2poly(p, field))
+ goto err;
+
+ ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
+ bn_check_top(r);
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * Compute the bth power of a, reduce modulo p, and store 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 int p[], BN_CTX *ctx)
+{
+ int ret = 0, i, n;
+ BIGNUM *u;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (BN_is_zero(b))
+ return (BN_one(r));
+
+ if (BN_abs_is_word(b, 1))
+ return (BN_copy(r, a) != NULL);
+
+ BN_CTX_start(ctx);
+ if ((u = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_GF2m_mod_arr(u, a, p))
+ goto err;
+
+ n = BN_num_bits(b) - 1;
+ for (i = n - 1; i >= 0; i--) {
+ if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx))
+ goto err;
+ if (BN_is_bit_set(b, i)) {
+ if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx))
+ goto err;
+ }
+ }
+ if (!BN_copy(r, u))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * Compute the bth power of a, reduce modulo p, and store the result in r. r
+ * could be a. This function calls down to the BN_GF2m_mod_exp_arr
+ * implementation; this wrapper function is only provided for convenience;
+ * for best performance, use the BN_GF2m_mod_exp_arr function.
+ */
+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) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
+ bn_check_top(r);
+ err:
+ if (arr)
+ OPENSSL_free(arr);
+ return ret;
+}
+
+/*
+ * Compute the square root of a, reduce modulo p, and store 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 int p[],
+ BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *u;
+
+ bn_check_top(a);
+
+ if (!p[0]) {
+ /* reduction mod 1 => return 0 */
+ BN_zero(r);
+ return 1;
+ }
+
+ BN_CTX_start(ctx);
+ if ((u = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_set_bit(u, p[0] - 1))
+ goto err;
+ ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
+ bn_check_top(r);
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * Compute the square root of a, reduce modulo p, and store the result in r.
+ * r could be a. This function calls down to the BN_GF2m_mod_sqrt_arr
+ * implementation; this wrapper function is only provided for convenience;
+ * for best performance, use the BN_GF2m_mod_sqrt_arr function.
+ */
+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) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
+ bn_check_top(r);
+ err:
+ if (arr)
+ OPENSSL_free(arr);
+ return ret;
+}
+
+/*
+ * 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 int p[],
+ BN_CTX *ctx)
+{
+ int ret = 0, count = 0, j;
+ BIGNUM *a, *z, *rho, *w, *w2, *tmp;
+
+ bn_check_top(a_);
+
+ if (!p[0]) {
+ /* reduction mod 1 => return 0 */
+ BN_zero(r);
+ return 1;
+ }
+
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ z = BN_CTX_get(ctx);
+ w = BN_CTX_get(ctx);
+ if (w == NULL)
+ goto err;
+
+ if (!BN_GF2m_mod_arr(a, a_, p))
+ goto err;
+
+ if (BN_is_zero(a)) {
+ BN_zero(r);
+ ret = 1;
+ goto err;
+ }
+
+ if (p[0] & 0x1) { /* m is odd */
+ /* compute half-trace of a */
+ if (!BN_copy(z, a))
+ goto err;
+ for (j = 1; j <= (p[0] - 1) / 2; j++) {
+ if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+ goto err;
+ if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+ goto err;
+ if (!BN_GF2m_add(z, z, a))
+ goto err;
+ }
+
+ } else { /* m is even */
+
+ rho = BN_CTX_get(ctx);
+ w2 = BN_CTX_get(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
+ do {
+ if (!BN_rand(rho, p[0], 0, 0))
+ goto err;
+ if (!BN_GF2m_mod_arr(rho, rho, p))
+ goto err;
+ BN_zero(z);
+ if (!BN_copy(w, rho))
+ goto err;
+ for (j = 1; j <= p[0] - 1; j++) {
+ if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+ goto err;
+ if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx))
+ goto err;
+ if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx))
+ goto err;
+ if (!BN_GF2m_add(z, z, tmp))
+ goto err;
+ if (!BN_GF2m_add(w, w2, rho))
+ goto err;
+ }
+ count++;
+ } while (BN_is_zero(w) && (count < MAX_ITERATIONS));
+ if (BN_is_zero(w)) {
+ BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS);
+ goto err;
+ }
+ }
+
+ if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx))
+ goto err;
+ if (!BN_GF2m_add(w, z, w))
+ goto err;
+ if (BN_GF2m_cmp(w, a)) {
+ BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
+ goto err;
+ }
+
+ if (!BN_copy(r, z))
+ goto err;
+ bn_check_top(r);
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns
+ * 0. This function calls down to the BN_GF2m_mod_solve_quad_arr
+ * implementation; this wrapper function is only provided for convenience;
+ * for best performance, use the BN_GF2m_mod_solve_quad_arr function.
+ */
+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) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
+ bn_check_top(r);
+ err:
+ if (arr)
+ OPENSSL_free(arr);
+ return ret;
+}
+
+/*
+ * Convert the bit-string representation of a polynomial ( \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 array elements that would
+ * be filled if array was large enough.
+ */
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
+{
+ int i, j, k = 0;
+ BN_ULONG mask;
+
+ if (BN_is_zero(a))
+ return 0;
+
+ for (i = a->top - 1; i >= 0; i--) {
+ if (!a->d[i])
+ /* skip word if a->d[i] == 0 */
+ continue;
+ mask = BN_TBIT;
+ for (j = BN_BITS2 - 1; j >= 0; j--) {
+ if (a->d[i] & mask) {
+ if (k < max)
+ p[k] = BN_BITS2 * i + j;
+ k++;
+ }
+ mask >>= 1;
+ }
+ }
+
+ 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 -1.
+ */
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
+{
+ int i;
+
+ bn_check_top(a);
+ BN_zero(a);
+ for (i = 0; p[i] != -1; i++) {
+ if (BN_set_bit(a, p[i]) == 0)
+ return 0;
+ }
+ bn_check_top(a);
+
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_kron.c b/Cryptlib/OpenSSL/crypto/bn/bn_kron.c
new file mode 100644
index 00000000..88d731ac
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_kron.c
@@ -0,0 +1,186 @@
+/* crypto/bn/bn_kron.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* least significant word */
+#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
+
+/* Returns -2 for errors because both -1 and 0 are valid results. */
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+ int i;
+ int ret = -2; /* avoid 'uninitialized' warning */
+ int err = 0;
+ BIGNUM *A, *B, *tmp;
+ /*-
+ * In 'tab', only odd-indexed entries are relevant:
+ * For any odd BIGNUM n,
+ * tab[BN_lsw(n) & 7]
+ * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
+ * Note that the sign of n does not matter.
+ */
+ static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 };
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ if (B == NULL)
+ goto end;
+
+ err = !BN_copy(A, a);
+ if (err)
+ goto end;
+ err = !BN_copy(B, b);
+ if (err)
+ goto end;
+
+ /*
+ * Kronecker symbol, imlemented according to Henri Cohen,
+ * "A Course in Computational Algebraic Number Theory"
+ * (algorithm 1.4.10).
+ */
+
+ /* Cohen's step 1: */
+
+ if (BN_is_zero(B)) {
+ ret = BN_abs_is_word(A, 1);
+ goto end;
+ }
+
+ /* Cohen's step 2: */
+
+ if (!BN_is_odd(A) && !BN_is_odd(B)) {
+ ret = 0;
+ goto end;
+ }
+
+ /* now B is non-zero */
+ i = 0;
+ while (!BN_is_bit_set(B, i))
+ i++;
+ err = !BN_rshift(B, B, i);
+ if (err)
+ goto end;
+ if (i & 1) {
+ /* i is odd */
+ /* (thus B was even, thus A must be odd!) */
+
+ /* set 'ret' to $(-1)^{(A^2-1)/8}$ */
+ ret = tab[BN_lsw(A) & 7];
+ } else {
+ /* i is even */
+ ret = 1;
+ }
+
+ if (B->neg) {
+ B->neg = 0;
+ if (A->neg)
+ ret = -ret;
+ }
+
+ /*
+ * now B is positive and odd, so what remains to be done is to compute
+ * the Jacobi symbol (A/B) and multiply it by 'ret'
+ */
+
+ while (1) {
+ /* Cohen's step 3: */
+
+ /* B is positive and odd */
+
+ if (BN_is_zero(A)) {
+ ret = BN_is_one(B) ? ret : 0;
+ goto end;
+ }
+
+ /* now A is non-zero */
+ i = 0;
+ while (!BN_is_bit_set(A, i))
+ i++;
+ err = !BN_rshift(A, A, i);
+ if (err)
+ goto end;
+ if (i & 1) {
+ /* i is odd */
+ /* multiply 'ret' by $(-1)^{(B^2-1)/8}$ */
+ ret = ret * tab[BN_lsw(B) & 7];
+ }
+
+ /* Cohen's step 4: */
+ /* multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ */
+ if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
+ ret = -ret;
+
+ /* (A, B) := (B mod |A|, |A|) */
+ err = !BN_nnmod(B, B, A, ctx);
+ if (err)
+ goto end;
+ tmp = A;
+ A = B;
+ B = tmp;
+ tmp->neg = 0;
+ }
+ end:
+ BN_CTX_end(ctx);
+ if (err)
+ return -2;
+ else
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_lcl.h b/Cryptlib/OpenSSL/crypto/bn/bn_lcl.h
new file mode 100644
index 00000000..00f4f099
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_lcl.h
@@ -0,0 +1,537 @@
+/* crypto/bn/bn_lcl.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.]
+ */
+/* ====================================================================
+ * 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_BN_LCL_H
+# define HEADER_BN_LCL_H
+
+# include <openssl/bn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ * 2^(w-1) + (b-w)/(w+1);
+ *
+ * here 2^(w-1) is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1) is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ * w >= 6 if b > 671
+ * w = 5 if 671 > b > 239
+ * w = 4 if 239 > b > 79
+ * w = 3 if 79 > b > 23
+ * w <= 2 if 23 > b
+ *
+ * (with draws in between). Very small exponents are often selected
+ * with low Hamming weight, so we use w = 1 for b <= 23.
+ */
+# if 1
+# define BN_window_bits_for_exponent_size(b) \
+ ((b) > 671 ? 6 : \
+ (b) > 239 ? 5 : \
+ (b) > 79 ? 4 : \
+ (b) > 23 ? 3 : 1)
+# else
+/*
+ * Old SSLeay/OpenSSL table. Maximum window size was 5, so this table differs
+ * for b==1024; but it coincides for other interesting values (b==160,
+ * b==512).
+ */
+# define BN_window_bits_for_exponent_size(b) \
+ ((b) > 255 ? 5 : \
+ (b) > 127 ? 4 : \
+ (b) > 17 ? 3 : 1)
+# endif
+
+/*
+ * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache
+ * line width of the target processor is at least the following value.
+ */
+# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 )
+# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
+
+/*
+ * Window sizes optimized for fixed window size modular exponentiation
+ * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of
+ * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are
+ * defined for cache line sizes of 32 and 64, cache line sizes where
+ * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be
+ * used on processors that have a 128 byte or greater cache line size.
+ */
+# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
+
+# define BN_window_bits_for_ctime_exponent_size(b) \
+ ((b) > 937 ? 6 : \
+ (b) > 306 ? 5 : \
+ (b) > 89 ? 4 : \
+ (b) > 22 ? 3 : 1)
+# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6)
+
+# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
+
+# define BN_window_bits_for_ctime_exponent_size(b) \
+ ((b) > 306 ? 5 : \
+ (b) > 89 ? 4 : \
+ (b) > 22 ? 3 : 1)
+# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5)
+
+# endif
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha 16,16,16,16.64 */
+# define BN_MULL_SIZE_NORMAL (16)/* 32 */
+# define BN_MUL_RECURSIVE_SIZE_NORMAL (16)/* 32 less than */
+# define BN_SQR_RECURSIVE_SIZE_NORMAL (16)/* 32 */
+# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32)/* 32 */
+# define BN_MONT_CTX_SET_SIZE_WORD (64)/* 32 */
+
+/*
+ * 2011-02-22 SMS. In various places, a size_t variable or a type cast to
+ * size_t was used to perform integer-only operations on pointers. This
+ * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t
+ * is still only 32 bits. What's needed in these cases is an integer type
+ * with the same size as a pointer, which size_t is not certain to be. The
+ * only fix here is VMS-specific.
+ */
+# if defined(OPENSSL_SYS_VMS)
+# if __INITIAL_POINTER_SIZE == 64
+# define PTR_SIZE_INT long long
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define PTR_SIZE_INT int
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+# elif !defined(PTR_SIZE_INT) /* defined(OPENSSL_SYS_VMS) */
+# define PTR_SIZE_INT size_t
+# endif /* defined(OPENSSL_SYS_VMS) [else] */
+
+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+# if defined(__DECC)
+# include <c_asm.h>
+# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+# elif defined(__GNUC__) && __GNUC__>=2
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("umulh %1,%2,%0" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif /* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+# if defined(__GNUC__) && __GNUC__>=2
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("mulhdu %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif /* compiler */
+# elif (defined(__x86_64) || defined(__x86_64__)) && \
+ (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+# if defined(__GNUC__) && __GNUC__>=2
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret,discard; \
+ asm ("mulq %3" \
+ : "=a"(discard),"=d"(ret) \
+ : "a"(a), "g"(b) \
+ : "cc"); \
+ ret; })
+# define BN_UMULT_LOHI(low,high,a,b) \
+ asm ("mulq %3" \
+ : "=a"(low),"=d"(high) \
+ : "a"(a),"g"(b) \
+ : "cc");
+# endif
+# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
+# if defined(_MSC_VER) && _MSC_VER>=1400
+unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b);
+unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
+ unsigned __int64 *h);
+# pragma intrinsic(__umulh,_umul128)
+# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
+# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
+# endif
+# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
+# if defined(__GNUC__) && __GNUC__>=2
+# if __GNUC__>4 || (__GNUC__>=4 && __GNUC_MINOR__>=4)
+ /* "h" constraint is no more since 4.4 */
+# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64)
+# define BN_UMULT_LOHI(low,high,a,b) ({ \
+ __uint128_t ret=(__uint128_t)(a)*(b); \
+ (high)=ret>>64; (low)=ret; })
+# else
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("dmultu %1,%2" \
+ : "=h"(ret) \
+ : "r"(a), "r"(b) : "l"); \
+ ret; })
+# define BN_UMULT_LOHI(low,high,a,b)\
+ asm ("dmultu %2,%3" \
+ : "=l"(low),"=h"(high) \
+ : "r"(a), "r"(b));
+# endif
+# endif
+# elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG)
+# if defined(__GNUC__) && __GNUC__>=2
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("umulh %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif
+# endif /* cpu */
+# endif /* OPENSSL_NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+# define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
+# define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+# ifdef BN_DEBUG_RAND
+# define bn_clear_top2max(a) \
+ { \
+ int ind = (a)->dmax - (a)->top; \
+ BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
+ for (; ind != 0; ind--) \
+ *(++ftl) = 0x0; \
+ }
+# else
+# define bn_clear_top2max(a)
+# endif
+
+# ifdef BN_LLONG
+# define mul_add(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (r) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+# define mul(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+# define sqr(r0,r1,a) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)(a)*(a); \
+ (r0)=Lw(t); \
+ (r1)=Hw(t); \
+ }
+
+# elif defined(BN_UMULT_LOHI)
+# define mul_add(r,a,w,c) { \
+ BN_ULONG high,low,ret,tmp=(a); \
+ ret = (r); \
+ BN_UMULT_LOHI(low,high,w,tmp); \
+ ret += (c); \
+ (c) = (ret<(c))?1:0; \
+ (c) += high; \
+ ret += low; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define mul(r,a,w,c) { \
+ BN_ULONG high,low,ret,ta=(a); \
+ BN_UMULT_LOHI(low,high,w,ta); \
+ ret = low + (c); \
+ (c) = high; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define sqr(r0,r1,a) { \
+ BN_ULONG tmp=(a); \
+ BN_UMULT_LOHI(r0,r1,tmp,tmp); \
+ }
+
+# elif defined(BN_UMULT_HIGH)
+# define mul_add(r,a,w,c) { \
+ BN_ULONG high,low,ret,tmp=(a); \
+ ret = (r); \
+ high= BN_UMULT_HIGH(w,tmp); \
+ ret += (c); \
+ low = (w) * tmp; \
+ (c) = (ret<(c))?1:0; \
+ (c) += high; \
+ ret += low; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define mul(r,a,w,c) { \
+ BN_ULONG high,low,ret,ta=(a); \
+ low = (w) * ta; \
+ high= BN_UMULT_HIGH(w,ta); \
+ ret = low + (c); \
+ (c) = high; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define sqr(r0,r1,a) { \
+ BN_ULONG tmp=(a); \
+ (r0) = tmp * tmp; \
+ (r1) = BN_UMULT_HIGH(tmp,tmp); \
+ }
+
+# else
+/*************************************************************
+ * No long long type
+ */
+
+# define LBITS(a) ((a)&BN_MASK2l)
+# define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l)
+# define L2HBITS(a) (((a)<<BN_BITS4)&BN_MASK2)
+
+# define LLBITS(a) ((a)&BN_MASKl)
+# define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl)
+# define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+# define mul64(l,h,bl,bh) \
+ { \
+ BN_ULONG m,m1,lt,ht; \
+ \
+ lt=l; \
+ ht=h; \
+ m =(bh)*(lt); \
+ lt=(bl)*(lt); \
+ m1=(bl)*(ht); \
+ ht =(bh)*(ht); \
+ m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \
+ ht+=HBITS(m); \
+ m1=L2HBITS(m); \
+ lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+ (l)=lt; \
+ (h)=ht; \
+ }
+
+# define sqr64(lo,ho,in) \
+ { \
+ BN_ULONG l,h,m; \
+ \
+ h=(in); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ m =(l)*(h); \
+ l*=l; \
+ h*=h; \
+ h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+ m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+ l=(l+m)&BN_MASK2; if (l < m) h++; \
+ (lo)=l; \
+ (ho)=h; \
+ }
+
+# define mul_add(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=(r); \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l; \
+ }
+
+# define mul(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l&BN_MASK2; \
+ }
+# endif /* !BN_LLONG */
+
+# if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS)
+# undef bn_div_words
+# endif
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n);
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ int dna, int dnb, BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+ int n, int tna, int tnb, BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+ BN_ULONG *t);
+BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl);
+BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl);
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0, int num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_lib.c b/Cryptlib/OpenSSL/crypto/bn/bn_lib.c
new file mode 100644
index 00000000..80105fff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_lib.c
@@ -0,0 +1,916 @@
+/* crypto/bn/bn_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.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT;
+
+/* This stuff appears to be completely unused, so is deprecated */
+#ifndef OPENSSL_NO_DEPRECATED
+/*-
+ * For a 32 bit machine
+ * 2 - 4 == 128
+ * 3 - 8 == 256
+ * 4 - 16 == 512
+ * 5 - 32 == 1024
+ * 6 - 64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits = 0;
+static int bn_limit_num = 8; /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low = 0;
+static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high = 0;
+static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont = 0;
+static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */
+
+void BN_set_params(int mult, int high, int low, int mont)
+{
+ if (mult >= 0) {
+ if (mult > (int)(sizeof(int) * 8) - 1)
+ mult = sizeof(int) * 8 - 1;
+ bn_limit_bits = mult;
+ bn_limit_num = 1 << mult;
+ }
+ if (high >= 0) {
+ if (high > (int)(sizeof(int) * 8) - 1)
+ high = sizeof(int) * 8 - 1;
+ bn_limit_bits_high = high;
+ bn_limit_num_high = 1 << high;
+ }
+ if (low >= 0) {
+ if (low > (int)(sizeof(int) * 8) - 1)
+ low = sizeof(int) * 8 - 1;
+ bn_limit_bits_low = low;
+ bn_limit_num_low = 1 << low;
+ }
+ if (mont >= 0) {
+ if (mont > (int)(sizeof(int) * 8) - 1)
+ mont = sizeof(int) * 8 - 1;
+ bn_limit_bits_mont = mont;
+ bn_limit_num_mont = 1 << mont;
+ }
+}
+
+int BN_get_params(int which)
+{
+ if (which == 0)
+ return (bn_limit_bits);
+ else if (which == 1)
+ return (bn_limit_bits_high);
+ else if (which == 2)
+ return (bn_limit_bits_low);
+ else if (which == 3)
+ return (bn_limit_bits_mont);
+ else
+ return (0);
+}
+#endif
+
+const BIGNUM *BN_value_one(void)
+{
+ 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);
+}
+
+int BN_num_bits_word(BN_ULONG l)
+{
+ 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,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ };
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffffffff00000000L) {
+ if (l & 0xffff000000000000L) {
+ if (l & 0xff00000000000000L) {
+ return (bits[(int)(l >> 56)] + 56);
+ } else
+ return (bits[(int)(l >> 48)] + 48);
+ } else {
+ if (l & 0x0000ff0000000000L) {
+ return (bits[(int)(l >> 40)] + 40);
+ } else
+ return (bits[(int)(l >> 32)] + 32);
+ }
+ } else
+#else
+# ifdef SIXTY_FOUR_BIT
+ if (l & 0xffffffff00000000LL) {
+ if (l & 0xffff000000000000LL) {
+ if (l & 0xff00000000000000LL) {
+ return (bits[(int)(l >> 56)] + 56);
+ } else
+ return (bits[(int)(l >> 48)] + 48);
+ } else {
+ if (l & 0x0000ff0000000000LL) {
+ return (bits[(int)(l >> 40)] + 40);
+ } else
+ return (bits[(int)(l >> 32)] + 32);
+ }
+ } else
+# endif
+#endif
+ {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffff0000L) {
+ if (l & 0xff000000L)
+ return (bits[(int)(l >> 24L)] + 24);
+ else
+ return (bits[(int)(l >> 16L)] + 16);
+ } else
+#endif
+ {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xff00L)
+ return (bits[(int)(l >> 8)] + 8);
+ else
+#endif
+ return (bits[(int)(l)]);
+ }
+ }
+}
+
+int BN_num_bits(const BIGNUM *a)
+{
+ int i = a->top - 1;
+ bn_check_top(a);
+
+ if (BN_is_zero(a))
+ return 0;
+ return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
+}
+
+void BN_clear_free(BIGNUM *a)
+{
+ int i;
+
+ if (a == NULL)
+ return;
+ bn_check_top(a);
+ if (a->d != NULL) {
+ OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
+ if (!(BN_get_flags(a, BN_FLG_STATIC_DATA)))
+ OPENSSL_free(a->d);
+ }
+ i = BN_get_flags(a, BN_FLG_MALLOCED);
+ OPENSSL_cleanse(a, sizeof(BIGNUM));
+ if (i)
+ OPENSSL_free(a);
+}
+
+void BN_free(BIGNUM *a)
+{
+ if (a == NULL)
+ return;
+ bn_check_top(a);
+ if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
+ OPENSSL_free(a->d);
+ if (a->flags & BN_FLG_MALLOCED)
+ OPENSSL_free(a);
+ else {
+#ifndef OPENSSL_NO_DEPRECATED
+ a->flags |= BN_FLG_FREE;
+#endif
+ a->d = NULL;
+ }
+}
+
+void BN_init(BIGNUM *a)
+{
+ memset(a, 0, sizeof(BIGNUM));
+ bn_check_top(a);
+}
+
+BIGNUM *BN_new(void)
+{
+ BIGNUM *ret;
+
+ if ((ret = (BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) {
+ BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->flags = BN_FLG_MALLOCED;
+ ret->top = 0;
+ ret->neg = 0;
+ ret->dmax = 0;
+ ret->d = NULL;
+ bn_check_top(ret);
+ return (ret);
+}
+
+/* This is used both by bn_expand2() and bn_dup_expand() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
+{
+ BN_ULONG *A, *a = NULL;
+ const BN_ULONG *B;
+ int i;
+
+ bn_check_top(b);
+
+ if (words > (INT_MAX / (4 * BN_BITS2))) {
+ BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
+ return NULL;
+ }
+ if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+ BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+ return (NULL);
+ }
+ a = A = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
+ if (A == NULL) {
+ BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+#ifdef PURIFY
+ /*
+ * Valgrind complains in BN_consttime_swap because we process the whole
+ * array even if it's not initialised yet. This doesn't matter in that
+ * function - what's important is constant time operation (we're not
+ * actually going to use the data)
+ */
+ memset(a, 0, sizeof(BN_ULONG) * words);
+#endif
+
+#if 1
+ B = b->d;
+ /* Check if the previous number needs to be copied */
+ if (B != NULL) {
+ for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+ /*
+ * The fact that the loop is unrolled
+ * 4-wise is a tribute to Intel. It's
+ * the one that doesn't have enough
+ * registers to accomodate more data.
+ * I'd unroll it 8-wise otherwise:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+ BN_ULONG a0, a1, a2, a3;
+ a0 = B[0];
+ a1 = B[1];
+ a2 = B[2];
+ a3 = B[3];
+ A[0] = a0;
+ A[1] = a1;
+ A[2] = a2;
+ A[3] = a3;
+ }
+ /*
+ * workaround for ultrix cc: without 'case 0', the optimizer does
+ * the switch table by doing a=top&3; a--; goto jump_table[a];
+ * which fails for top== 0
+ */
+ switch (b->top & 3) {
+ case 3:
+ A[2] = B[2];
+ case 2:
+ A[1] = B[1];
+ case 1:
+ A[0] = B[0];
+ case 0:
+ ;
+ }
+ }
+#else
+ memset(A, 0, sizeof(BN_ULONG) * words);
+ memcpy(A, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+ return (a);
+}
+
+/*
+ * This is an internal function that can be used instead of bn_expand2() when
+ * there is a need to copy BIGNUMs instead of only expanding the data part,
+ * while still expanding them. Especially useful when needing to expand
+ * BIGNUMs that are declared 'const' and should therefore not be changed. The
+ * reason to use this instead of a BN_dup() followed by a bn_expand2() is
+ * memory allocation overhead. A BN_dup() followed by a bn_expand2() will
+ * allocate new memory for the BIGNUM data twice, and free it once, while
+ * bn_dup_expand() makes sure allocation is made only once.
+ */
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
+{
+ BIGNUM *r = NULL;
+
+ bn_check_top(b);
+
+ /*
+ * This function does not work if words <= b->dmax && top < words because
+ * BN_dup() does not preserve 'dmax'! (But bn_dup_expand() is not used
+ * anywhere yet.)
+ */
+
+ if (words > b->dmax) {
+ BN_ULONG *a = bn_expand_internal(b, words);
+
+ if (a) {
+ r = BN_new();
+ if (r) {
+ r->top = b->top;
+ r->dmax = words;
+ r->neg = b->neg;
+ r->d = a;
+ } else {
+ /* r == NULL, BN_new failure */
+ OPENSSL_free(a);
+ }
+ }
+ /*
+ * If a == NULL, there was an error in allocation in
+ * bn_expand_internal(), and NULL should be returned
+ */
+ } else {
+ r = BN_dup(b);
+ }
+
+ bn_check_top(r);
+ return r;
+}
+#endif
+
+/*
+ * This is an internal function that should not be used in applications. It
+ * ensures that 'b' has enough room for a 'words' word number and initialises
+ * any unused part of b->d with leading zeros. It is mostly used by the
+ * various BIGNUM routines. If there is an error, NULL is returned. If not,
+ * 'b' is returned.
+ */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+{
+ bn_check_top(b);
+
+ if (words > b->dmax) {
+ BN_ULONG *a = bn_expand_internal(b, words);
+ if (!a)
+ return NULL;
+ if (b->d)
+ OPENSSL_free(b->d);
+ b->d = a;
+ b->dmax = words;
+ }
+
+/* None of this should be necessary because of what b->top means! */
+#if 0
+ /*
+ * NB: bn_wexpand() calls this only if the BIGNUM really has to grow
+ */
+ if (b->top < b->dmax) {
+ int i;
+ BN_ULONG *A = &(b->d[b->top]);
+ for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) {
+ A[0] = 0;
+ A[1] = 0;
+ A[2] = 0;
+ A[3] = 0;
+ A[4] = 0;
+ A[5] = 0;
+ A[6] = 0;
+ A[7] = 0;
+ }
+ for (i = (b->dmax - b->top) & 7; i > 0; i--, A++)
+ A[0] = 0;
+ assert(A == &(b->d[b->dmax]));
+ }
+#endif
+ bn_check_top(b);
+ return b;
+}
+
+BIGNUM *BN_dup(const BIGNUM *a)
+{
+ BIGNUM *t;
+
+ if (a == NULL)
+ return NULL;
+ bn_check_top(a);
+
+ t = BN_new();
+ if (t == NULL)
+ return NULL;
+ if (!BN_copy(t, a)) {
+ BN_free(t);
+ return NULL;
+ }
+ bn_check_top(t);
+ return t;
+}
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ BN_ULONG *A;
+ const BN_ULONG *B;
+
+ bn_check_top(b);
+
+ if (a == b)
+ return (a);
+ if (bn_wexpand(a, b->top) == NULL)
+ return (NULL);
+
+#if 1
+ A = a->d;
+ B = b->d;
+ for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+ BN_ULONG a0, a1, a2, a3;
+ a0 = B[0];
+ a1 = B[1];
+ a2 = B[2];
+ a3 = B[3];
+ A[0] = a0;
+ A[1] = a1;
+ A[2] = a2;
+ A[3] = a3;
+ }
+ /* ultrix cc workaround, see comments in bn_expand_internal */
+ switch (b->top & 3) {
+ case 3:
+ A[2] = B[2];
+ case 2:
+ A[1] = B[1];
+ case 1:
+ A[0] = B[0];
+ case 0:;
+ }
+#else
+ memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+ a->top = b->top;
+ a->neg = b->neg;
+ bn_check_top(a);
+ return (a);
+}
+
+void BN_swap(BIGNUM *a, BIGNUM *b)
+{
+ int flags_old_a, flags_old_b;
+ BN_ULONG *tmp_d;
+ int tmp_top, tmp_dmax, tmp_neg;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ flags_old_a = a->flags;
+ flags_old_b = b->flags;
+
+ tmp_d = a->d;
+ tmp_top = a->top;
+ tmp_dmax = a->dmax;
+ tmp_neg = a->neg;
+
+ a->d = b->d;
+ a->top = b->top;
+ a->dmax = b->dmax;
+ a->neg = b->neg;
+
+ b->d = tmp_d;
+ b->top = tmp_top;
+ b->dmax = tmp_dmax;
+ b->neg = tmp_neg;
+
+ a->flags =
+ (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
+ b->flags =
+ (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+ bn_check_top(a);
+ bn_check_top(b);
+}
+
+void BN_clear(BIGNUM *a)
+{
+ bn_check_top(a);
+ if (a->d != NULL)
+ memset(a->d, 0, a->dmax * sizeof(a->d[0]));
+ a->top = 0;
+ a->neg = 0;
+}
+
+BN_ULONG BN_get_word(const BIGNUM *a)
+{
+ if (a->top > 1)
+ return BN_MASK2;
+ else if (a->top == 1)
+ return a->d[0];
+ /* a->top == 0 */
+ return 0;
+}
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+{
+ bn_check_top(a);
+ if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
+ return (0);
+ a->neg = 0;
+ a->d[0] = w;
+ a->top = (w ? 1 : 0);
+ bn_check_top(a);
+ return (1);
+}
+
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+ unsigned int i, m;
+ unsigned int n;
+ BN_ULONG l;
+ BIGNUM *bn = NULL;
+
+ if (ret == NULL)
+ ret = bn = BN_new();
+ if (ret == NULL)
+ return (NULL);
+ bn_check_top(ret);
+ l = 0;
+ n = len;
+ if (n == 0) {
+ ret->top = 0;
+ return (ret);
+ }
+ i = ((n - 1) / BN_BYTES) + 1;
+ m = ((n - 1) % (BN_BYTES));
+ if (bn_wexpand(ret, (int)i) == NULL) {
+ if (bn)
+ BN_free(bn);
+ return NULL;
+ }
+ ret->top = i;
+ ret->neg = 0;
+ while (n--) {
+ l = (l << 8L) | *(s++);
+ if (m-- == 0) {
+ ret->d[--i] = l;
+ l = 0;
+ m = BN_BYTES - 1;
+ }
+ }
+ /*
+ * need to call this due to clear byte at top if avoiding having the top
+ * bit set (-ve number)
+ */
+ bn_correct_top(ret);
+ return (ret);
+}
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+{
+ int n, i;
+ BN_ULONG l;
+
+ bn_check_top(a);
+ n = i = BN_num_bytes(a);
+ while (i--) {
+ l = a->d[i / BN_BYTES];
+ *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
+ }
+ return (n);
+}
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ BN_ULONG t1, t2, *ap, *bp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ i = a->top - b->top;
+ if (i != 0)
+ return (i);
+ ap = a->d;
+ bp = b->d;
+ for (i = a->top - 1; i >= 0; i--) {
+ t1 = ap[i];
+ t2 = bp[i];
+ if (t1 != t2)
+ return ((t1 > t2) ? 1 : -1);
+ }
+ return (0);
+}
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ int gt, lt;
+ BN_ULONG t1, t2;
+
+ if ((a == NULL) || (b == NULL)) {
+ if (a != NULL)
+ return (-1);
+ else if (b != NULL)
+ return (1);
+ else
+ return (0);
+ }
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->neg != b->neg) {
+ if (a->neg)
+ return (-1);
+ else
+ return (1);
+ }
+ if (a->neg == 0) {
+ gt = 1;
+ lt = -1;
+ } else {
+ gt = -1;
+ lt = 1;
+ }
+
+ if (a->top > b->top)
+ return (gt);
+ if (a->top < b->top)
+ return (lt);
+ for (i = a->top - 1; i >= 0; i--) {
+ t1 = a->d[i];
+ t2 = b->d[i];
+ if (t1 > t2)
+ return (gt);
+ if (t1 < t2)
+ return (lt);
+ }
+ return (0);
+}
+
+int BN_set_bit(BIGNUM *a, int n)
+{
+ int i, j, k;
+
+ if (n < 0)
+ return 0;
+
+ i = n / BN_BITS2;
+ j = n % BN_BITS2;
+ if (a->top <= i) {
+ if (bn_wexpand(a, i + 1) == NULL)
+ return (0);
+ for (k = a->top; k < i + 1; k++)
+ a->d[k] = 0;
+ a->top = i + 1;
+ }
+
+ a->d[i] |= (((BN_ULONG)1) << j);
+ bn_check_top(a);
+ return (1);
+}
+
+int BN_clear_bit(BIGNUM *a, int n)
+{
+ int i, j;
+
+ bn_check_top(a);
+ if (n < 0)
+ return 0;
+
+ i = n / BN_BITS2;
+ j = n % BN_BITS2;
+ if (a->top <= i)
+ return (0);
+
+ a->d[i] &= (~(((BN_ULONG)1) << j));
+ bn_correct_top(a);
+ return (1);
+}
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+{
+ int i, j;
+
+ bn_check_top(a);
+ if (n < 0)
+ return 0;
+ i = n / BN_BITS2;
+ j = n % BN_BITS2;
+ if (a->top <= i)
+ return 0;
+ return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
+}
+
+int BN_mask_bits(BIGNUM *a, int n)
+{
+ int b, w;
+
+ bn_check_top(a);
+ if (n < 0)
+ return 0;
+
+ w = n / BN_BITS2;
+ b = n % BN_BITS2;
+ if (w >= a->top)
+ return 0;
+ if (b == 0)
+ a->top = w;
+ else {
+ a->top = w + 1;
+ a->d[w] &= ~(BN_MASK2 << b);
+ }
+ bn_correct_top(a);
+ return (1);
+}
+
+void BN_set_negative(BIGNUM *a, int b)
+{
+ if (b && !BN_is_zero(a))
+ a->neg = 1;
+ else
+ a->neg = 0;
+}
+
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+ int i;
+ BN_ULONG aa, bb;
+
+ aa = a[n - 1];
+ bb = b[n - 1];
+ if (aa != bb)
+ return ((aa > bb) ? 1 : -1);
+ for (i = n - 2; i >= 0; i--) {
+ aa = a[i];
+ bb = b[i];
+ if (aa != bb)
+ return ((aa > bb) ? 1 : -1);
+ }
+ return (0);
+}
+
+/*
+ * Here follows a specialised variants of bn_cmp_words(). It has the
+ * property of performing the operation on arrays of different sizes. The
+ * sizes of those arrays is expressed through cl, which is the common length
+ * ( basicall, min(len(a),len(b)) ), and dl, which is the delta between the
+ * two lengths, calculated as len(a)-len(b). All lengths are the number of
+ * BN_ULONGs...
+ */
+
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
+{
+ int n, i;
+ n = cl - 1;
+
+ if (dl < 0) {
+ for (i = dl; i < 0; i++) {
+ if (b[n - i] != 0)
+ return -1; /* a < b */
+ }
+ }
+ if (dl > 0) {
+ for (i = dl; i > 0; i--) {
+ if (a[n + i] != 0)
+ return 1; /* a > b */
+ }
+ }
+ return bn_cmp_words(a, b, cl);
+}
+
+/*
+ * Constant-time conditional swap of a and b.
+ * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+{
+ BN_ULONG t;
+ int i;
+
+ bn_wcheck_size(a, nwords);
+ bn_wcheck_size(b, nwords);
+
+ assert(a != b);
+ assert((condition & (condition - 1)) == 0);
+ assert(sizeof(BN_ULONG) >= sizeof(int));
+
+ condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+ t = (a->top ^ b->top) & condition;
+ a->top ^= t;
+ b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+ do { \
+ t = (a->d[ind] ^ b->d[ind]) & condition; \
+ a->d[ind] ^= t; \
+ b->d[ind] ^= t; \
+ } while (0)
+
+ switch (nwords) {
+ default:
+ for (i = 10; i < nwords; i++)
+ BN_CONSTTIME_SWAP(i);
+ /* Fallthrough */
+ case 10:
+ BN_CONSTTIME_SWAP(9); /* Fallthrough */
+ case 9:
+ BN_CONSTTIME_SWAP(8); /* Fallthrough */
+ case 8:
+ BN_CONSTTIME_SWAP(7); /* Fallthrough */
+ case 7:
+ BN_CONSTTIME_SWAP(6); /* Fallthrough */
+ case 6:
+ BN_CONSTTIME_SWAP(5); /* Fallthrough */
+ case 5:
+ BN_CONSTTIME_SWAP(4); /* Fallthrough */
+ case 4:
+ BN_CONSTTIME_SWAP(3); /* Fallthrough */
+ case 3:
+ BN_CONSTTIME_SWAP(2); /* Fallthrough */
+ case 2:
+ BN_CONSTTIME_SWAP(1); /* Fallthrough */
+ case 1:
+ BN_CONSTTIME_SWAP(0);
+ }
+#undef BN_CONSTTIME_SWAP
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_mod.c b/Cryptlib/OpenSSL/crypto/bn/bn_mod.c
new file mode 100644
index 00000000..ffbce890
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_mod.c
@@ -0,0 +1,316 @@
+/* crypto/bn/bn_mod.c */
+/*
+ * Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+/* 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 "cryptlib.h"
+#include "bn_lcl.h"
+
+#if 0 /* now just a #define */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+{
+ return (BN_div(NULL, rem, m, d, ctx));
+ /* note that rem->neg == m->neg (unless the remainder is zero) */
+}
+#endif
+
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+{
+ /*
+ * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d|
+ * always holds)
+ */
+
+ if (!(BN_mod(r, m, d, ctx)))
+ return 0;
+ if (!r->neg)
+ return 1;
+ /* now -|d| < r < 0, so we have to set r := r + |d| */
+ return (d->neg ? BN_sub : BN_add) (r, r, d);
+}
+
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ if (!BN_add(r, a, b))
+ return 0;
+ return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_add variant that may be used if both a and b are non-negative and
+ * less than m
+ */
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m)
+{
+ if (!BN_uadd(r, a, b))
+ return 0;
+ if (BN_ucmp(r, m) >= 0)
+ return BN_usub(r, r, m);
+ return 1;
+}
+
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ if (!BN_sub(r, a, b))
+ return 0;
+ return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_sub variant that may be used if both a and b are non-negative and
+ * less than m
+ */
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m)
+{
+ if (!BN_sub(r, a, b))
+ return 0;
+ if (r->neg)
+ return BN_add(r, r, m);
+ return 1;
+}
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ BIGNUM *t;
+ int ret = 0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(m);
+
+ BN_CTX_start(ctx);
+ if ((t = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (a == b) {
+ if (!BN_sqr(t, a, ctx))
+ goto err;
+ } else {
+ if (!BN_mul(t, a, b, ctx))
+ goto err;
+ }
+ if (!BN_nnmod(r, t, m, ctx))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+ if (!BN_sqr(r, a, ctx))
+ return 0;
+ /* r->neg == 0, thus we don't need BN_nnmod */
+ return BN_mod(r, r, m, ctx);
+}
+
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+ if (!BN_lshift1(r, a))
+ return 0;
+ bn_check_top(r);
+ return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_lshift1 variant that may be used if a is non-negative and less than
+ * m
+ */
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
+{
+ if (!BN_lshift1(r, a))
+ return 0;
+ bn_check_top(r);
+ if (BN_cmp(r, m) >= 0)
+ return BN_sub(r, r, m);
+ return 1;
+}
+
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ BIGNUM *abs_m = NULL;
+ int ret;
+
+ if (!BN_nnmod(r, a, m, ctx))
+ return 0;
+
+ if (m->neg) {
+ abs_m = BN_dup(m);
+ if (abs_m == NULL)
+ return 0;
+ abs_m->neg = 0;
+ }
+
+ ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+ bn_check_top(r);
+
+ if (abs_m)
+ BN_free(abs_m);
+ return ret;
+}
+
+/*
+ * BN_mod_lshift variant that may be used if a is non-negative and less than
+ * m
+ */
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
+{
+ if (r != a) {
+ if (BN_copy(r, a) == NULL)
+ return 0;
+ }
+
+ while (n > 0) {
+ int max_shift;
+
+ /* 0 < r < m */
+ max_shift = BN_num_bits(m) - BN_num_bits(r);
+ /* max_shift >= 0 */
+
+ if (max_shift < 0) {
+ BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
+ return 0;
+ }
+
+ if (max_shift > n)
+ max_shift = n;
+
+ if (max_shift) {
+ if (!BN_lshift(r, r, max_shift))
+ return 0;
+ n -= max_shift;
+ } else {
+ if (!BN_lshift1(r, r))
+ return 0;
+ --n;
+ }
+
+ /* BN_num_bits(r) <= BN_num_bits(m) */
+
+ if (BN_cmp(r, m) >= 0) {
+ if (!BN_sub(r, r, m))
+ return 0;
+ }
+ }
+ bn_check_top(r);
+
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_mont.c b/Cryptlib/OpenSSL/crypto/bn/bn_mont.c
new file mode 100644
index 00000000..be95bd55
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_mont.c
@@ -0,0 +1,558 @@
+/* crypto/bn/bn_mont.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-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).
+ *
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+#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)
+{
+ BIGNUM *tmp;
+ int ret = 0;
+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
+ int num = mont->N.top;
+
+ if (num > 1 && a->top == num && b->top == num) {
+ if (bn_wexpand(r, num) == NULL)
+ return (0);
+ if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
+ r->neg = a->neg ^ b->neg;
+ r->top = num;
+ bn_correct_top(r);
+ return (1);
+ }
+ }
+#endif
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
+
+ bn_check_top(tmp);
+ if (a == b) {
+ if (!BN_sqr(tmp, a, ctx))
+ goto err;
+ } else {
+ if (!BN_mul(tmp, a, b, ctx))
+ goto err;
+ }
+ /* reduce from aRR to aR */
+#ifdef MONT_WORD
+ if (!BN_from_montgomery_word(r, tmp, mont))
+ goto err;
+#else
+ if (!BN_from_montgomery(r, tmp, mont, ctx))
+ goto err;
+#endif
+ bn_check_top(r);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+{
+ BIGNUM *n;
+ BN_ULONG *ap, *np, *rp, n0, v, carry;
+ int nl, max, i;
+
+ n = &(mont->N);
+ nl = n->top;
+ if (nl == 0) {
+ ret->top = 0;
+ return (1);
+ }
+
+ max = (2 * nl); /* carry is stored separately */
+ if (bn_wexpand(r, max) == NULL)
+ return (0);
+
+ r->neg ^= n->neg;
+ np = n->d;
+ rp = r->d;
+
+ /* clear the top words of T */
+# if 1
+ for (i = r->top; i < max; i++) /* memset? XXX */
+ rp[i] = 0;
+# else
+ memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG));
+# endif
+
+ r->top = max;
+ n0 = mont->n0[0];
+
+# ifdef BN_COUNT
+ fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl);
+# endif
+ for (carry = 0, i = 0; i < nl; i++, rp++) {
+# ifdef __TANDEM
+ {
+ long long t1;
+ long long t2;
+ long long t3;
+ t1 = rp[0] * (n0 & 0177777);
+ t2 = 037777600000l;
+ t2 = n0 & t2;
+ t3 = rp[0] & 0177777;
+ t2 = (t3 * t2) & BN_MASK2;
+ t1 = t1 + t2;
+ v = bn_mul_add_words(rp, np, nl, (BN_ULONG)t1);
+ }
+# else
+ v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
+# endif
+ v = (v + carry + rp[nl]) & BN_MASK2;
+ carry |= (v != rp[nl]);
+ carry &= (v <= rp[nl]);
+ rp[nl] = v;
+ }
+
+ if (bn_wexpand(ret, nl) == NULL)
+ return (0);
+ ret->top = nl;
+ ret->neg = r->neg;
+
+ rp = ret->d;
+ ap = &(r->d[nl]);
+
+# define BRANCH_FREE 1
+# if BRANCH_FREE
+ {
+ BN_ULONG *nrp;
+ size_t m;
+
+ v = bn_sub_words(rp, ap, np, nl) - carry;
+ /*
+ * if subtraction result is real, then trick unconditional memcpy
+ * below to perform in-place "refresh" instead of actual copy.
+ */
+ m = (0 - (size_t)v);
+ nrp =
+ (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
+
+ for (i = 0, nl -= 4; i < nl; i += 4) {
+ BN_ULONG t1, t2, t3, t4;
+
+ t1 = nrp[i + 0];
+ t2 = nrp[i + 1];
+ t3 = nrp[i + 2];
+ ap[i + 0] = 0;
+ t4 = nrp[i + 3];
+ ap[i + 1] = 0;
+ rp[i + 0] = t1;
+ ap[i + 2] = 0;
+ rp[i + 1] = t2;
+ ap[i + 3] = 0;
+ rp[i + 2] = t3;
+ rp[i + 3] = t4;
+ }
+ for (nl += 4; i < nl; i++)
+ rp[i] = nrp[i], ap[i] = 0;
+ }
+# else
+ if (bn_sub_words(rp, ap, np, nl) - carry)
+ memcpy(rp, ap, nl * sizeof(BN_ULONG));
+# endif
+ bn_correct_top(r);
+ bn_correct_top(ret);
+ 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);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL)
+ goto err;
+
+ if (!BN_copy(t1, a))
+ goto err;
+ BN_mask_bits(t1, mont->ri);
+
+ if (!BN_mul(t2, t1, &mont->Ni, ctx))
+ goto err;
+ BN_mask_bits(t2, mont->ri);
+
+ 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;
+
+ if (BN_ucmp(ret, &(mont->N)) >= 0) {
+ if (!BN_usub(ret, ret, &(mont->N)))
+ goto err;
+ }
+ retn = 1;
+ bn_check_top(ret);
+ err:
+ BN_CTX_end(ctx);
+#endif /* MONT_WORD */
+ return (retn);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+{
+ BN_MONT_CTX *ret;
+
+ if ((ret = (BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
+ return (NULL);
+
+ BN_MONT_CTX_init(ret);
+ ret->flags = BN_FLG_MALLOCED;
+ return (ret);
+}
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+{
+ ctx->ri = 0;
+ BN_init(&(ctx->RR));
+ BN_init(&(ctx->N));
+ BN_init(&(ctx->Ni));
+ ctx->n0[0] = ctx->n0[1] = 0;
+ ctx->flags = 0;
+}
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+{
+ if (mont == NULL)
+ return;
+
+ BN_clear_free(&(mont->RR));
+ BN_clear_free(&(mont->N));
+ BN_clear_free(&(mont->Ni));
+ if (mont->flags & BN_FLG_MALLOCED)
+ OPENSSL_free(mont);
+}
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *Ri, *R;
+
+ if (BN_is_zero(mod))
+ return 0;
+
+ BN_CTX_start(ctx);
+ if ((Ri = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ R = &(mont->RR); /* grab RR as a temp */
+ if (!BN_copy(&(mont->N), mod))
+ goto err; /* Set N */
+ mont->N.neg = 0;
+
+#ifdef MONT_WORD
+ {
+ BIGNUM tmod;
+ BN_ULONG buf[2];
+
+ BN_init(&tmod);
+ tmod.d = buf;
+ tmod.dmax = 2;
+ tmod.neg = 0;
+
+ 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;
+
+ if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+ goto err;
+ if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
+ goto err; /* R*Ri */
+ if (!BN_is_zero(Ri)) {
+ if (!BN_sub_word(Ri, 1))
+ goto err;
+ } else { /* if N mod word size == 1 */
+
+ if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
+ goto err;
+ /* Ri-- (mod double word size) */
+ Ri->neg = 0;
+ Ri->d[0] = BN_MASK2;
+ Ri->d[1] = BN_MASK2;
+ Ri->top = 2;
+ }
+ if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+ goto err;
+ /*
+ * Ni = (R*Ri-1)/N, keep only couple of least significant words:
+ */
+ 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;
+ if (!BN_lshift(Ri, Ri, BN_BITS2))
+ goto err; /* R*Ri */
+ if (!BN_is_zero(Ri)) {
+ if (!BN_sub_word(Ri, 1))
+ goto err;
+ } else { /* if N mod word size == 1 */
+
+ if (!BN_set_word(Ri, BN_MASK2))
+ goto err; /* Ri-- (mod word size) */
+ }
+ if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+ goto err;
+ /*
+ * Ni = (R*Ri-1)/N, keep only least significant word:
+ */
+ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+ mont->n0[1] = 0;
+# endif
+ }
+#else /* !MONT_WORD */
+ { /* bignum version */
+ mont->ri = BN_num_bits(&mont->N);
+ BN_zero(R);
+ if (!BN_set_bit(R, mont->ri))
+ goto err; /* R = 2^ri */
+ /* Ri = R^-1 mod N */
+ if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL)
+ goto err;
+ if (!BN_lshift(Ri, Ri, mont->ri))
+ goto err; /* R*Ri */
+ if (!BN_sub_word(Ri, 1))
+ goto err;
+ /*
+ * Ni = (R*Ri-1) / N
+ */
+ if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx))
+ goto err;
+ }
+#endif
+
+ /* setup RR for conversions */
+ BN_zero(&(mont->RR));
+ if (!BN_set_bit(&(mont->RR), mont->ri * 2))
+ goto err;
+ if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
+ goto err;
+
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+{
+ if (to == from)
+ return (to);
+
+ if (!BN_copy(&(to->RR), &(from->RR)))
+ return NULL;
+ if (!BN_copy(&(to->N), &(from->N)))
+ return NULL;
+ if (!BN_copy(&(to->Ni), &(from->Ni)))
+ return NULL;
+ to->ri = from->ri;
+ to->n0[0] = from->n0[0];
+ to->n0[1] = from->n0[1];
+ return (to);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+ const BIGNUM *mod, BN_CTX *ctx)
+{
+ BN_MONT_CTX *ret;
+
+ CRYPTO_r_lock(lock);
+ ret = *pmont;
+ CRYPTO_r_unlock(lock);
+ if (ret)
+ return ret;
+
+ /*
+ * We don't want to serialise globally while doing our lazy-init math in
+ * BN_MONT_CTX_set. That punishes threads that are doing independent
+ * things. Instead, punish the case where more than one thread tries to
+ * lazy-init the same 'pmont', by having each do the lazy-init math work
+ * independently and only use the one from the thread that wins the race
+ * (the losers throw away the work they've done).
+ */
+ ret = BN_MONT_CTX_new();
+ if (!ret)
+ return NULL;
+ if (!BN_MONT_CTX_set(ret, mod, ctx)) {
+ BN_MONT_CTX_free(ret);
+ return NULL;
+ }
+
+ /* The locked compare-and-set, after the local work is done. */
+ CRYPTO_w_lock(lock);
+ if (*pmont) {
+ BN_MONT_CTX_free(ret);
+ ret = *pmont;
+ } else
+ *pmont = ret;
+ CRYPTO_w_unlock(lock);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_mpi.c b/Cryptlib/OpenSSL/crypto/bn/bn_mpi.c
new file mode 100644
index 00000000..3bd40bbd
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_mpi.c
@@ -0,0 +1,128 @@
+/* crypto/bn/bn_mpi.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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
+{
+ int bits;
+ int num = 0;
+ int ext = 0;
+ long l;
+
+ bits = BN_num_bits(a);
+ num = (bits + 7) / 8;
+ if (bits > 0) {
+ ext = ((bits & 0x07) == 0);
+ }
+ if (d == NULL)
+ return (num + 4 + ext);
+
+ l = num + ext;
+ d[0] = (unsigned char)(l >> 24) & 0xff;
+ d[1] = (unsigned char)(l >> 16) & 0xff;
+ d[2] = (unsigned char)(l >> 8) & 0xff;
+ d[3] = (unsigned char)(l) & 0xff;
+ if (ext)
+ d[4] = 0;
+ num = BN_bn2bin(a, &(d[4 + ext]));
+ if (a->neg)
+ d[4] |= 0x80;
+ return (num + 4 + ext);
+}
+
+BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
+{
+ long len;
+ int neg = 0;
+
+ if (n < 4) {
+ BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
+ return (NULL);
+ }
+ len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int)
+ d[3];
+ if ((len + 4) != n) {
+ BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR);
+ return (NULL);
+ }
+
+ if (a == NULL)
+ a = BN_new();
+ if (a == NULL)
+ return (NULL);
+
+ if (len == 0) {
+ a->neg = 0;
+ a->top = 0;
+ return (a);
+ }
+ d += 4;
+ if ((*d) & 0x80)
+ neg = 1;
+ if (BN_bin2bn(d, (int)len, a) == NULL)
+ return (NULL);
+ a->neg = neg;
+ if (neg) {
+ BN_clear_bit(a, BN_num_bits(a) - 1);
+ }
+ bn_check_top(a);
+ return (a);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_mul.c b/Cryptlib/OpenSSL/crypto/bn/bn_mul.c
new file mode 100644
index 00000000..b174850b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_mul.c
@@ -0,0 +1,1164 @@
+/* crypto/bn/bn_mul.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 <stdio.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
+/*
+ * Here follows specialised variants of bn_add_words() and bn_sub_words().
+ * They have the property performing operations on arrays of different sizes.
+ * The sizes of those arrays is expressed through cl, which is the common
+ * length ( basicall, min(len(a),len(b)) ), and dl, which is the delta
+ * between the two lengths, calculated as len(a)-len(b). All lengths are the
+ * number of BN_ULONGs... For the operations that require a result array as
+ * parameter, it must have the length cl+abs(dl). These functions should
+ * probably end up in bn_asm.c as soon as there are assembler counterparts
+ * for the systems that use assembler files.
+ */
+
+BN_ULONG bn_sub_part_words(BN_ULONG *r,
+ const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl)
+{
+ BN_ULONG c, t;
+
+ assert(cl >= 0);
+ c = bn_sub_words(r, a, b, cl);
+
+ if (dl == 0)
+ return c;
+
+ r += cl;
+ a += cl;
+ b += cl;
+
+ if (dl < 0) {
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl,
+ dl, c);
+# endif
+ for (;;) {
+ t = b[0];
+ r[0] = (0 - t - c) & BN_MASK2;
+ if (t != 0)
+ c = 1;
+ if (++dl >= 0)
+ break;
+
+ t = b[1];
+ r[1] = (0 - t - c) & BN_MASK2;
+ if (t != 0)
+ c = 1;
+ if (++dl >= 0)
+ break;
+
+ t = b[2];
+ r[2] = (0 - t - c) & BN_MASK2;
+ if (t != 0)
+ c = 1;
+ if (++dl >= 0)
+ break;
+
+ t = b[3];
+ r[3] = (0 - t - c) & BN_MASK2;
+ if (t != 0)
+ c = 1;
+ if (++dl >= 0)
+ break;
+
+ b += 4;
+ r += 4;
+ }
+ } else {
+ int save_dl = dl;
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl,
+ dl, c);
+# endif
+ while (c) {
+ t = a[0];
+ r[0] = (t - c) & BN_MASK2;
+ if (t != 0)
+ c = 0;
+ if (--dl <= 0)
+ break;
+
+ t = a[1];
+ r[1] = (t - c) & BN_MASK2;
+ if (t != 0)
+ c = 0;
+ if (--dl <= 0)
+ break;
+
+ t = a[2];
+ r[2] = (t - c) & BN_MASK2;
+ if (t != 0)
+ c = 0;
+ if (--dl <= 0)
+ break;
+
+ t = a[3];
+ r[3] = (t - c) & BN_MASK2;
+ if (t != 0)
+ c = 0;
+ if (--dl <= 0)
+ break;
+
+ save_dl = dl;
+ a += 4;
+ r += 4;
+ }
+ if (dl > 0) {
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n",
+ cl, dl);
+# endif
+ if (save_dl > dl) {
+ switch (save_dl - dl) {
+ case 1:
+ r[1] = a[1];
+ if (--dl <= 0)
+ break;
+ case 2:
+ r[2] = a[2];
+ if (--dl <= 0)
+ break;
+ case 3:
+ r[3] = a[3];
+ if (--dl <= 0)
+ break;
+ }
+ a += 4;
+ r += 4;
+ }
+ }
+ if (dl > 0) {
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n",
+ cl, dl);
+# endif
+ for (;;) {
+ r[0] = a[0];
+ if (--dl <= 0)
+ break;
+ r[1] = a[1];
+ if (--dl <= 0)
+ break;
+ r[2] = a[2];
+ if (--dl <= 0)
+ break;
+ r[3] = a[3];
+ if (--dl <= 0)
+ break;
+
+ a += 4;
+ r += 4;
+ }
+ }
+ }
+ return c;
+}
+#endif
+
+BN_ULONG bn_add_part_words(BN_ULONG *r,
+ const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl)
+{
+ BN_ULONG c, l, t;
+
+ assert(cl >= 0);
+ c = bn_add_words(r, a, b, cl);
+
+ if (dl == 0)
+ return c;
+
+ r += cl;
+ a += cl;
+ b += cl;
+
+ if (dl < 0) {
+ int save_dl = dl;
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl,
+ dl, c);
+#endif
+ while (c) {
+ l = (c + b[0]) & BN_MASK2;
+ c = (l < c);
+ r[0] = l;
+ if (++dl >= 0)
+ break;
+
+ l = (c + b[1]) & BN_MASK2;
+ c = (l < c);
+ r[1] = l;
+ if (++dl >= 0)
+ break;
+
+ l = (c + b[2]) & BN_MASK2;
+ c = (l < c);
+ r[2] = l;
+ if (++dl >= 0)
+ break;
+
+ l = (c + b[3]) & BN_MASK2;
+ c = (l < c);
+ r[3] = l;
+ if (++dl >= 0)
+ break;
+
+ save_dl = dl;
+ b += 4;
+ r += 4;
+ }
+ if (dl < 0) {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n",
+ cl, dl);
+#endif
+ if (save_dl < dl) {
+ switch (dl - save_dl) {
+ case 1:
+ r[1] = b[1];
+ if (++dl >= 0)
+ break;
+ case 2:
+ r[2] = b[2];
+ if (++dl >= 0)
+ break;
+ case 3:
+ r[3] = b[3];
+ if (++dl >= 0)
+ break;
+ }
+ b += 4;
+ r += 4;
+ }
+ }
+ if (dl < 0) {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n",
+ cl, dl);
+#endif
+ for (;;) {
+ r[0] = b[0];
+ if (++dl >= 0)
+ break;
+ r[1] = b[1];
+ if (++dl >= 0)
+ break;
+ r[2] = b[2];
+ if (++dl >= 0)
+ break;
+ r[3] = b[3];
+ if (++dl >= 0)
+ break;
+
+ b += 4;
+ r += 4;
+ }
+ }
+ } else {
+ int save_dl = dl;
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
+#endif
+ while (c) {
+ t = (a[0] + c) & BN_MASK2;
+ c = (t < c);
+ r[0] = t;
+ if (--dl <= 0)
+ break;
+
+ t = (a[1] + c) & BN_MASK2;
+ c = (t < c);
+ r[1] = t;
+ if (--dl <= 0)
+ break;
+
+ t = (a[2] + c) & BN_MASK2;
+ c = (t < c);
+ r[2] = t;
+ if (--dl <= 0)
+ break;
+
+ t = (a[3] + c) & BN_MASK2;
+ c = (t < c);
+ r[3] = t;
+ if (--dl <= 0)
+ break;
+
+ save_dl = dl;
+ a += 4;
+ r += 4;
+ }
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl,
+ dl);
+#endif
+ if (dl > 0) {
+ if (save_dl > dl) {
+ switch (save_dl - dl) {
+ case 1:
+ r[1] = a[1];
+ if (--dl <= 0)
+ break;
+ case 2:
+ r[2] = a[2];
+ if (--dl <= 0)
+ break;
+ case 3:
+ r[3] = a[3];
+ if (--dl <= 0)
+ break;
+ }
+ a += 4;
+ r += 4;
+ }
+ }
+ if (dl > 0) {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n",
+ cl, dl);
+#endif
+ for (;;) {
+ r[0] = a[0];
+ if (--dl <= 0)
+ break;
+ r[1] = a[1];
+ if (--dl <= 0)
+ break;
+ r[2] = a[2];
+ if (--dl <= 0)
+ break;
+ r[3] = a[3];
+ if (--dl <= 0)
+ break;
+
+ a += 4;
+ r += 4;
+ }
+ }
+ }
+ return c;
+}
+
+#ifdef BN_RECURSION
+/*
+ * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of
+ * Computer Programming, Vol. 2)
+ */
+
+/*-
+ * r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+/* dnX may not be positive, but n2/2+dnX has to be */
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ int dna, int dnb, BN_ULONG *t)
+{
+ int n = n2 / 2, c1, c2;
+ int tna = n + dna, tnb = n + dnb;
+ unsigned int neg, zero;
+ BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n", n2, dna, n2, dnb);
+# endif
+# ifdef BN_MUL_COMBA
+# if 0
+ if (n2 == 4) {
+ bn_mul_comba4(r, a, b);
+ return;
+ }
+# endif
+ /*
+ * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete
+ * [steve]
+ */
+ if (n2 == 8 && dna == 0 && dnb == 0) {
+ bn_mul_comba8(r, a, b);
+ return;
+ }
+# endif /* BN_MUL_COMBA */
+ /* Else do normal multiply */
+ if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+ bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
+ if ((dna + dnb) < 0)
+ memset(&r[2 * n2 + dna + dnb], 0,
+ sizeof(BN_ULONG) * -(dna + dnb));
+ return;
+ }
+ /* r=(a[0]-a[1])*(b[1]-b[0]) */
+ c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+ c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
+ zero = neg = 0;
+ switch (c1 * 3 + c2) {
+ case -4:
+ bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+ bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+ break;
+ case -3:
+ zero = 1;
+ break;
+ case -2:
+ bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+ bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
+ neg = 1;
+ break;
+ case -1:
+ case 0:
+ case 1:
+ zero = 1;
+ break;
+ case 2:
+ bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
+ bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+ neg = 1;
+ break;
+ case 3:
+ zero = 1;
+ break;
+ case 4:
+ bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
+ bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
+ break;
+ }
+
+# ifdef BN_MUL_COMBA
+ if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take
+ * extra args to do this well */
+ if (!zero)
+ bn_mul_comba4(&(t[n2]), t, &(t[n]));
+ else
+ memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
+
+ bn_mul_comba4(r, a, b);
+ bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
+ } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could
+ * take extra args to do
+ * this well */
+ if (!zero)
+ bn_mul_comba8(&(t[n2]), t, &(t[n]));
+ else
+ memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
+
+ bn_mul_comba8(r, a, b);
+ bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
+ } else
+# endif /* BN_MUL_COMBA */
+ {
+ p = &(t[n2 * 2]);
+ if (!zero)
+ bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
+ else
+ memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
+ bn_mul_recursive(r, a, b, n, 0, 0, p);
+ bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+ if (neg) { /* if t[32] is negative */
+ c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+ } else {
+ /* Might have a carry */
+ c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ * c1 holds the carry bits
+ */
+ c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+ if (c1) {
+ p = &(r[n + n2]);
+ lo = *p;
+ ln = (lo + c1) & BN_MASK2;
+ *p = ln;
+
+ /*
+ * The overflow will stop before we over write words we should not
+ * overwrite
+ */
+ if (ln < (BN_ULONG)c1) {
+ do {
+ p++;
+ lo = *p;
+ ln = (lo + 1) & BN_MASK2;
+ *p = ln;
+ } while (ln == 0);
+ }
+ }
+}
+
+/*
+ * n+tn is the word length t needs to be n*4 is size, as does r
+ */
+/* tnX may not be negative but less than n */
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
+ int tna, int tnb, BN_ULONG *t)
+{
+ int i, j, n2 = n * 2;
+ int c1, c2, neg;
+ BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
+ n, tna, n, tnb);
+# endif
+ if (n < 8) {
+ bn_mul_normal(r, a, n + tna, b, n + tnb);
+ return;
+ }
+
+ /* r=(a[0]-a[1])*(b[1]-b[0]) */
+ c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+ c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
+ neg = 0;
+ switch (c1 * 3 + c2) {
+ case -4:
+ bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+ bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+ break;
+ case -3:
+ /* break; */
+ case -2:
+ bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+ bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
+ neg = 1;
+ break;
+ case -1:
+ case 0:
+ case 1:
+ /* break; */
+ case 2:
+ bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
+ bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+ neg = 1;
+ break;
+ case 3:
+ /* break; */
+ case 4:
+ bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
+ bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
+ break;
+ }
+ /*
+ * The zero case isn't yet implemented here. The speedup would probably
+ * be negligible.
+ */
+# if 0
+ if (n == 4) {
+ bn_mul_comba4(&(t[n2]), t, &(t[n]));
+ bn_mul_comba4(r, a, b);
+ bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
+ memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2));
+ } else
+# endif
+ if (n == 8) {
+ bn_mul_comba8(&(t[n2]), t, &(t[n]));
+ bn_mul_comba8(r, a, b);
+ bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
+ memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb));
+ } else {
+ p = &(t[n2 * 2]);
+ bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
+ bn_mul_recursive(r, a, b, n, 0, 0, p);
+ i = n / 2;
+ /*
+ * If there is only a bottom half to the number, just do it
+ */
+ if (tna > tnb)
+ j = tna - i;
+ else
+ j = tnb - i;
+ if (j == 0) {
+ bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
+ i, tna - i, tnb - i, p);
+ memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2));
+ } else if (j > 0) { /* eg, n == 16, i == 8 and tn == 11 */
+ bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
+ i, tna - i, tnb - i, p);
+ memset(&(r[n2 + tna + tnb]), 0,
+ sizeof(BN_ULONG) * (n2 - tna - tnb));
+ } else { /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
+
+ memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
+ if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
+ && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+ bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
+ } else {
+ for (;;) {
+ i /= 2;
+ /*
+ * these simplified conditions work exclusively because
+ * difference between tna and tnb is 1 or 0
+ */
+ if (i < tna || i < tnb) {
+ bn_mul_part_recursive(&(r[n2]),
+ &(a[n]), &(b[n]),
+ i, tna - i, tnb - i, p);
+ break;
+ } else if (i == tna || i == tnb) {
+ bn_mul_recursive(&(r[n2]),
+ &(a[n]), &(b[n]),
+ i, tna - i, tnb - i, p);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+ if (neg) { /* if t[32] is negative */
+ c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+ } else {
+ /* Might have a carry */
+ c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ * c1 holds the carry bits
+ */
+ c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+ if (c1) {
+ p = &(r[n + n2]);
+ lo = *p;
+ ln = (lo + c1) & BN_MASK2;
+ *p = ln;
+
+ /*
+ * The overflow will stop before we over write words we should not
+ * overwrite
+ */
+ if (ln < (BN_ULONG)c1) {
+ do {
+ p++;
+ lo = *p;
+ ln = (lo + 1) & BN_MASK2;
+ *p = ln;
+ } while (ln == 0);
+ }
+ }
+}
+
+/*-
+ * a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ BN_ULONG *t)
+{
+ int n = n2 / 2;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_low_recursive %d * %d\n", n2, n2);
+# endif
+
+ bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
+ if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
+ bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
+ bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+ bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
+ bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+ } else {
+ bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
+ bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
+ bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+ bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
+ }
+}
+
+/*-
+ * a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+ BN_ULONG *t)
+{
+ int i, n;
+ int c1, c2;
+ int neg, oneg, zero;
+ BN_ULONG ll, lc, *lp, *mp;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_high %d * %d\n", n2, n2);
+# endif
+ n = n2 / 2;
+
+ /* Calculate (al-ah)*(bh-bl) */
+ neg = zero = 0;
+ c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
+ c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
+ switch (c1 * 3 + c2) {
+ case -4:
+ bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+ bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+ break;
+ case -3:
+ zero = 1;
+ break;
+ case -2:
+ bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+ bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+ neg = 1;
+ break;
+ case -1:
+ case 0:
+ case 1:
+ zero = 1;
+ break;
+ case 2:
+ bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+ bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+ neg = 1;
+ break;
+ case 3:
+ zero = 1;
+ break;
+ case 4:
+ bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+ bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+ break;
+ }
+
+ oneg = neg;
+ /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+ /* r[10] = (a[1]*b[1]) */
+# ifdef BN_MUL_COMBA
+ if (n == 8) {
+ bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
+ bn_mul_comba8(r, &(a[n]), &(b[n]));
+ } else
+# endif
+ {
+ bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2]));
+ bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2]));
+ }
+
+ /*-
+ * s0 == low(al*bl)
+ * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+ * We know s0 and s1 so the only unknown is high(al*bl)
+ * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+ * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+ */
+ if (l != NULL) {
+ lp = &(t[n2 + n]);
+ c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n));
+ } else {
+ c1 = 0;
+ lp = &(r[0]);
+ }
+
+ if (neg)
+ neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
+ else {
+ bn_add_words(&(t[n2]), lp, &(t[0]), n);
+ neg = 0;
+ }
+
+ if (l != NULL) {
+ bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
+ } else {
+ lp = &(t[n2 + n]);
+ mp = &(t[n2]);
+ for (i = 0; i < n; i++)
+ lp[i] = ((~mp[i]) + 1) & BN_MASK2;
+ }
+
+ /*-
+ * s[0] = low(al*bl)
+ * t[3] = high(al*bl)
+ * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+ * r[10] = (a[1]*b[1])
+ */
+ /*-
+ * R[10] = al*bl
+ * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+ * R[32] = ah*bh
+ */
+ /*-
+ * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+ * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+ * R[3]=r[1]+(carry/borrow)
+ */
+ if (l != NULL) {
+ lp = &(t[n2]);
+ c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n));
+ } else {
+ lp = &(t[n2 + n]);
+ c1 = 0;
+ }
+ c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n));
+ if (oneg)
+ c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+ else
+ c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+
+ c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n));
+ c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n));
+ if (oneg)
+ c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n));
+ else
+ c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n));
+
+ if (c1 != 0) { /* Add starting at r[0], could be +ve or -ve */
+ i = 0;
+ if (c1 > 0) {
+ lc = c1;
+ do {
+ ll = (r[i] + lc) & BN_MASK2;
+ r[i++] = ll;
+ lc = (lc > ll);
+ } while (lc);
+ } else {
+ lc = -c1;
+ do {
+ ll = r[i];
+ r[i++] = (ll - lc) & BN_MASK2;
+ lc = (lc > ll);
+ } while (lc);
+ }
+ }
+ if (c2 != 0) { /* Add starting at r[1] */
+ i = n;
+ if (c2 > 0) {
+ lc = c2;
+ do {
+ ll = (r[i] + lc) & BN_MASK2;
+ r[i++] = ll;
+ lc = (lc > ll);
+ } while (lc);
+ } else {
+ lc = -c2;
+ do {
+ ll = r[i];
+ r[i++] = (ll - lc) & BN_MASK2;
+ lc = (lc > ll);
+ } while (lc);
+ }
+ }
+}
+#endif /* BN_RECURSION */
+
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+ int ret = 0;
+ int top, al, bl;
+ BIGNUM *rr;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ int i;
+#endif
+#ifdef BN_RECURSION
+ BIGNUM *t = NULL;
+ int j = 0, k;
+#endif
+
+#ifdef BN_COUNT
+ fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top);
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(r);
+
+ al = a->top;
+ bl = b->top;
+
+ if ((al == 0) || (bl == 0)) {
+ BN_zero(r);
+ return (1);
+ }
+ top = al + bl;
+
+ BN_CTX_start(ctx);
+ if ((r == a) || (r == b)) {
+ if ((rr = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ } else
+ rr = r;
+ rr->neg = a->neg ^ b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ i = al - bl;
+#endif
+#ifdef BN_MUL_COMBA
+ if (i == 0) {
+# if 0
+ if (al == 4) {
+ if (bn_wexpand(rr, 8) == NULL)
+ goto err;
+ rr->top = 8;
+ bn_mul_comba4(rr->d, a->d, b->d);
+ goto end;
+ }
+# endif
+ if (al == 8) {
+ if (bn_wexpand(rr, 16) == NULL)
+ goto err;
+ rr->top = 16;
+ bn_mul_comba8(rr->d, a->d, b->d);
+ goto end;
+ }
+ }
+#endif /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+ if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
+ if (i >= -1 && i <= 1) {
+ /*
+ * Find out the power of two lower or equal to the longest of the
+ * two numbers
+ */
+ if (i >= 0) {
+ j = BN_num_bits_word((BN_ULONG)al);
+ }
+ if (i == -1) {
+ j = BN_num_bits_word((BN_ULONG)bl);
+ }
+ j = 1 << (j - 1);
+ assert(j <= al || j <= bl);
+ k = j + j;
+ t = BN_CTX_get(ctx);
+ if (t == NULL)
+ goto err;
+ if (al > j || bl > j) {
+ if (bn_wexpand(t, k * 4) == NULL)
+ goto err;
+ if (bn_wexpand(rr, k * 4) == NULL)
+ goto err;
+ bn_mul_part_recursive(rr->d, a->d, b->d,
+ j, al - j, bl - j, t->d);
+ } else { /* al <= j || bl <= j */
+
+ if (bn_wexpand(t, k * 2) == NULL)
+ goto err;
+ if (bn_wexpand(rr, k * 2) == NULL)
+ goto err;
+ bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
+ }
+ rr->top = top;
+ goto end;
+ }
+# if 0
+ if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+ BIGNUM *tmp_bn = (BIGNUM *)b;
+ if (bn_wexpand(tmp_bn, al) == NULL)
+ goto err;
+ tmp_bn->d[bl] = 0;
+ bl++;
+ i--;
+ } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
+ BIGNUM *tmp_bn = (BIGNUM *)a;
+ if (bn_wexpand(tmp_bn, bl) == NULL)
+ goto err;
+ tmp_bn->d[al] = 0;
+ al++;
+ i++;
+ }
+ if (i == 0) {
+ /* symmetric and > 4 */
+ /* 16 or larger */
+ j = BN_num_bits_word((BN_ULONG)al);
+ j = 1 << (j - 1);
+ k = j + j;
+ t = BN_CTX_get(ctx);
+ if (al == j) { /* exact multiple */
+ if (bn_wexpand(t, k * 2) == NULL)
+ goto err;
+ if (bn_wexpand(rr, k * 2) == NULL)
+ goto err;
+ bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
+ } else {
+ if (bn_wexpand(t, k * 4) == NULL)
+ goto err;
+ if (bn_wexpand(rr, k * 4) == NULL)
+ goto err;
+ bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d);
+ }
+ rr->top = top;
+ goto end;
+ }
+# endif
+ }
+#endif /* BN_RECURSION */
+ if (bn_wexpand(rr, top) == NULL)
+ goto err;
+ rr->top = top;
+ bn_mul_normal(rr->d, a->d, al, b->d, bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ end:
+#endif
+ bn_correct_top(rr);
+ if (r != rr)
+ BN_copy(r, rr);
+ ret = 1;
+ err:
+ bn_check_top(r);
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+{
+ BN_ULONG *rr;
+
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb);
+#endif
+
+ if (na < nb) {
+ int itmp;
+ BN_ULONG *ltmp;
+
+ itmp = na;
+ na = nb;
+ nb = itmp;
+ ltmp = a;
+ a = b;
+ b = ltmp;
+
+ }
+ rr = &(r[na]);
+ if (nb <= 0) {
+ (void)bn_mul_words(r, a, na, 0);
+ return;
+ } else
+ rr[0] = bn_mul_words(r, a, na, b[0]);
+
+ for (;;) {
+ if (--nb <= 0)
+ return;
+ rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
+ if (--nb <= 0)
+ return;
+ rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
+ if (--nb <= 0)
+ return;
+ rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
+ if (--nb <= 0)
+ return;
+ rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
+ rr += 4;
+ r += 4;
+ b += 4;
+ }
+}
+
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+{
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n);
+#endif
+ bn_mul_words(r, a, n, b[0]);
+
+ for (;;) {
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[1]), a, n, b[1]);
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[2]), a, n, b[2]);
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[3]), a, n, b[3]);
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[4]), a, n, b[4]);
+ r += 4;
+ b += 4;
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_nist.c b/Cryptlib/OpenSSL/crypto/bn/bn_nist.c
new file mode 100644
index 00000000..4a45404c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_nist.c
@@ -0,0 +1,1262 @@
+/* crypto/bn/bn_nist.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).
+ *
+ */
+
+#include "bn_lcl.h"
+#include "cryptlib.h"
+
+#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
+
+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
+#if BN_BITS2 == 64
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+ {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
+};
+
+static const BN_ULONG _nist_p_192_sqr[] = {
+ 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
+ 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+ {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL},
+ {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is
+ * "carry-full" */
+};
+
+static const BN_ULONG _nist_p_224_sqr[] = {
+ 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
+ 0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+ 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+ {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL},
+ {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFE00000002ULL},
+ {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFD00000003ULL},
+ {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFC00000004ULL},
+ {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFB00000005ULL},
+};
+
+static const BN_ULONG _nist_p_256_sqr[] = {
+ 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
+ 0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
+ 0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
+};
+
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+ {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+};
+
+static const BN_ULONG _nist_p_384_sqr[] = {
+ 0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
+ 0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
+ 0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_521[] =
+ { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0x00000000000001FFULL
+};
+
+static const BN_ULONG _nist_p_521_sqr[] = {
+ 0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
+};
+#elif BN_BITS2 == 32
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+ {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
+};
+
+static const BN_ULONG _nist_p_192_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+ {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
+};
+
+static const BN_ULONG _nist_p_224_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+ {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
+ {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
+ {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
+ {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
+ 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
+ {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
+ 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
+};
+
+static const BN_ULONG _nist_p_256_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
+ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
+ 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
+};
+
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+ {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+};
+
+static const BN_ULONG _nist_p_384_sqr[] = {
+ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x000001FF
+};
+
+static const BN_ULONG _nist_p_521_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
+};
+#else
+# error "unsupported BN_BITS2"
+#endif
+
+static const BIGNUM _bignum_nist_p_192 = {
+ (BN_ULONG *)_nist_p_192[0],
+ BN_NIST_192_TOP,
+ BN_NIST_192_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_224 = {
+ (BN_ULONG *)_nist_p_224[0],
+ BN_NIST_224_TOP,
+ BN_NIST_224_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_256 = {
+ (BN_ULONG *)_nist_p_256[0],
+ BN_NIST_256_TOP,
+ BN_NIST_256_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_384 = {
+ (BN_ULONG *)_nist_p_384[0],
+ BN_NIST_384_TOP,
+ BN_NIST_384_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_521 = {
+ (BN_ULONG *)_nist_p_521,
+ BN_NIST_521_TOP,
+ BN_NIST_521_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+const BIGNUM *BN_get0_nist_prime_192(void)
+{
+ return &_bignum_nist_p_192;
+}
+
+const BIGNUM *BN_get0_nist_prime_224(void)
+{
+ return &_bignum_nist_p_224;
+}
+
+const BIGNUM *BN_get0_nist_prime_256(void)
+{
+ return &_bignum_nist_p_256;
+}
+
+const BIGNUM *BN_get0_nist_prime_384(void)
+{
+ return &_bignum_nist_p_384;
+}
+
+const BIGNUM *BN_get0_nist_prime_521(void)
+{
+ return &_bignum_nist_p_521;
+}
+
+static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
+{
+ int i;
+
+#ifdef BN_DEBUG
+ OPENSSL_assert(top <= max);
+#endif
+ for (i = 0; i < top; i++)
+ dst[i] = src[i];
+ for (; i < max; i++)
+ dst[i] = 0;
+}
+
+static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
+{
+ int i;
+
+ for (i = 0; i < top; i++)
+ dst[i] = src[i];
+}
+
+#if BN_BITS2 == 64
+# define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
+# define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0;
+/*
+ * two following macros are implemented under assumption that they
+ * are called in a sequence with *ascending* n, i.e. as they are...
+ */
+# define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
+ :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
+# define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
+# define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
+# if defined(L_ENDIAN)
+# if defined(__arch64__)
+# define NIST_INT64 long
+# else
+# define NIST_INT64 long long
+# endif
+# endif
+#else
+# define bn_cp_64(to, n, from, m) \
+ { \
+ bn_cp_32(to, (n)*2, from, (m)*2); \
+ bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
+ }
+# define bn_64_set_0(to, n) \
+ { \
+ bn_32_set_0(to, (n)*2); \
+ bn_32_set_0(to, (n)*2+1); \
+ }
+# define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
+# define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
+# if defined(_WIN32) && !defined(__GNUC__)
+# define NIST_INT64 __int64
+# elif defined(BN_LLONG)
+# define NIST_INT64 long long
+# endif
+#endif /* BN_BITS2 != 64 */
+
+#define nist_set_192(to, from, a1, a2, a3) \
+ { \
+ bn_cp_64(to, 0, from, (a3) - 3) \
+ bn_cp_64(to, 1, from, (a2) - 3) \
+ bn_cp_64(to, 2, from, (a1) - 3) \
+ }
+
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int top = a->top, i;
+ int carry;
+ register BN_ULONG *r_d, *a_d = a->d;
+ union {
+ BN_ULONG bn[BN_NIST_192_TOP];
+ unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_192_TOP], *res;
+ PTR_SIZE_INT mask;
+ static const BIGNUM _bignum_nist_p_192_sqr = {
+ (BN_ULONG *)_nist_p_192_sqr,
+ sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]),
+ sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_192; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_192_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
+ } else
+ r_d = a_d;
+
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
+ BN_NIST_192_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc += bp[3 * 2 - 6];
+ acc += bp[5 * 2 - 6];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc += bp[3 * 2 - 5];
+ acc += bp[5 * 2 - 5];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc += bp[3 * 2 - 6];
+ acc += bp[4 * 2 - 6];
+ acc += bp[5 * 2 - 6];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[3 * 2 - 5];
+ acc += bp[4 * 2 - 5];
+ acc += bp[5 * 2 - 5];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[4 * 2 - 6];
+ acc += bp[5 * 2 - 6];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[4 * 2 - 5];
+ acc += bp[5 * 2 - 5];
+ rp[5] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_192_TOP];
+
+ nist_set_192(t_d, buf.bn, 0, 3, 3);
+ carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+ nist_set_192(t_d, buf.bn, 4, 4, 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+ nist_set_192(t_d, buf.bn, 5, 5, 5)
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+ }
+#endif
+ if (carry > 0)
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
+ BN_NIST_192_TOP);
+ else
+ carry = 1;
+
+ /*
+ * we need 'if (carry==0 || result>=modulus) result-=modulus;'
+ * as comparison implies subtraction, we can write
+ * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
+ * this is what happens below, but without explicit if:-) a.
+ */
+ mask =
+ 0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0],
+ BN_NIST_192_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)
+ (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_192_TOP);
+ r->top = BN_NIST_192_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *,
+ const BN_ULONG *, int);
+
+#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
+ { \
+ bn_cp_32(to, 0, from, (a7) - 7) \
+ bn_cp_32(to, 1, from, (a6) - 7) \
+ bn_cp_32(to, 2, from, (a5) - 7) \
+ bn_cp_32(to, 3, from, (a4) - 7) \
+ bn_cp_32(to, 4, from, (a3) - 7) \
+ bn_cp_32(to, 5, from, (a2) - 7) \
+ bn_cp_32(to, 6, from, (a1) - 7) \
+ }
+
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int top = a->top, i;
+ int carry;
+ BN_ULONG *r_d, *a_d = a->d;
+ union {
+ BN_ULONG bn[BN_NIST_224_TOP];
+ unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_224_TOP], *res;
+ PTR_SIZE_INT mask;
+ union {
+ bn_addsub_f f;
+ PTR_SIZE_INT p;
+ } u;
+ static const BIGNUM _bignum_nist_p_224_sqr = {
+ (BN_ULONG *)_nist_p_224_sqr,
+ sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
+ sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_224; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_224_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
+ } else
+ r_d = a_d;
+
+#if BN_BITS2==64
+ /* copy upper 256 bits of 448 bit number ... */
+ nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
+ top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
+ /* ... and right shift by 32 to obtain upper 224 bits */
+ nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
+ /* truncate lower part to 224 bits too */
+ r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
+#else
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP,
+ BN_NIST_224_TOP);
+#endif
+
+#if defined(NIST_INT64) && BN_BITS2!=64
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc -= bp[7 - 7];
+ acc -= bp[11 - 7];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc -= bp[8 - 7];
+ acc -= bp[12 - 7];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc -= bp[9 - 7];
+ acc -= bp[13 - 7];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[7 - 7];
+ acc += bp[11 - 7];
+ acc -= bp[10 - 7];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[8 - 7];
+ acc += bp[12 - 7];
+ acc -= bp[11 - 7];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[9 - 7];
+ acc += bp[13 - 7];
+ acc -= bp[12 - 7];
+ rp[5] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[6];
+ acc += bp[10 - 7];
+ acc -= bp[13 - 7];
+ rp[6] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+# if BN_BITS2==64
+ rp[7] = carry;
+# endif
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_224_TOP];
+
+ nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
+ carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+ nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+ nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+ nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+
+# if BN_BITS2==64
+ carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
+# endif
+ }
+#endif
+ u.f = bn_sub_words;
+ if (carry > 0) {
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
+ BN_NIST_224_TOP);
+#if BN_BITS2==64
+ carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
+#endif
+ } else if (carry < 0) {
+ /*
+ * it's a bit more comlicated logic in this case. if bn_add_words
+ * yields no carry, then result has to be adjusted by unconditionally
+ * *adding* the modulus. but if it does, then result has to be
+ * compared to the modulus and conditionally adjusted by
+ * *subtracting* the latter.
+ */
+ carry =
+ (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
+ BN_NIST_224_TOP);
+ mask = 0 - (PTR_SIZE_INT) carry;
+ u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+ ((PTR_SIZE_INT) bn_add_words & ~mask);
+ } else
+ carry = 1;
+
+ /* otherwise it's effectively same as in BN_nist_mod_192... */
+ mask =
+ 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_224_TOP);
+ r->top = BN_NIST_224_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
+ { \
+ bn_cp_32(to, 0, from, (a8) - 8) \
+ bn_cp_32(to, 1, from, (a7) - 8) \
+ bn_cp_32(to, 2, from, (a6) - 8) \
+ bn_cp_32(to, 3, from, (a5) - 8) \
+ bn_cp_32(to, 4, from, (a4) - 8) \
+ bn_cp_32(to, 5, from, (a3) - 8) \
+ bn_cp_32(to, 6, from, (a2) - 8) \
+ bn_cp_32(to, 7, from, (a1) - 8) \
+ }
+
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int i, top = a->top;
+ int carry = 0;
+ register BN_ULONG *a_d = a->d, *r_d;
+ union {
+ BN_ULONG bn[BN_NIST_256_TOP];
+ unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_256_TOP], *res;
+ PTR_SIZE_INT mask;
+ union {
+ bn_addsub_f f;
+ PTR_SIZE_INT p;
+ } u;
+ static const BIGNUM _bignum_nist_p_256_sqr = {
+ (BN_ULONG *)_nist_p_256_sqr,
+ sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
+ sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_256; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_256_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
+ } else
+ r_d = a_d;
+
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP,
+ BN_NIST_256_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc += bp[8 - 8];
+ acc += bp[9 - 8];
+ acc -= bp[11 - 8];
+ acc -= bp[12 - 8];
+ acc -= bp[13 - 8];
+ acc -= bp[14 - 8];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc += bp[9 - 8];
+ acc += bp[10 - 8];
+ acc -= bp[12 - 8];
+ acc -= bp[13 - 8];
+ acc -= bp[14 - 8];
+ acc -= bp[15 - 8];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc += bp[10 - 8];
+ acc += bp[11 - 8];
+ acc -= bp[13 - 8];
+ acc -= bp[14 - 8];
+ acc -= bp[15 - 8];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[11 - 8];
+ acc += bp[11 - 8];
+ acc += bp[12 - 8];
+ acc += bp[12 - 8];
+ acc += bp[13 - 8];
+ acc -= bp[15 - 8];
+ acc -= bp[8 - 8];
+ acc -= bp[9 - 8];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[12 - 8];
+ acc += bp[12 - 8];
+ acc += bp[13 - 8];
+ acc += bp[13 - 8];
+ acc += bp[14 - 8];
+ acc -= bp[9 - 8];
+ acc -= bp[10 - 8];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[13 - 8];
+ acc += bp[13 - 8];
+ acc += bp[14 - 8];
+ acc += bp[14 - 8];
+ acc += bp[15 - 8];
+ acc -= bp[10 - 8];
+ acc -= bp[11 - 8];
+ rp[5] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[6];
+ acc += bp[14 - 8];
+ acc += bp[14 - 8];
+ acc += bp[15 - 8];
+ acc += bp[15 - 8];
+ acc += bp[14 - 8];
+ acc += bp[13 - 8];
+ acc -= bp[8 - 8];
+ acc -= bp[9 - 8];
+ rp[6] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[7];
+ acc += bp[15 - 8];
+ acc += bp[15 - 8];
+ acc += bp[15 - 8];
+ acc += bp[8 - 8];
+ acc -= bp[10 - 8];
+ acc -= bp[11 - 8];
+ acc -= bp[12 - 8];
+ acc -= bp[13 - 8];
+ rp[7] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_256_TOP];
+
+ /*
+ * S1
+ */
+ nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
+ /*
+ * S2
+ */
+ nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
+ carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
+ /* left shift */
+ {
+ register BN_ULONG *ap, t, c;
+ ap = t_d;
+ c = 0;
+ for (i = BN_NIST_256_TOP; i != 0; --i) {
+ t = *ap;
+ *(ap++) = ((t << 1) | c) & BN_MASK2;
+ c = (t & BN_TBIT) ? 1 : 0;
+ }
+ carry <<= 1;
+ carry |= c;
+ }
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * S3
+ */
+ nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * S4
+ */
+ nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D1
+ */
+ nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D2
+ */
+ nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D3
+ */
+ nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D4
+ */
+ nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+
+ }
+#endif
+ /* see BN_nist_mod_224 for explanation */
+ u.f = bn_sub_words;
+ if (carry > 0)
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
+ BN_NIST_256_TOP);
+ else if (carry < 0) {
+ carry =
+ (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
+ BN_NIST_256_TOP);
+ mask = 0 - (PTR_SIZE_INT) carry;
+ u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+ ((PTR_SIZE_INT) bn_add_words & ~mask);
+ } else
+ carry = 1;
+
+ mask =
+ 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_256_TOP);
+ r->top = BN_NIST_256_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
+ { \
+ bn_cp_32(to, 0, from, (a12) - 12) \
+ bn_cp_32(to, 1, from, (a11) - 12) \
+ bn_cp_32(to, 2, from, (a10) - 12) \
+ bn_cp_32(to, 3, from, (a9) - 12) \
+ bn_cp_32(to, 4, from, (a8) - 12) \
+ bn_cp_32(to, 5, from, (a7) - 12) \
+ bn_cp_32(to, 6, from, (a6) - 12) \
+ bn_cp_32(to, 7, from, (a5) - 12) \
+ bn_cp_32(to, 8, from, (a4) - 12) \
+ bn_cp_32(to, 9, from, (a3) - 12) \
+ bn_cp_32(to, 10, from, (a2) - 12) \
+ bn_cp_32(to, 11, from, (a1) - 12) \
+ }
+
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int i, top = a->top;
+ int carry = 0;
+ register BN_ULONG *r_d, *a_d = a->d;
+ union {
+ BN_ULONG bn[BN_NIST_384_TOP];
+ unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_384_TOP], *res;
+ PTR_SIZE_INT mask;
+ union {
+ bn_addsub_f f;
+ PTR_SIZE_INT p;
+ } u;
+ static const BIGNUM _bignum_nist_p_384_sqr = {
+ (BN_ULONG *)_nist_p_384_sqr,
+ sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
+ sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_384; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_384_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
+ } else
+ r_d = a_d;
+
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP,
+ BN_NIST_384_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc += bp[12 - 12];
+ acc += bp[21 - 12];
+ acc += bp[20 - 12];
+ acc -= bp[23 - 12];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc += bp[13 - 12];
+ acc += bp[22 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[12 - 12];
+ acc -= bp[20 - 12];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc += bp[14 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[13 - 12];
+ acc -= bp[21 - 12];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[15 - 12];
+ acc += bp[12 - 12];
+ acc += bp[20 - 12];
+ acc += bp[21 - 12];
+ acc -= bp[14 - 12];
+ acc -= bp[22 - 12];
+ acc -= bp[23 - 12];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[21 - 12];
+ acc += bp[21 - 12];
+ acc += bp[16 - 12];
+ acc += bp[13 - 12];
+ acc += bp[12 - 12];
+ acc += bp[20 - 12];
+ acc += bp[22 - 12];
+ acc -= bp[15 - 12];
+ acc -= bp[23 - 12];
+ acc -= bp[23 - 12];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[22 - 12];
+ acc += bp[22 - 12];
+ acc += bp[17 - 12];
+ acc += bp[14 - 12];
+ acc += bp[13 - 12];
+ acc += bp[21 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[16 - 12];
+ rp[5] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[6];
+ acc += bp[23 - 12];
+ acc += bp[23 - 12];
+ acc += bp[18 - 12];
+ acc += bp[15 - 12];
+ acc += bp[14 - 12];
+ acc += bp[22 - 12];
+ acc -= bp[17 - 12];
+ rp[6] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[7];
+ acc += bp[19 - 12];
+ acc += bp[16 - 12];
+ acc += bp[15 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[18 - 12];
+ rp[7] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[8];
+ acc += bp[20 - 12];
+ acc += bp[17 - 12];
+ acc += bp[16 - 12];
+ acc -= bp[19 - 12];
+ rp[8] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[9];
+ acc += bp[21 - 12];
+ acc += bp[18 - 12];
+ acc += bp[17 - 12];
+ acc -= bp[20 - 12];
+ rp[9] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[10];
+ acc += bp[22 - 12];
+ acc += bp[19 - 12];
+ acc += bp[18 - 12];
+ acc -= bp[21 - 12];
+ rp[10] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[11];
+ acc += bp[23 - 12];
+ acc += bp[20 - 12];
+ acc += bp[19 - 12];
+ acc -= bp[22 - 12];
+ rp[11] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_384_TOP];
+
+ /*
+ * S1
+ */
+ nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4);
+ /* left shift */
+ {
+ register BN_ULONG *ap, t, c;
+ ap = t_d;
+ c = 0;
+ for (i = 3; i != 0; --i) {
+ t = *ap;
+ *(ap++) = ((t << 1) | c) & BN_MASK2;
+ c = (t & BN_TBIT) ? 1 : 0;
+ }
+ *ap = c;
+ }
+ carry =
+ (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2),
+ t_d, BN_NIST_256_TOP);
+ /*
+ * S2
+ */
+ carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
+ /*
+ * S3
+ */
+ nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,
+ 21);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * S4
+ */
+ nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23,
+ 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * S5
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * S6
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * D1
+ */
+ nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+ 23);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * D2
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * D3
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+
+ }
+#endif
+ /* see BN_nist_mod_224 for explanation */
+ u.f = bn_sub_words;
+ if (carry > 0)
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
+ BN_NIST_384_TOP);
+ else if (carry < 0) {
+ carry =
+ (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
+ BN_NIST_384_TOP);
+ mask = 0 - (PTR_SIZE_INT) carry;
+ u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+ ((PTR_SIZE_INT) bn_add_words & ~mask);
+ } else
+ carry = 1;
+
+ mask =
+ 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_384_TOP);
+ r->top = BN_NIST_384_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+#define BN_NIST_521_RSHIFT (521%BN_BITS2)
+#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT)
+#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
+
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int top = a->top, i;
+ BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
+ PTR_SIZE_INT mask;
+ static const BIGNUM _bignum_nist_p_521_sqr = {
+ (BN_ULONG *)_nist_p_521_sqr,
+ sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]),
+ sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_521; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_521_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
+ } else
+ r_d = a_d;
+
+ /* upper 521 bits, copy ... */
+ nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
+ top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
+ /* ... and right shift */
+ for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
+ t_d[i] = (val >> BN_NIST_521_RSHIFT |
+ (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2;
+ val = tmp;
+ }
+ t_d[i] = val >> BN_NIST_521_RSHIFT;
+ /* lower 521 bits */
+ r_d[i] &= BN_NIST_521_TOP_MASK;
+
+ bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
+ mask =
+ 0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521,
+ BN_NIST_521_TOP);
+ res = t_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_521_TOP);
+ r->top = BN_NIST_521_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_prime.c b/Cryptlib/OpenSSL/crypto/bn/bn_prime.c
new file mode 100644
index 00000000..ad641c37
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_prime.c
@@ -0,0 +1,519 @@
+/* crypto/bn/bn_prime.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 <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+/*
+ * NB: these functions have been "upgraded", the deprecated versions (which
+ * are compatibility wrappers using these functions) are in bn_depr.c. -
+ * Geoff
+ */
+
+/*
+ * The quick sieve algorithm approach to weeding out primes is Philip
+ * Zimmermann's, as implemented in PGP. I have had a read of his comments
+ * and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+ const BIGNUM *a1_odd, int k, BN_CTX *ctx,
+ BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods);
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+ const BIGNUM *add, const BIGNUM *rem,
+ BN_CTX *ctx);
+static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add,
+ const BIGNUM *rem, BN_CTX *ctx);
+
+int BN_GENCB_call(BN_GENCB *cb, int a, int b)
+{
+ /* No callback means continue */
+ if (!cb)
+ return 1;
+ switch (cb->ver) {
+ case 1:
+ /* Deprecated-style callbacks */
+ if (!cb->cb.cb_1)
+ return 1;
+ cb->cb.cb_1(a, b, cb->arg);
+ return 1;
+ case 2:
+ /* New-style callbacks */
+ return cb->cb.cb_2(a, b, cb);
+ default:
+ break;
+ }
+ /* Unrecognised callback type */
+ return 0;
+}
+
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
+ const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
+{
+ BIGNUM *t;
+ int found = 0;
+ int i, j, c1 = 0;
+ BN_CTX *ctx = NULL;
+ prime_t *mods = NULL;
+ int checks = BN_prime_checks_for_size(bits);
+
+ mods = OPENSSL_malloc(sizeof(*mods) * NUMPRIMES);
+ if (mods == NULL)
+ goto err;
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ t = BN_CTX_get(ctx);
+ if (!t)
+ goto err;
+ loop:
+ /* make a random number and set the top and bottom bits */
+ if (add == NULL) {
+ if (!probable_prime(ret, bits, mods))
+ goto err;
+ } else {
+ if (safe) {
+ if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
+ goto err;
+ } else {
+ if (!probable_prime_dh(ret, bits, add, rem, ctx))
+ goto err;
+ }
+ }
+ /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
+ if (!BN_GENCB_call(cb, 0, c1++))
+ /* aborted */
+ goto err;
+
+ if (!safe) {
+ i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
+ if (i == -1)
+ goto err;
+ if (i == 0)
+ goto loop;
+ } else {
+ /*
+ * for "safe prime" generation, check that (p-1)/2 is prime. Since a
+ * prime is odd, We just need to divide by 2
+ */
+ if (!BN_rshift1(t, ret))
+ goto err;
+
+ for (i = 0; i < checks; i++) {
+ j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
+ if (j == -1)
+ goto err;
+ if (j == 0)
+ goto loop;
+
+ j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
+ if (j == -1)
+ goto err;
+ if (j == 0)
+ goto loop;
+
+ if (!BN_GENCB_call(cb, 2, c1 - 1))
+ goto err;
+ /* We have a safe prime test pass */
+ }
+ }
+ /* we have a prime :-) */
+ found = 1;
+ err:
+ OPENSSL_free(mods);
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ bn_check_top(ret);
+ return found;
+}
+
+int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+ BN_GENCB *cb)
+{
+ return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
+}
+
+int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+ int do_trial_division, BN_GENCB *cb)
+{
+ int i, j, ret = -1;
+ int k;
+ BN_CTX *ctx = NULL;
+ BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+ BN_MONT_CTX *mont = NULL;
+ const BIGNUM *A = NULL;
+
+ if (BN_cmp(a, BN_value_one()) <= 0)
+ return 0;
+
+ if (checks == BN_prime_checks)
+ checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+ /* first look for small factors */
+ if (!BN_is_odd(a))
+ /* a is even => a is prime if and only if a == 2 */
+ return BN_is_word(a, 2);
+ if (do_trial_division) {
+ for (i = 1; i < NUMPRIMES; i++)
+ if (BN_mod_word(a, primes[i]) == 0)
+ return 0;
+ if (!BN_GENCB_call(cb, 1, -1))
+ goto err;
+ }
+
+ if (ctx_passed != NULL)
+ ctx = ctx_passed;
+ else if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+
+ /* A := abs(a) */
+ if (a->neg) {
+ BIGNUM *t;
+ if ((t = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ BN_copy(t, a);
+ t->neg = 0;
+ A = t;
+ } else
+ A = a;
+ A1 = BN_CTX_get(ctx);
+ A1_odd = BN_CTX_get(ctx);
+ check = BN_CTX_get(ctx);
+ if (check == NULL)
+ goto err;
+
+ /* compute A1 := A - 1 */
+ if (!BN_copy(A1, A))
+ goto err;
+ if (!BN_sub_word(A1, 1))
+ goto err;
+ if (BN_is_zero(A1)) {
+ ret = 0;
+ goto err;
+ }
+
+ /* write A1 as A1_odd * 2^k */
+ k = 1;
+ while (!BN_is_bit_set(A1, k))
+ k++;
+ if (!BN_rshift(A1_odd, A1, k))
+ goto err;
+
+ /* Montgomery setup for computations mod A */
+ mont = BN_MONT_CTX_new();
+ if (mont == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, A, ctx))
+ goto err;
+
+ for (i = 0; i < checks; i++) {
+ if (!BN_pseudo_rand_range(check, A1))
+ goto err;
+ if (!BN_add_word(check, 1))
+ goto err;
+ /* now 1 <= check < A */
+
+ j = witness(check, A, A1, A1_odd, k, ctx, mont);
+ if (j == -1)
+ goto err;
+ if (j) {
+ ret = 0;
+ goto err;
+ }
+ if (!BN_GENCB_call(cb, 1, i))
+ goto err;
+ }
+ ret = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ if (ctx_passed == NULL)
+ BN_CTX_free(ctx);
+ }
+ if (mont != NULL)
+ BN_MONT_CTX_free(mont);
+
+ return (ret);
+}
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+ const BIGNUM *a1_odd, int k, BN_CTX *ctx,
+ BN_MONT_CTX *mont)
+{
+ if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+ return -1;
+ if (BN_is_one(w))
+ return 0; /* probably prime */
+ if (BN_cmp(w, a1) == 0)
+ return 0; /* w == -1 (mod a), 'a' is probably prime */
+ while (--k) {
+ if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+ return -1;
+ if (BN_is_one(w))
+ return 1; /* 'a' is composite, otherwise a previous 'w'
+ * would have been == -1 (mod 'a') */
+ if (BN_cmp(w, a1) == 0)
+ return 0; /* w == -1 (mod a), 'a' is probably prime */
+ }
+ /*
+ * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
+ * it is neither -1 nor +1 -- so 'a' cannot be prime
+ */
+ bn_check_top(w);
+ return 1;
+}
+
+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods)
+{
+ int i;
+ BN_ULONG delta, maxdelta;
+
+ again:
+ if (!BN_rand(rnd, bits, 1, 1))
+ return (0);
+ /* we now have a random number 'rand' to test. */
+ for (i = 1; i < NUMPRIMES; i++)
+ mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]);
+ maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
+ delta = 0;
+ loop:for (i = 1; i < NUMPRIMES; i++) {
+ /*
+ * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1
+ * (except for 2)
+ */
+ if (((mods[i] + delta) % primes[i]) <= 1) {
+ delta += 2;
+ if (delta > maxdelta)
+ goto again;
+ goto loop;
+ }
+ }
+ if (!BN_add_word(rnd, delta))
+ return (0);
+ bn_check_top(rnd);
+ return (1);
+}
+
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+ const BIGNUM *add, const BIGNUM *rem,
+ BN_CTX *ctx)
+{
+ int i, ret = 0;
+ BIGNUM *t1;
+
+ BN_CTX_start(ctx);
+ if ((t1 = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_rand(rnd, bits, 0, 1))
+ goto err;
+
+ /* we need ((rnd-rem) % add) == 0 */
+
+ if (!BN_mod(t1, rnd, add, ctx))
+ goto err;
+ if (!BN_sub(rnd, rnd, t1))
+ goto err;
+ if (rem == NULL) {
+ if (!BN_add_word(rnd, 1))
+ goto err;
+ } else {
+ if (!BN_add(rnd, rnd, rem))
+ goto err;
+ }
+
+ /* we now have a random number 'rand' to test. */
+
+ loop:for (i = 1; i < NUMPRIMES; i++) {
+ /* check that rnd is a prime */
+ if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
+ if (!BN_add(rnd, rnd, add))
+ goto err;
+ goto loop;
+ }
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(rnd);
+ return (ret);
+}
+
+static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
+ const BIGNUM *rem, BN_CTX *ctx)
+{
+ int i, ret = 0;
+ BIGNUM *t1, *qadd, *q;
+
+ bits--;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ q = BN_CTX_get(ctx);
+ qadd = BN_CTX_get(ctx);
+ if (qadd == NULL)
+ goto err;
+
+ if (!BN_rshift1(qadd, padd))
+ goto err;
+
+ if (!BN_rand(q, bits, 0, 1))
+ goto err;
+
+ /* we need ((rnd-rem) % add) == 0 */
+ if (!BN_mod(t1, q, qadd, ctx))
+ goto err;
+ if (!BN_sub(q, q, t1))
+ goto err;
+ if (rem == NULL) {
+ if (!BN_add_word(q, 1))
+ goto err;
+ } else {
+ if (!BN_rshift1(t1, rem))
+ goto err;
+ if (!BN_add(q, q, t1))
+ goto err;
+ }
+
+ /* we now have a random number 'rand' to test. */
+ if (!BN_lshift1(p, q))
+ goto err;
+ if (!BN_add_word(p, 1))
+ goto err;
+
+ loop:for (i = 1; i < NUMPRIMES; i++) {
+ /* check that p and q are prime */
+ /*
+ * check that for p and q gcd(p-1,primes) == 1 (except for 2)
+ */
+ if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
+ (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
+ if (!BN_add(p, p, padd))
+ goto err;
+ if (!BN_add(q, q, qadd))
+ goto err;
+ goto loop;
+ }
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(p);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_prime.h b/Cryptlib/OpenSSL/crypto/bn/bn_prime.h
new file mode 100644
index 00000000..5cf0de16
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_prime.h
@@ -0,0 +1,326 @@
+/* Auto generated by bn_prime.pl */
+/* 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 EIGHT_BIT
+# define NUMPRIMES 2048
+typedef unsigned short prime_t;
+#else
+# define NUMPRIMES 54
+typedef unsigned char prime_t;
+#endif
+static const prime_t primes[NUMPRIMES] = {
+ 2, 3, 5, 7, 11, 13, 17, 19,
+ 23, 29, 31, 37, 41, 43, 47, 53,
+ 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131,
+ 137, 139, 149, 151, 157, 163, 167, 173,
+ 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+ 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311,
+ 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409,
+ 419, 421, 431, 433, 439, 443, 449, 457,
+ 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569,
+ 571, 577, 587, 593, 599, 601, 607, 613,
+ 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719,
+ 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881,
+ 883, 887, 907, 911, 919, 929, 937, 941,
+ 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
+ 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
+ 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
+ 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
+ 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
+ 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
+ 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
+ 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
+ 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+ 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571,
+ 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
+ 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
+ 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
+ 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
+ 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
+ 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
+ 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
+ 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
+ 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
+ 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
+ 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
+ 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311,
+ 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
+ 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
+ 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
+ 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
+ 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
+ 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
+ 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
+ 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
+ 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,
+ 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
+ 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
+ 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
+ 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
+ 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
+ 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301,
+ 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
+ 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
+ 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491,
+ 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
+ 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
+ 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671,
+ 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
+ 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
+ 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863,
+ 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
+ 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
+ 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
+ 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
+ 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
+ 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259,
+ 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
+ 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
+ 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
+ 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
+ 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
+ 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673,
+ 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
+ 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
+ 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
+ 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
+ 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
+ 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
+ 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
+ 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
+ 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
+ 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
+ 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
+ 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
+ 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
+ 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
+ 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711,
+ 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
+ 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
+ 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897,
+ 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
+ 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
+ 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
+ 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
+ 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
+ 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329,
+ 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
+ 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
+ 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563,
+ 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
+ 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
+ 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,
+ 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
+ 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
+ 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
+ 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
+ 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
+ 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
+ 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
+ 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
+ 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457,
+ 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
+ 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
+ 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
+ 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
+ 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
+ 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853,
+ 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
+ 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
+ 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087,
+ 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
+ 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231,
+ 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
+ 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
+ 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
+ 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537,
+ 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
+ 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
+ 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731,
+ 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
+ 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861,
+ 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
+ 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
+ 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091,
+ 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161,
+ 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
+ 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311,
+ 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
+ 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
+ 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,
+ 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587,
+ 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
+ 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
+ 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791,
+ 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
+ 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
+ 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
+ 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
+ 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
+ 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
+ 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303,
+ 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369,
+ 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
+ 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
+ 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
+ 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691,
+ 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771,
+ 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
+ 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
+ 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003,
+ 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087,
+ 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161,
+ 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
+ 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
+ 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399,
+ 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483,
+ 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551,
+ 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
+ 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
+ 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813,
+ 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887,
+ 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941,
+ 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
+ 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
+ 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161,
+ 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
+ 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323,
+ 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
+ 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
+ 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
+ 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589,
+ 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
+ 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
+ 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
+ 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907,
+ 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967,
+ 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033,
+ 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
+ 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
+ 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259,
+ 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
+ 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421,
+ 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
+ 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
+ 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681,
+ 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723,
+ 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799,
+ 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
+ 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
+ 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
+ 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143,
+ 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
+ 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
+ 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
+ 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461,
+ 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549,
+ 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627,
+ 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
+ 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
+ 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821,
+ 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887,
+ 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957,
+ 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
+ 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
+ 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
+ 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277,
+ 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331,
+ 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
+ 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
+ 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569,
+ 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643,
+ 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727,
+ 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
+ 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
+ 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919,
+ 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007,
+ 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
+ 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
+ 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
+ 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349,
+ 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427,
+ 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493,
+ 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
+ 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
+ 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
+ 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
+ 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927,
+ 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
+ 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
+ 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159,
+ 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
+ 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327,
+ 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
+ 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
+ 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
+ 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
+ 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683,
+ 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
+ 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
+#endif
+};
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_print.c b/Cryptlib/OpenSSL/crypto/bn/bn_print.c
new file mode 100644
index 00000000..bfa31efc
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_print.c
@@ -0,0 +1,397 @@
+/* crypto/bn/bn_print.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 <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
+static const char Hex[] = "0123456789ABCDEF";
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+{
+ int i, j, v, z = 0;
+ char *buf;
+ char *p;
+
+ if (a->neg && BN_is_zero(a)) {
+ /* "-0" == 3 bytes including NULL terminator */
+ buf = OPENSSL_malloc(3);
+ } else {
+ buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+ }
+ if (buf == NULL) {
+ BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = buf;
+ if (a->neg)
+ *(p++) = '-';
+ if (BN_is_zero(a))
+ *(p++) = '0';
+ for (i = a->top - 1; i >= 0; i--) {
+ for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
+ /* strip leading zeros */
+ v = ((int)(a->d[i] >> (long)j)) & 0xff;
+ if (z || (v != 0)) {
+ *(p++) = Hex[v >> 4];
+ *(p++) = Hex[v & 0x0f];
+ z = 1;
+ }
+ }
+ }
+ *p = '\0';
+ err:
+ return (buf);
+}
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2dec(const BIGNUM *a)
+{
+ int i = 0, num, ok = 0;
+ char *buf = NULL;
+ char *p;
+ BIGNUM *t = NULL;
+ BN_ULONG *bn_data = NULL, *lp;
+
+ /*-
+ * get an upper bound for the length of the decimal integer
+ * num <= (BN_num_bits(a) + 1) * log(2)
+ * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error)
+ * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
+ */
+ i = BN_num_bits(a) * 3;
+ num = (i / 10 + i / 1000 + 1) + 1;
+ bn_data =
+ (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
+ buf = (char *)OPENSSL_malloc(num + 3);
+ if ((buf == NULL) || (bn_data == NULL)) {
+ BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((t = BN_dup(a)) == NULL)
+ goto err;
+
+#define BUF_REMAIN (num+3 - (size_t)(p - buf))
+ p = buf;
+ lp = bn_data;
+ if (BN_is_zero(t)) {
+ *(p++) = '0';
+ *(p++) = '\0';
+ } else {
+ if (BN_is_negative(t))
+ *p++ = '-';
+
+ i = 0;
+ while (!BN_is_zero(t)) {
+ *lp = BN_div_word(t, BN_DEC_CONV);
+ lp++;
+ }
+ lp--;
+ /*
+ * We now have a series of blocks, BN_DEC_NUM chars in length, where
+ * the last one needs truncation. The blocks need to be reversed in
+ * order.
+ */
+ BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
+ while (*p)
+ p++;
+ while (lp != bn_data) {
+ lp--;
+ BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
+ while (*p)
+ p++;
+ }
+ }
+ ok = 1;
+ err:
+ if (bn_data != NULL)
+ OPENSSL_free(bn_data);
+ if (t != NULL)
+ BN_free(t);
+ if (!ok && buf) {
+ OPENSSL_free(buf);
+ buf = NULL;
+ }
+
+ return (buf);
+}
+
+int BN_hex2bn(BIGNUM **bn, const char *a)
+{
+ BIGNUM *ret = NULL;
+ BN_ULONG l = 0;
+ int neg = 0, h, m, i, j, k, c;
+ int num;
+
+ if ((a == NULL) || (*a == '\0'))
+ return (0);
+
+ if (*a == '-') {
+ neg = 1;
+ a++;
+ }
+
+ for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
+ continue;
+
+ if (i > INT_MAX/4)
+ goto err;
+
+ num = i + neg;
+ if (bn == NULL)
+ return (num);
+
+ /* a is the start of the hex digits, and it is 'i' long */
+ if (*bn == NULL) {
+ if ((ret = BN_new()) == NULL)
+ return (0);
+ } else {
+ ret = *bn;
+ BN_zero(ret);
+ }
+
+ /* i is the number of hex digits */
+ if (bn_expand(ret, i * 4) == NULL)
+ goto err;
+
+ j = i; /* least significant 'hex' */
+ m = 0;
+ h = 0;
+ while (j > 0) {
+ m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
+ l = 0;
+ for (;;) {
+ c = a[j - m];
+ if ((c >= '0') && (c <= '9'))
+ k = c - '0';
+ else if ((c >= 'a') && (c <= 'f'))
+ k = c - 'a' + 10;
+ else if ((c >= 'A') && (c <= 'F'))
+ k = c - 'A' + 10;
+ else
+ k = 0; /* paranoia */
+ l = (l << 4) | k;
+
+ if (--m <= 0) {
+ ret->d[h++] = l;
+ break;
+ }
+ }
+ j -= (BN_BYTES * 2);
+ }
+ ret->top = h;
+ bn_correct_top(ret);
+ ret->neg = neg;
+
+ *bn = ret;
+ bn_check_top(ret);
+ return (num);
+ err:
+ if (*bn == NULL)
+ BN_free(ret);
+ return (0);
+}
+
+int BN_dec2bn(BIGNUM **bn, const char *a)
+{
+ BIGNUM *ret = NULL;
+ BN_ULONG l = 0;
+ int neg = 0, i, j;
+ int num;
+
+ if ((a == NULL) || (*a == '\0'))
+ return (0);
+ if (*a == '-') {
+ neg = 1;
+ a++;
+ }
+
+ for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
+ continue;
+
+ if (i > INT_MAX/4)
+ goto err;
+
+ num = i + neg;
+ if (bn == NULL)
+ return (num);
+
+ /*
+ * a is the start of the digits, and it is 'i' long. We chop it into
+ * BN_DEC_NUM digits at a time
+ */
+ if (*bn == NULL) {
+ if ((ret = BN_new()) == NULL)
+ return (0);
+ } else {
+ ret = *bn;
+ BN_zero(ret);
+ }
+
+ /* i is the number of digits, a bit of an over expand */
+ if (bn_expand(ret, i * 4) == NULL)
+ goto err;
+
+ j = BN_DEC_NUM - (i % BN_DEC_NUM);
+ if (j == BN_DEC_NUM)
+ j = 0;
+ l = 0;
+ while (*a) {
+ l *= 10;
+ l += *a - '0';
+ a++;
+ if (++j == BN_DEC_NUM) {
+ BN_mul_word(ret, BN_DEC_CONV);
+ BN_add_word(ret, l);
+ l = 0;
+ j = 0;
+ }
+ }
+ ret->neg = neg;
+
+ bn_correct_top(ret);
+ *bn = ret;
+ bn_check_top(ret);
+ return (num);
+ err:
+ if (*bn == NULL)
+ BN_free(ret);
+ 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)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL)
+ return (0);
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = BN_print(b, a);
+ BIO_free(b);
+ return (ret);
+}
+# endif
+
+int BN_print(BIO *bp, const BIGNUM *a)
+{
+ int i, j, v, z = 0;
+ int ret = 0;
+
+ if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
+ goto end;
+ if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
+ goto end;
+ for (i = a->top - 1; i >= 0; i--) {
+ for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
+ /* strip leading zeros */
+ v = ((int)(a->d[i] >> (long)j)) & 0x0f;
+ if (z || (v != 0)) {
+ if (BIO_write(bp, &(Hex[v]), 1) != 1)
+ goto end;
+ z = 1;
+ }
+ }
+ }
+ ret = 1;
+ end:
+ return (ret);
+}
+#endif
+
+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/Cryptlib/OpenSSL/crypto/bn/bn_rand.c b/Cryptlib/OpenSSL/crypto/bn/bn_rand.c
new file mode 100644
index 00000000..f9fb2e9e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_rand.c
@@ -0,0 +1,295 @@
+/* crypto/bn/bn_rand.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 <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+{
+ unsigned char *buf = NULL;
+ int ret = 0, bit, bytes, mask;
+ time_t tim;
+
+ if (bits < 0 || (bits == 1 && top > 0)) {
+ BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
+ return 0;
+ }
+
+ if (bits == 0) {
+ BN_zero(rnd);
+ return 1;
+ }
+
+ bytes = (bits + 7) / 8;
+ bit = (bits - 1) % 8;
+ mask = 0xff << (bit + 1);
+
+ buf = (unsigned char *)OPENSSL_malloc(bytes);
+ if (buf == NULL) {
+ BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* make a random number and set the top and bottom bits */
+ time(&tim);
+ RAND_add(&tim, sizeof(tim), 0.0);
+
+ if (pseudorand) {
+ if (RAND_pseudo_bytes(buf, bytes) == -1)
+ goto err;
+ } else {
+ if (RAND_bytes(buf, bytes) <= 0)
+ goto err;
+ }
+
+#if 1
+ if (pseudorand == 2) {
+ /*
+ * generate patterns that are more likely to trigger BN library bugs
+ */
+ int i;
+ unsigned char c;
+
+ for (i = 0; i < bytes; i++) {
+ if (RAND_pseudo_bytes(&c, 1) < 0)
+ goto err;
+ if (c >= 128 && i > 0)
+ buf[i] = buf[i - 1];
+ else if (c < 42)
+ buf[i] = 0;
+ else if (c < 84)
+ buf[i] = 255;
+ }
+ }
+#endif
+
+ if (top >= 0) {
+ if (top) {
+ if (bit == 0) {
+ buf[0] = 1;
+ buf[1] |= 0x80;
+ } else {
+ buf[0] |= (3 << (bit - 1));
+ }
+ } else {
+ buf[0] |= (1 << bit);
+ }
+ }
+ buf[0] &= ~mask;
+ if (bottom) /* set bottom bit if requested */
+ buf[bytes - 1] |= 1;
+ if (!BN_bin2bn(buf, bytes, rnd))
+ goto err;
+ ret = 1;
+ err:
+ if (buf != NULL) {
+ OPENSSL_cleanse(buf, bytes);
+ OPENSSL_free(buf);
+ }
+ bn_check_top(rnd);
+ return (ret);
+}
+
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+ return bnrand(0, rnd, bits, top, bottom);
+}
+
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+ return bnrand(1, rnd, bits, top, bottom);
+}
+
+#if 1
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+ return bnrand(2, rnd, bits, top, bottom);
+}
+#endif
+
+/* random number r: 0 <= r < range */
+static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
+{
+ int (*bn_rand) (BIGNUM *, int, int, int) =
+ pseudo ? BN_pseudo_rand : BN_rand;
+ int n;
+ int count = 100;
+
+ if (range->neg || BN_is_zero(range)) {
+ BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
+ return 0;
+ }
+
+ n = BN_num_bits(range); /* n > 0 */
+
+ /* BN_is_bit_set(range, n - 1) always holds */
+
+ if (n == 1)
+ BN_zero(r);
+ else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
+ /*
+ * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
+ * than range
+ */
+ do {
+ if (!bn_rand(r, n + 1, -1, 0))
+ return 0;
+ /*
+ * If r < 3*range, use r := r MOD range (which is either r, r -
+ * range, or r - 2*range). Otherwise, iterate once more. Since
+ * 3*range = 11..._2, each iteration succeeds with probability >=
+ * .75.
+ */
+ if (BN_cmp(r, range) >= 0) {
+ if (!BN_sub(r, r, range))
+ return 0;
+ if (BN_cmp(r, range) >= 0)
+ if (!BN_sub(r, r, range))
+ return 0;
+ }
+
+ if (!--count) {
+ BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+ return 0;
+ }
+
+ }
+ while (BN_cmp(r, range) >= 0);
+ } else {
+ do {
+ /* range = 11..._2 or range = 101..._2 */
+ if (!bn_rand(r, n, -1, 0))
+ return 0;
+
+ if (!--count) {
+ BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+ return 0;
+ }
+ }
+ while (BN_cmp(r, range) >= 0);
+ }
+
+ bn_check_top(r);
+ return 1;
+}
+
+int BN_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+ return bn_rand_range(0, r, range);
+}
+
+int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+ return bn_rand_range(1, r, range);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_recp.c b/Cryptlib/OpenSSL/crypto/bn/bn_recp.c
new file mode 100644
index 00000000..f047040e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_recp.c
@@ -0,0 +1,252 @@
+/* crypto/bn/bn_recp.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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
+{
+ BN_init(&(recp->N));
+ BN_init(&(recp->Nr));
+ recp->num_bits = 0;
+ recp->shift = 0;
+ recp->flags = 0;
+}
+
+BN_RECP_CTX *BN_RECP_CTX_new(void)
+{
+ BN_RECP_CTX *ret;
+
+ if ((ret = (BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL)
+ return (NULL);
+
+ BN_RECP_CTX_init(ret);
+ ret->flags = BN_FLG_MALLOCED;
+ return (ret);
+}
+
+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
+{
+ if (recp == NULL)
+ return;
+
+ BN_free(&(recp->N));
+ BN_free(&(recp->Nr));
+ if (recp->flags & BN_FLG_MALLOCED)
+ OPENSSL_free(recp);
+}
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+{
+ if (!BN_copy(&(recp->N), d))
+ return 0;
+ BN_zero(&(recp->Nr));
+ recp->num_bits = BN_num_bits(d);
+ recp->shift = 0;
+ return (1);
+}
+
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+ BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *a;
+ const BIGNUM *ca;
+
+ BN_CTX_start(ctx);
+ if ((a = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (y != NULL) {
+ if (x == y) {
+ if (!BN_sqr(a, x, ctx))
+ goto err;
+ } else {
+ if (!BN_mul(a, x, y, ctx))
+ goto err;
+ }
+ ca = a;
+ } else
+ ca = x; /* Just do the mod */
+
+ ret = BN_div_recp(NULL, r, ca, recp, ctx);
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+ int i, j, ret = 0;
+ BIGNUM *a, *b, *d, *r;
+
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ if (dv != NULL)
+ d = dv;
+ else
+ d = BN_CTX_get(ctx);
+ if (rem != NULL)
+ r = rem;
+ else
+ r = BN_CTX_get(ctx);
+ if (a == NULL || b == NULL || d == NULL || r == NULL)
+ goto err;
+
+ if (BN_ucmp(m, &(recp->N)) < 0) {
+ BN_zero(d);
+ if (!BN_copy(r, m)) {
+ BN_CTX_end(ctx);
+ return 0;
+ }
+ BN_CTX_end(ctx);
+ return (1);
+ }
+
+ /*
+ * We want the remainder Given input of ABCDEF / ab we need multiply
+ * ABCDEF by 3 digests of the reciprocal of ab
+ */
+
+ /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
+ i = BN_num_bits(m);
+ j = recp->num_bits << 1;
+ if (j > i)
+ i = j;
+
+ /* Nr := round(2^i / N) */
+ if (i != recp->shift)
+ recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx);
+ /* BN_reciprocal could have returned -1 for an error */
+ if (recp->shift == -1)
+ goto err;
+
+ /*-
+ * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
+ * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
+ * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
+ * = |m/N|
+ */
+ if (!BN_rshift(a, m, recp->num_bits))
+ goto err;
+ if (!BN_mul(b, a, &(recp->Nr), ctx))
+ goto err;
+ if (!BN_rshift(d, b, i - recp->num_bits))
+ goto err;
+ d->neg = 0;
+
+ if (!BN_mul(b, &(recp->N), d, ctx))
+ goto err;
+ if (!BN_usub(r, m, b))
+ goto err;
+ r->neg = 0;
+
+#if 1
+ j = 0;
+ while (BN_ucmp(r, &(recp->N)) >= 0) {
+ if (j++ > 2) {
+ BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL);
+ goto err;
+ }
+ if (!BN_usub(r, r, &(recp->N)))
+ goto err;
+ if (!BN_add_word(d, 1))
+ goto err;
+ }
+#endif
+
+ r->neg = BN_is_zero(r) ? 0 : m->neg;
+ d->neg = m->neg ^ recp->N.neg;
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(dv);
+ bn_check_top(rem);
+ return (ret);
+}
+
+/*
+ * len is the expected size of the result We actually calculate with an extra
+ * word of precision, so we can do faster division if the remainder is not
+ * required.
+ */
+/* r := 2^len / m */
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
+{
+ int ret = -1;
+ BIGNUM *t;
+
+ BN_CTX_start(ctx);
+ if ((t = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_set_bit(t, len))
+ goto err;
+
+ if (!BN_div(r, NULL, t, m, ctx))
+ goto err;
+
+ ret = len;
+ err:
+ bn_check_top(r);
+ BN_CTX_end(ctx);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_shift.c b/Cryptlib/OpenSSL/crypto/bn/bn_shift.c
new file mode 100644
index 00000000..9673d9a3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_shift.c
@@ -0,0 +1,224 @@
+/* crypto/bn/bn_shift.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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, const BIGNUM *a)
+{
+ register BN_ULONG *ap, *rp, t, c;
+ int i;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ if (r != a) {
+ r->neg = a->neg;
+ if (bn_wexpand(r, a->top + 1) == NULL)
+ return (0);
+ r->top = a->top;
+ } else {
+ if (bn_wexpand(r, a->top + 1) == NULL)
+ return (0);
+ }
+ ap = a->d;
+ rp = r->d;
+ c = 0;
+ for (i = 0; i < a->top; i++) {
+ t = *(ap++);
+ *(rp++) = ((t << 1) | c) & BN_MASK2;
+ c = (t & BN_TBIT) ? 1 : 0;
+ }
+ if (c) {
+ *rp = 1;
+ r->top++;
+ }
+ bn_check_top(r);
+ return (1);
+}
+
+int BN_rshift1(BIGNUM *r, const BIGNUM *a)
+{
+ BN_ULONG *ap, *rp, t, c;
+ int i, j;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ if (BN_is_zero(a)) {
+ BN_zero(r);
+ return (1);
+ }
+ i = a->top;
+ ap = a->d;
+ j = i - (ap[i - 1] == 1);
+ if (a != r) {
+ if (bn_wexpand(r, j) == NULL)
+ return (0);
+ r->neg = a->neg;
+ }
+ rp = r->d;
+ t = ap[--i];
+ c = (t & 1) ? BN_TBIT : 0;
+ if (t >>= 1)
+ rp[i] = t;
+ while (i > 0) {
+ t = ap[--i];
+ rp[i] = ((t >> 1) & BN_MASK2) | c;
+ c = (t & 1) ? BN_TBIT : 0;
+ }
+ r->top = j;
+ bn_check_top(r);
+ return (1);
+}
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+ int i, nw, lb, rb;
+ BN_ULONG *t, *f;
+ BN_ULONG l;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ if (n < 0) {
+ BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT);
+ return 0;
+ }
+
+ r->neg = a->neg;
+ nw = n / BN_BITS2;
+ if (bn_wexpand(r, a->top + nw + 1) == NULL)
+ return (0);
+ lb = n % BN_BITS2;
+ rb = BN_BITS2 - lb;
+ f = a->d;
+ t = r->d;
+ t[a->top + nw] = 0;
+ if (lb == 0)
+ for (i = a->top - 1; i >= 0; i--)
+ t[nw + i] = f[i];
+ else
+ for (i = a->top - 1; i >= 0; i--) {
+ l = f[i];
+ t[nw + i + 1] |= (l >> rb) & BN_MASK2;
+ t[nw + i] = (l << lb) & BN_MASK2;
+ }
+ memset(t, 0, nw * sizeof(t[0]));
+ /*
+ * for (i=0; i<nw; i++) t[i]=0;
+ */
+ r->top = a->top + nw + 1;
+ bn_correct_top(r);
+ bn_check_top(r);
+ return (1);
+}
+
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+ int i, j, nw, lb, rb;
+ BN_ULONG *t, *f;
+ BN_ULONG l, tmp;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ if (n < 0) {
+ BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT);
+ return 0;
+ }
+
+ nw = n / BN_BITS2;
+ rb = n % BN_BITS2;
+ lb = BN_BITS2 - rb;
+ if (nw >= a->top || a->top == 0) {
+ BN_zero(r);
+ return (1);
+ }
+ i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
+ if (r != a) {
+ r->neg = a->neg;
+ if (bn_wexpand(r, i) == NULL)
+ return (0);
+ } else {
+ if (n == 0)
+ return 1; /* or the copying loop will go berserk */
+ }
+
+ f = &(a->d[nw]);
+ t = r->d;
+ j = a->top - nw;
+ r->top = i;
+
+ if (rb == 0) {
+ for (i = j; i != 0; i--)
+ *(t++) = *(f++);
+ } else {
+ l = *(f++);
+ for (i = j - 1; i != 0; i--) {
+ tmp = (l >> rb) & BN_MASK2;
+ l = *(f++);
+ *(t++) = (tmp | (l << lb)) & BN_MASK2;
+ }
+ if ((l = (l >> rb) & BN_MASK2))
+ *(t) = l;
+ }
+ bn_check_top(r);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_sqr.c b/Cryptlib/OpenSSL/crypto/bn/bn_sqr.c
new file mode 100644
index 00000000..3ca69879
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_sqr.c
@@ -0,0 +1,290 @@
+/* crypto/bn/bn_sqr.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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r must not be a */
+/*
+ * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
+ */
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+{
+ int max, al;
+ int ret = 0;
+ BIGNUM *tmp, *rr;
+
+#ifdef BN_COUNT
+ fprintf(stderr, "BN_sqr %d * %d\n", a->top, a->top);
+#endif
+ bn_check_top(a);
+
+ al = a->top;
+ if (al <= 0) {
+ r->top = 0;
+ r->neg = 0;
+ return 1;
+ }
+
+ BN_CTX_start(ctx);
+ rr = (a != r) ? r : BN_CTX_get(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (!rr || !tmp)
+ goto err;
+
+ max = 2 * al; /* Non-zero (from above) */
+ if (bn_wexpand(rr, max) == NULL)
+ goto err;
+
+ if (al == 4) {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[8];
+ bn_sqr_normal(rr->d, a->d, 4, t);
+#else
+ bn_sqr_comba4(rr->d, a->d);
+#endif
+ } else if (al == 8) {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[16];
+ bn_sqr_normal(rr->d, a->d, 8, t);
+#else
+ bn_sqr_comba8(rr->d, a->d);
+#endif
+ } else {
+#if defined(BN_RECURSION)
+ if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+ BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
+ bn_sqr_normal(rr->d, a->d, al, t);
+ } else {
+ int j, k;
+
+ j = BN_num_bits_word((BN_ULONG)al);
+ j = 1 << (j - 1);
+ k = j + j;
+ if (al == j) {
+ if (bn_wexpand(tmp, k * 2) == NULL)
+ goto err;
+ bn_sqr_recursive(rr->d, a->d, al, tmp->d);
+ } else {
+ if (bn_wexpand(tmp, max) == NULL)
+ goto err;
+ bn_sqr_normal(rr->d, a->d, al, tmp->d);
+ }
+ }
+#else
+ if (bn_wexpand(tmp, max) == NULL)
+ goto err;
+ bn_sqr_normal(rr->d, a->d, al, tmp->d);
+#endif
+ }
+
+ rr->neg = 0;
+ /*
+ * If the most-significant half of the top word of 'a' is zero, then the
+ * square of 'a' will max-1 words.
+ */
+ if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
+ rr->top = max - 1;
+ else
+ rr->top = max;
+ if (rr != r)
+ BN_copy(r, rr);
+ ret = 1;
+ err:
+ bn_check_top(rr);
+ bn_check_top(tmp);
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
+{
+ int i, j, max;
+ const BN_ULONG *ap;
+ BN_ULONG *rp;
+
+ max = n * 2;
+ ap = a;
+ rp = r;
+ rp[0] = rp[max - 1] = 0;
+ rp++;
+ j = n;
+
+ if (--j > 0) {
+ ap++;
+ rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
+ rp += 2;
+ }
+
+ for (i = n - 2; i > 0; i--) {
+ j--;
+ ap++;
+ rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
+ rp += 2;
+ }
+
+ bn_add_words(r, r, r, max);
+
+ /* There will not be a carry */
+
+ bn_sqr_words(tmp, a, n);
+
+ bn_add_words(r, r, tmp, max);
+}
+
+#ifdef BN_RECURSION
+/*-
+ * r is 2*n words in size,
+ * a and b are both n words in size. (There's not actually a 'b' here ...)
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
+{
+ int n = n2 / 2;
+ int zero, c1;
+ BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_sqr_recursive %d * %d\n", n2, n2);
+# endif
+ if (n2 == 4) {
+# ifndef BN_SQR_COMBA
+ bn_sqr_normal(r, a, 4, t);
+# else
+ bn_sqr_comba4(r, a);
+# endif
+ return;
+ } else if (n2 == 8) {
+# ifndef BN_SQR_COMBA
+ bn_sqr_normal(r, a, 8, t);
+# else
+ bn_sqr_comba8(r, a);
+# endif
+ return;
+ }
+ if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+ bn_sqr_normal(r, a, n2, t);
+ return;
+ }
+ /* r=(a[0]-a[1])*(a[1]-a[0]) */
+ c1 = bn_cmp_words(a, &(a[n]), n);
+ zero = 0;
+ if (c1 > 0)
+ bn_sub_words(t, a, &(a[n]), n);
+ else if (c1 < 0)
+ bn_sub_words(t, &(a[n]), a, n);
+ else
+ zero = 1;
+
+ /* The result will always be negative unless it is zero */
+ p = &(t[n2 * 2]);
+
+ if (!zero)
+ bn_sqr_recursive(&(t[n2]), t, n, p);
+ else
+ memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
+ bn_sqr_recursive(r, a, n, p);
+ bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+ /* t[32] is negative */
+ c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+ * r[10] holds (a[0]*a[0])
+ * r[32] holds (a[1]*a[1])
+ * c1 holds the carry bits
+ */
+ c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+ if (c1) {
+ p = &(r[n + n2]);
+ lo = *p;
+ ln = (lo + c1) & BN_MASK2;
+ *p = ln;
+
+ /*
+ * The overflow will stop before we over write words we should not
+ * overwrite
+ */
+ if (ln < (BN_ULONG)c1) {
+ do {
+ p++;
+ lo = *p;
+ ln = (lo + 1) & BN_MASK2;
+ *p = ln;
+ } while (ln == 0);
+ }
+ }
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c b/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c
new file mode 100644
index 00000000..232af99a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c
@@ -0,0 +1,409 @@
+/* crypto/bn/bn_sqrt.c */
+/*
+ * Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> and Bodo
+ * Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+/*
+ * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks
+ * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number
+ * Theory", algorithm 1.5.1). 'p' must be prime!
+ */
+{
+ BIGNUM *ret = in;
+ int err = 1;
+ int r;
+ BIGNUM *A, *b, *q, *t, *x, *y;
+ int e, i, j;
+
+ if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
+ if (BN_abs_is_word(p, 2)) {
+ if (ret == NULL)
+ ret = BN_new();
+ if (ret == NULL)
+ goto end;
+ if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
+ if (ret != in)
+ BN_free(ret);
+ return NULL;
+ }
+ bn_check_top(ret);
+ return ret;
+ }
+
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+ return (NULL);
+ }
+
+ if (BN_is_zero(a) || BN_is_one(a)) {
+ if (ret == NULL)
+ ret = BN_new();
+ if (ret == NULL)
+ goto end;
+ if (!BN_set_word(ret, BN_is_one(a))) {
+ if (ret != in)
+ BN_free(ret);
+ return NULL;
+ }
+ bn_check_top(ret);
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ q = BN_CTX_get(ctx);
+ t = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL)
+ goto end;
+
+ if (ret == NULL)
+ ret = BN_new();
+ if (ret == NULL)
+ goto end;
+
+ /* A = a mod p */
+ if (!BN_nnmod(A, a, p, ctx))
+ goto end;
+
+ /* now write |p| - 1 as 2^e*q where q is odd */
+ e = 1;
+ while (!BN_is_bit_set(p, e))
+ e++;
+ /* we'll set q later (if needed) */
+
+ if (e == 1) {
+ /*-
+ * The easy case: (|p|-1)/2 is odd, so 2 has an inverse
+ * modulo (|p|-1)/2, and square roots can be computed
+ * directly by modular exponentiation.
+ * We have
+ * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2),
+ * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1.
+ */
+ if (!BN_rshift(q, p, 2))
+ goto end;
+ q->neg = 0;
+ if (!BN_add_word(q, 1))
+ goto end;
+ if (!BN_mod_exp(ret, A, q, p, ctx))
+ goto end;
+ err = 0;
+ goto vrfy;
+ }
+
+ if (e == 2) {
+ /*-
+ * |p| == 5 (mod 8)
+ *
+ * In this case 2 is always a non-square since
+ * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime.
+ * So if a really is a square, then 2*a is a non-square.
+ * Thus for
+ * b := (2*a)^((|p|-5)/8),
+ * i := (2*a)*b^2
+ * we have
+ * i^2 = (2*a)^((1 + (|p|-5)/4)*2)
+ * = (2*a)^((p-1)/2)
+ * = -1;
+ * so if we set
+ * x := a*b*(i-1),
+ * then
+ * x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
+ * = a^2 * b^2 * (-2*i)
+ * = a*(-i)*(2*a*b^2)
+ * = a*(-i)*i
+ * = a.
+ *
+ * (This is due to A.O.L. Atkin,
+ * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
+ * November 1992.)
+ */
+
+ /* t := 2*a */
+ if (!BN_mod_lshift1_quick(t, A, p))
+ goto end;
+
+ /* b := (2*a)^((|p|-5)/8) */
+ if (!BN_rshift(q, p, 3))
+ goto end;
+ q->neg = 0;
+ if (!BN_mod_exp(b, t, q, p, ctx))
+ goto end;
+
+ /* y := b^2 */
+ if (!BN_mod_sqr(y, b, p, ctx))
+ goto end;
+
+ /* t := (2*a)*b^2 - 1 */
+ if (!BN_mod_mul(t, t, y, p, ctx))
+ goto end;
+ if (!BN_sub_word(t, 1))
+ goto end;
+
+ /* x = a*b*t */
+ if (!BN_mod_mul(x, A, b, p, ctx))
+ goto end;
+ if (!BN_mod_mul(x, x, t, p, ctx))
+ goto end;
+
+ if (!BN_copy(ret, x))
+ goto end;
+ err = 0;
+ goto vrfy;
+ }
+
+ /*
+ * e > 2, so we really have to use the Tonelli/Shanks algorithm. First,
+ * find some y that is not a square.
+ */
+ if (!BN_copy(q, p))
+ goto end; /* use 'q' as temp */
+ q->neg = 0;
+ i = 2;
+ do {
+ /*
+ * For efficiency, try small numbers first; if this fails, try random
+ * numbers.
+ */
+ if (i < 22) {
+ if (!BN_set_word(y, i))
+ goto end;
+ } else {
+ if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0))
+ goto end;
+ if (BN_ucmp(y, p) >= 0) {
+ if (!(p->neg ? BN_add : BN_sub) (y, y, p))
+ goto end;
+ }
+ /* now 0 <= y < |p| */
+ if (BN_is_zero(y))
+ if (!BN_set_word(y, i))
+ goto end;
+ }
+
+ r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
+ if (r < -1)
+ goto end;
+ if (r == 0) {
+ /* m divides p */
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+ goto end;
+ }
+ }
+ while (r == 1 && ++i < 82);
+
+ if (r != -1) {
+ /*
+ * Many rounds and still no non-square -- this is more likely a bug
+ * than just bad luck. Even if p is not prime, we should have found
+ * some y such that r == -1.
+ */
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
+ goto end;
+ }
+
+ /* Here's our actual 'q': */
+ if (!BN_rshift(q, q, e))
+ goto end;
+
+ /*
+ * Now that we have some non-square, we can find an element of order 2^e
+ * by computing its q'th power.
+ */
+ if (!BN_mod_exp(y, y, q, p, ctx))
+ goto end;
+ if (BN_is_one(y)) {
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+ goto end;
+ }
+
+ /*-
+ * Now we know that (if p is indeed prime) there is an integer
+ * k, 0 <= k < 2^e, such that
+ *
+ * a^q * y^k == 1 (mod p).
+ *
+ * As a^q is a square and y is not, k must be even.
+ * q+1 is even, too, so there is an element
+ *
+ * X := a^((q+1)/2) * y^(k/2),
+ *
+ * and it satisfies
+ *
+ * X^2 = a^q * a * y^k
+ * = a,
+ *
+ * so it is the square root that we are looking for.
+ */
+
+ /* t := (q-1)/2 (note that q is odd) */
+ if (!BN_rshift1(t, q))
+ goto end;
+
+ /* x := a^((q-1)/2) */
+ if (BN_is_zero(t)) { /* special case: p = 2^e + 1 */
+ if (!BN_nnmod(t, A, p, ctx))
+ goto end;
+ if (BN_is_zero(t)) {
+ /* special case: a == 0 (mod p) */
+ BN_zero(ret);
+ err = 0;
+ goto end;
+ } else if (!BN_one(x))
+ goto end;
+ } else {
+ if (!BN_mod_exp(x, A, t, p, ctx))
+ goto end;
+ if (BN_is_zero(x)) {
+ /* special case: a == 0 (mod p) */
+ BN_zero(ret);
+ err = 0;
+ goto end;
+ }
+ }
+
+ /* b := a*x^2 (= a^q) */
+ if (!BN_mod_sqr(b, x, p, ctx))
+ goto end;
+ if (!BN_mod_mul(b, b, A, p, ctx))
+ goto end;
+
+ /* x := a*x (= a^((q+1)/2)) */
+ if (!BN_mod_mul(x, x, A, p, ctx))
+ goto end;
+
+ while (1) {
+ /*-
+ * Now b is a^q * y^k for some even k (0 <= k < 2^E
+ * where E refers to the original value of e, which we
+ * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2).
+ *
+ * We have a*b = x^2,
+ * y^2^(e-1) = -1,
+ * b^2^(e-1) = 1.
+ */
+
+ if (BN_is_one(b)) {
+ if (!BN_copy(ret, x))
+ goto end;
+ err = 0;
+ goto vrfy;
+ }
+
+ /* find smallest i such that b^(2^i) = 1 */
+ i = 1;
+ if (!BN_mod_sqr(t, b, p, ctx))
+ goto end;
+ while (!BN_is_one(t)) {
+ i++;
+ if (i == e) {
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+ goto end;
+ }
+ if (!BN_mod_mul(t, t, t, p, ctx))
+ goto end;
+ }
+
+ /* t := y^2^(e - i - 1) */
+ if (!BN_copy(t, y))
+ goto end;
+ for (j = e - i - 1; j > 0; j--) {
+ if (!BN_mod_sqr(t, t, p, ctx))
+ goto end;
+ }
+ if (!BN_mod_mul(y, t, t, p, ctx))
+ goto end;
+ if (!BN_mod_mul(x, x, t, p, ctx))
+ goto end;
+ if (!BN_mod_mul(b, b, y, p, ctx))
+ goto end;
+ e = i;
+ }
+
+ vrfy:
+ if (!err) {
+ /*
+ * verify the result -- the input might have been not a square (test
+ * added in 0.9.8)
+ */
+
+ if (!BN_mod_sqr(x, ret, p, ctx))
+ err = 1;
+
+ if (!err && 0 != BN_cmp(x, A)) {
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+ err = 1;
+ }
+ }
+
+ end:
+ if (err) {
+ if (ret != NULL && ret != in) {
+ BN_clear_free(ret);
+ }
+ ret = NULL;
+ }
+ BN_CTX_end(ctx);
+ bn_check_top(ret);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_word.c b/Cryptlib/OpenSSL/crypto/bn/bn_word.c
new file mode 100644
index 00000000..b031a60b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_word.c
@@ -0,0 +1,227 @@
+/* crypto/bn/bn_word.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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+{
+#ifndef BN_LLONG
+ BN_ULONG ret = 0;
+#else
+ BN_ULLONG ret = 0;
+#endif
+ int i;
+
+ if (w == 0)
+ return (BN_ULONG)-1;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+ for (i = a->top - 1; i >= 0; i--) {
+#ifndef BN_LLONG
+ ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
+ ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
+#else
+ ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) %
+ (BN_ULLONG) w);
+#endif
+ }
+ return ((BN_ULONG)ret);
+}
+
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
+{
+ BN_ULONG ret = 0;
+ int i, j;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+
+ if (!w)
+ /* actually this an error (division by zero) */
+ return (BN_ULONG)-1;
+ if (a->top == 0)
+ return 0;
+
+ /* normalize input (so bn_div_words doesn't complain) */
+ j = BN_BITS2 - BN_num_bits_word(w);
+ w <<= j;
+ if (!BN_lshift(a, a, j))
+ return (BN_ULONG)-1;
+
+ for (i = a->top - 1; i >= 0; i--) {
+ BN_ULONG l, d;
+
+ l = a->d[i];
+ d = bn_div_words(ret, l, w);
+ ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
+ a->d[i] = d;
+ }
+ if ((a->top > 0) && (a->d[a->top - 1] == 0))
+ a->top--;
+ ret >>= j;
+ bn_check_top(a);
+ return (ret);
+}
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+{
+ BN_ULONG l;
+ int i;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+
+ /* degenerate case: w is zero */
+ if (!w)
+ return 1;
+ /* degenerate case: a is zero */
+ if (BN_is_zero(a))
+ return BN_set_word(a, w);
+ /* handle 'a' when negative */
+ if (a->neg) {
+ a->neg = 0;
+ i = BN_sub_word(a, w);
+ if (!BN_is_zero(a))
+ a->neg = !(a->neg);
+ return (i);
+ }
+ for (i = 0; w != 0 && i < a->top; i++) {
+ a->d[i] = l = (a->d[i] + w) & BN_MASK2;
+ w = (w > l) ? 1 : 0;
+ }
+ if (w && i == a->top) {
+ if (bn_wexpand(a, a->top + 1) == NULL)
+ return 0;
+ a->top++;
+ a->d[i] = w;
+ }
+ bn_check_top(a);
+ return (1);
+}
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+{
+ int i;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+
+ /* degenerate case: w is zero */
+ if (!w)
+ return 1;
+ /* degenerate case: a is zero */
+ if (BN_is_zero(a)) {
+ i = BN_set_word(a, w);
+ if (i != 0)
+ BN_set_negative(a, 1);
+ return i;
+ }
+ /* handle 'a' when negative */
+ if (a->neg) {
+ a->neg = 0;
+ i = BN_add_word(a, w);
+ a->neg = 1;
+ return (i);
+ }
+
+ if ((a->top == 1) && (a->d[0] < w)) {
+ a->d[0] = w - a->d[0];
+ a->neg = 1;
+ return (1);
+ }
+ i = 0;
+ for (;;) {
+ if (a->d[i] >= w) {
+ a->d[i] -= w;
+ break;
+ } else {
+ a->d[i] = (a->d[i] - w) & BN_MASK2;
+ i++;
+ w = 1;
+ }
+ }
+ if ((a->d[i] == 0) && (i == (a->top - 1)))
+ a->top--;
+ bn_check_top(a);
+ return (1);
+}
+
+int BN_mul_word(BIGNUM *a, BN_ULONG w)
+{
+ BN_ULONG ll;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+ if (a->top) {
+ if (w == 0)
+ BN_zero(a);
+ else {
+ ll = bn_mul_words(a->d, a->d, a->top, w);
+ if (ll) {
+ if (bn_wexpand(a, a->top + 1) == NULL)
+ return (0);
+ a->d[a->top++] = ll;
+ }
+ }
+ }
+ bn_check_top(a);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_x931p.c b/Cryptlib/OpenSSL/crypto/bn/bn_x931p.c
new file mode 100644
index 00000000..efa48bdf
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_x931p.c
@@ -0,0 +1,277 @@
+/* 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 <stdio.h>
+#include <openssl/bn.h>
+
+/* 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))
+ goto err;
+
+ BN_CTX_start(ctx);
+ t = BN_CTX_get(ctx);
+
+ for (i = 0; i < 1000; i++) {
+ if (!BN_rand(Xq, nbits, 1, 0))
+ goto err;
+ /* 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;
+
+ err:
+ BN_CTX_end(ctx);
+ 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/Cryptlib/OpenSSL/crypto/bn/rsaz_exp.h b/Cryptlib/OpenSSL/crypto/bn/rsaz_exp.h
new file mode 100644
index 00000000..229e181f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/bn/rsaz_exp.h
@@ -0,0 +1,68 @@
+/*****************************************************************************
+* *
+* Copyright (c) 2012, Intel Corporation *
+* *
+* All rights reserved. *
+* *
+* Redistribution and use in source and binary forms, with or without *
+* modification, are permitted provided that the following conditions are *
+* met: *
+* *
+* * Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above copyright *
+* notice, this list of conditions and the following disclaimer in the *
+* documentation and/or other materials provided with the *
+* distribution. *
+* *
+* * Neither the name of the Intel Corporation nor the names of its *
+* contributors may be used to endorse or promote products derived from *
+* this software without specific prior written permission. *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY *
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR *
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+* *
+******************************************************************************
+* Developers and authors: *
+* Shay Gueron (1, 2), and Vlad Krasnov (1) *
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel *
+* (2) University of Haifa, Israel *
+*****************************************************************************/
+
+#ifndef RSAZ_EXP_H
+# define RSAZ_EXP_H
+
+# undef RSAZ_ENABLED
+# if defined(OPENSSL_BN_ASM_MONT) && \
+ (defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64))
+# define RSAZ_ENABLED
+
+# include <openssl/bn.h>
+
+void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16],
+ const BN_ULONG base_norm[16],
+ const BN_ULONG exponent[16],
+ const BN_ULONG m_norm[16], const BN_ULONG RR[16],
+ BN_ULONG k0);
+int rsaz_avx2_eligible();
+
+void RSAZ_512_mod_exp(BN_ULONG result[8],
+ const BN_ULONG base_norm[8], const BN_ULONG exponent[8],
+ const BN_ULONG m_norm[8], BN_ULONG k0,
+ const BN_ULONG RR[8]);
+
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/buffer/buf_err.c b/Cryptlib/OpenSSL/crypto/buffer/buf_err.c
new file mode 100644
index 00000000..631eec38
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/buffer/buf_err.c
@@ -0,0 +1,97 @@
+/* crypto/buffer/buf_err.c */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason)
+
+static ERR_STRING_DATA BUF_str_functs[] = {
+ {ERR_FUNC(BUF_F_BUF_MEMDUP), "BUF_memdup"},
+ {ERR_FUNC(BUF_F_BUF_MEM_GROW), "BUF_MEM_grow"},
+ {ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN), "BUF_MEM_grow_clean"},
+ {ERR_FUNC(BUF_F_BUF_MEM_NEW), "BUF_MEM_new"},
+ {ERR_FUNC(BUF_F_BUF_STRDUP), "BUF_strdup"},
+ {ERR_FUNC(BUF_F_BUF_STRNDUP), "BUF_strndup"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA BUF_str_reasons[] = {
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_BUF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, BUF_str_functs);
+ ERR_load_strings(0, BUF_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/buffer/buf_str.c b/Cryptlib/OpenSSL/crypto/buffer/buf_str.c
new file mode 100644
index 00000000..fa0d608e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/buffer/buf_str.c
@@ -0,0 +1,137 @@
+/* crypto/buffer/buffer.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 <stdio.h>
+#include "cryptlib.h"
+#include <limits.h>
+#include <openssl/buffer.h>
+
+size_t BUF_strnlen(const char *str, size_t maxlen)
+{
+ const char *p;
+
+ for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ;
+
+ return p - str;
+}
+
+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;
+
+ siz = BUF_strnlen(str, siz);
+
+ if (siz >= INT_MAX)
+ return NULL;
+
+ ret = OPENSSL_malloc(siz + 1);
+ if (ret == NULL) {
+ BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ memcpy(ret, str, siz);
+ ret[siz] = '\0';
+
+ return (ret);
+}
+
+void *BUF_memdup(const void *data, size_t siz)
+{
+ void *ret;
+
+ if (data == NULL || siz >= INT_MAX)
+ 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);
+}
diff --git a/Cryptlib/OpenSSL/crypto/buffer/buffer.c b/Cryptlib/OpenSSL/crypto/buffer/buffer.c
new file mode 100644
index 00000000..eff3e081
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/buffer/buffer.c
@@ -0,0 +1,187 @@
+/* crypto/buffer/buffer.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+
+/*
+ * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
+ * function is applied in several functions in this file and this limit
+ * ensures that the result fits in an int.
+ */
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
+
+BUF_MEM *BUF_MEM_new(void)
+{
+ BUF_MEM *ret;
+
+ ret = OPENSSL_malloc(sizeof(BUF_MEM));
+ if (ret == NULL) {
+ BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->length = 0;
+ ret->max = 0;
+ ret->data = NULL;
+ return (ret);
+}
+
+void BUF_MEM_free(BUF_MEM *a)
+{
+ if (a == NULL)
+ return;
+
+ if (a->data != NULL) {
+ OPENSSL_cleanse(a->data, a->max);
+ OPENSSL_free(a->data);
+ }
+ OPENSSL_free(a);
+}
+
+int BUF_MEM_grow(BUF_MEM *str, size_t len)
+{
+ char *ret;
+ size_t n;
+
+ if (str->length >= len) {
+ str->length = len;
+ return (len);
+ }
+ if (str->max >= len) {
+ memset(&str->data[str->length], 0, len - str->length);
+ str->length = len;
+ return (len);
+ }
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+ if (len > LIMIT_BEFORE_EXPANSION) {
+ BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ n = (len + 3) / 3 * 4;
+ if (str->data == NULL)
+ ret = OPENSSL_malloc(n);
+ else
+ ret = OPENSSL_realloc(str->data, n);
+ if (ret == NULL) {
+ BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
+ len = 0;
+ } else {
+ str->data = ret;
+ str->max = n;
+ memset(&str->data[str->length], 0, len - str->length);
+ str->length = len;
+ }
+ return (len);
+}
+
+int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
+{
+ char *ret;
+ size_t n;
+
+ if (str->length >= len) {
+ memset(&str->data[len], 0, str->length - len);
+ str->length = len;
+ return (len);
+ }
+ if (str->max >= len) {
+ memset(&str->data[str->length], 0, len - str->length);
+ str->length = len;
+ return (len);
+ }
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+ if (len > LIMIT_BEFORE_EXPANSION) {
+ BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ n = (len + 3) / 3 * 4;
+ if (str->data == NULL)
+ ret = OPENSSL_malloc(n);
+ else
+ ret = OPENSSL_realloc_clean(str->data, str->max, n);
+ if (ret == NULL) {
+ BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
+ len = 0;
+ } else {
+ str->data = ret;
+ str->max = n;
+ memset(&str->data[str->length], 0, len - str->length);
+ str->length = len;
+ }
+ return (len);
+}
+
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size)
+{
+ size_t i;
+ if (in) {
+ out += size - 1;
+ for (i = 0; i < size; i++)
+ *out-- = *in++;
+ } 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/Cryptlib/OpenSSL/crypto/cmac/cm_ameth.c b/Cryptlib/OpenSSL/crypto/cmac/cm_ameth.c
new file mode 100644
index 00000000..bf933e08
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cmac/cm_ameth.c
@@ -0,0 +1,96 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2010.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include "asn1_locl.h"
+
+/*
+ * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output
+ * length and to free up a CMAC key.
+ */
+
+static int cmac_size(const EVP_PKEY *pkey)
+{
+ return EVP_MAX_BLOCK_LENGTH;
+}
+
+static void cmac_key_free(EVP_PKEY *pkey)
+{
+ CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr;
+ if (cmctx)
+ CMAC_CTX_free(cmctx);
+}
+
+const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
+ EVP_PKEY_CMAC,
+ EVP_PKEY_CMAC,
+ 0,
+
+ "CMAC",
+ "OpenSSL CMAC method",
+
+ 0, 0, 0, 0,
+
+ 0, 0, 0,
+
+ cmac_size,
+ 0,
+ 0, 0, 0, 0, 0, 0, 0,
+
+ cmac_key_free,
+ 0,
+ 0, 0
+};
diff --git a/Cryptlib/OpenSSL/crypto/cmac/cm_pmeth.c b/Cryptlib/OpenSSL/crypto/cmac/cm_pmeth.c
new file mode 100644
index 00000000..a2300df1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cmac/cm_pmeth.c
@@ -0,0 +1,216 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2010.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include "evp_locl.h"
+
+/* The context structure and "key" is simply a CMAC_CTX */
+
+static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
+{
+ ctx->data = CMAC_CTX_new();
+ if (!ctx->data)
+ return 0;
+ ctx->keygen_info_count = 0;
+ return 1;
+}
+
+static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+ if (!pkey_cmac_init(dst))
+ return 0;
+ if (!CMAC_CTX_copy(dst->data, src->data))
+ return 0;
+ return 1;
+}
+
+static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+ CMAC_CTX_free(ctx->data);
+}
+
+static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ CMAC_CTX *cmkey = CMAC_CTX_new();
+ CMAC_CTX *cmctx = ctx->data;
+ if (!cmkey)
+ return 0;
+ if (!CMAC_CTX_copy(cmkey, cmctx)) {
+ CMAC_CTX_free(cmkey);
+ return 0;
+ }
+ EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
+
+ return 1;
+}
+
+static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ if (!CMAC_Update(ctx->pctx->data, data, count))
+ return 0;
+ return 1;
+}
+
+static int cmac_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 cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ EVP_MD_CTX *mctx)
+{
+ return CMAC_Final(ctx->data, sig, siglen);
+}
+
+static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+ CMAC_CTX *cmctx = ctx->data;
+ switch (type) {
+
+ case EVP_PKEY_CTRL_SET_MAC_KEY:
+ if (!p2 || p1 < 0)
+ return 0;
+ if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
+ return 0;
+ break;
+
+ case EVP_PKEY_CTRL_CIPHER:
+ if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
+ return 0;
+ break;
+
+ case EVP_PKEY_CTRL_MD:
+ if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
+ (CMAC_CTX *)ctx->pkey->pkey.ptr))
+ return 0;
+ if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
+ return 0;
+ break;
+
+ default:
+ return -2;
+
+ }
+ return 1;
+}
+
+static int pkey_cmac_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_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(p), p);
+ }
+ if (!strcmp(type, "cipher")) {
+ const EVP_CIPHER *c;
+ c = EVP_get_cipherbyname(value);
+ if (!c)
+ return 0;
+ return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
+ }
+ if (!strcmp(type, "hexkey")) {
+ unsigned char *key;
+ int r;
+ long keylen;
+ key = string_to_hex(value, &keylen);
+ if (!key)
+ return 0;
+ r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+ OPENSSL_free(key);
+ return r;
+ }
+ return -2;
+}
+
+const EVP_PKEY_METHOD cmac_pkey_meth = {
+ EVP_PKEY_CMAC,
+ EVP_PKEY_FLAG_SIGCTX_CUSTOM,
+ pkey_cmac_init,
+ pkey_cmac_copy,
+ pkey_cmac_cleanup,
+
+ 0, 0,
+
+ 0,
+ pkey_cmac_keygen,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ cmac_signctx_init,
+ cmac_signctx,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ pkey_cmac_ctrl,
+ pkey_cmac_ctrl_str
+};
diff --git a/Cryptlib/OpenSSL/crypto/cmac/cmac.c b/Cryptlib/OpenSSL/crypto/cmac/cmac.c
new file mode 100644
index 00000000..2954b6eb
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cmac/cmac.c
@@ -0,0 +1,306 @@
+/* crypto/cmac/cmac.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/cmac.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+struct CMAC_CTX_st {
+ /* Cipher context to use */
+ EVP_CIPHER_CTX cctx;
+ /* Keys k1 and k2 */
+ unsigned char k1[EVP_MAX_BLOCK_LENGTH];
+ unsigned char k2[EVP_MAX_BLOCK_LENGTH];
+ /* Temporary block */
+ unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
+ /* Last (possibly partial) block */
+ unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
+ /* Number of bytes in last block: -1 means context not initialised */
+ int nlast_block;
+};
+
+/* Make temporary keys K1 and K2 */
+
+static void make_kn(unsigned char *k1, unsigned char *l, int bl)
+{
+ int i;
+ /* Shift block to left, including carry */
+ for (i = 0; i < bl; i++) {
+ k1[i] = l[i] << 1;
+ if (i < bl - 1 && l[i + 1] & 0x80)
+ k1[i] |= 1;
+ }
+ /* If MSB set fixup with R */
+ if (l[0] & 0x80)
+ k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
+}
+
+CMAC_CTX *CMAC_CTX_new(void)
+{
+ CMAC_CTX *ctx;
+ ctx = OPENSSL_malloc(sizeof(CMAC_CTX));
+ if (!ctx)
+ return NULL;
+ EVP_CIPHER_CTX_init(&ctx->cctx);
+ ctx->nlast_block = -1;
+ return ctx;
+}
+
+void CMAC_CTX_cleanup(CMAC_CTX *ctx)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->cctx.engine) {
+ FIPS_cmac_ctx_cleanup(ctx);
+ return;
+ }
+#endif
+ EVP_CIPHER_CTX_cleanup(&ctx->cctx);
+ OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
+ OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
+ OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
+ OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
+ ctx->nlast_block = -1;
+}
+
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
+{
+ return &ctx->cctx;
+}
+
+void CMAC_CTX_free(CMAC_CTX *ctx)
+{
+ if (!ctx)
+ return;
+ CMAC_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
+{
+ int bl;
+ if (in->nlast_block == -1)
+ return 0;
+ if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
+ return 0;
+ bl = EVP_CIPHER_CTX_block_size(&in->cctx);
+ memcpy(out->k1, in->k1, bl);
+ memcpy(out->k2, in->k2, bl);
+ memcpy(out->tbl, in->tbl, bl);
+ memcpy(out->last_block, in->last_block, bl);
+ out->nlast_block = in->nlast_block;
+ return 1;
+}
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+ const EVP_CIPHER *cipher, ENGINE *impl)
+{
+ static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode()) {
+ /* If we have an ENGINE need to allow non FIPS */
+ if ((impl || ctx->cctx.engine)
+ && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) {
+ EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
+ return 0;
+ }
+
+ /* Switch to FIPS cipher implementation if possible */
+ if (cipher != NULL) {
+ const EVP_CIPHER *fcipher;
+ fcipher = FIPS_get_cipherbynid(EVP_CIPHER_nid(cipher));
+ if (fcipher != NULL)
+ cipher = fcipher;
+ }
+ /*
+ * Other algorithm blocking will be done in FIPS_cmac_init, via
+ * FIPS_cipherinit().
+ */
+ if (!impl && !ctx->cctx.engine)
+ return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
+ }
+#endif
+ /* All zeros means restart */
+ if (!key && !cipher && !impl && keylen == 0) {
+ /* Not initialised */
+ if (ctx->nlast_block == -1)
+ return 0;
+ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
+ return 0;
+ memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
+ ctx->nlast_block = 0;
+ return 1;
+ }
+ /* Initialiase context */
+ if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
+ return 0;
+ /* Non-NULL key means initialisation complete */
+ if (key) {
+ int bl;
+ if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
+ return 0;
+ if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
+ return 0;
+ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
+ return 0;
+ bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
+ return 0;
+ make_kn(ctx->k1, ctx->tbl, bl);
+ make_kn(ctx->k2, ctx->k1, bl);
+ OPENSSL_cleanse(ctx->tbl, bl);
+ /* Reset context again ready for first data block */
+ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
+ return 0;
+ /* Zero tbl so resume works */
+ memset(ctx->tbl, 0, bl);
+ ctx->nlast_block = 0;
+ }
+ return 1;
+}
+
+int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
+{
+ const unsigned char *data = in;
+ size_t bl;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->cctx.engine)
+ return FIPS_cmac_update(ctx, in, dlen);
+#endif
+ if (ctx->nlast_block == -1)
+ return 0;
+ if (dlen == 0)
+ return 1;
+ bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+ /* Copy into partial block if we need to */
+ if (ctx->nlast_block > 0) {
+ size_t nleft;
+ nleft = bl - ctx->nlast_block;
+ if (dlen < nleft)
+ nleft = dlen;
+ memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
+ dlen -= nleft;
+ ctx->nlast_block += nleft;
+ /* If no more to process return */
+ if (dlen == 0)
+ return 1;
+ data += nleft;
+ /* Else not final block so encrypt it */
+ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl))
+ return 0;
+ }
+ /* Encrypt all but one of the complete blocks left */
+ while (dlen > bl) {
+ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
+ return 0;
+ dlen -= bl;
+ data += bl;
+ }
+ /* Copy any data left to last block buffer */
+ memcpy(ctx->last_block, data, dlen);
+ ctx->nlast_block = dlen;
+ return 1;
+
+}
+
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
+{
+ int i, bl, lb;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->cctx.engine)
+ return FIPS_cmac_final(ctx, out, poutlen);
+#endif
+ if (ctx->nlast_block == -1)
+ return 0;
+ bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+ *poutlen = (size_t)bl;
+ if (!out)
+ return 1;
+ lb = ctx->nlast_block;
+ /* Is last block complete? */
+ if (lb == bl) {
+ for (i = 0; i < bl; i++)
+ out[i] = ctx->last_block[i] ^ ctx->k1[i];
+ } else {
+ ctx->last_block[lb] = 0x80;
+ if (bl - lb > 1)
+ memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
+ for (i = 0; i < bl; i++)
+ out[i] = ctx->last_block[i] ^ ctx->k2[i];
+ }
+ if (!EVP_Cipher(&ctx->cctx, out, out, bl)) {
+ OPENSSL_cleanse(out, bl);
+ return 0;
+ }
+ return 1;
+}
+
+int CMAC_resume(CMAC_CTX *ctx)
+{
+ if (ctx->nlast_block == -1)
+ return 0;
+ /*
+ * The buffer "tbl" containes the last fully encrypted block which is the
+ * last IV (or all zeroes if no last encrypted block). The last block has
+ * not been modified since CMAC_final(). So reinitliasing using the last
+ * decrypted block will allow CMAC to continue after calling
+ * CMAC_Final().
+ */
+ return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
+}
diff --git a/Cryptlib/OpenSSL/crypto/comp/c_rle.c b/Cryptlib/OpenSSL/crypto/comp/c_rle.c
new file mode 100644
index 00000000..e9aabbd1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/comp/c_rle.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen);
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen);
+
+static COMP_METHOD rle_method = {
+ NID_rle_compression,
+ LN_rle_compression,
+ NULL,
+ NULL,
+ rle_compress_block,
+ rle_expand_block,
+ NULL,
+ NULL,
+};
+
+COMP_METHOD *COMP_rle(void)
+{
+ return (&rle_method);
+}
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen)
+{
+ /* int i; */
+
+ if (ilen == 0 || olen < (ilen - 1)) {
+ /* ZZZZZZZZZZZZZZZZZZZZZZ */
+ return (-1);
+ }
+
+ *(out++) = 0;
+ memcpy(out, in, ilen);
+ return (ilen + 1);
+}
+
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen)
+{
+ int i;
+
+ if (olen < (ilen - 1)) {
+ /* ZZZZZZZZZZZZZZZZZZZZZZ */
+ return (-1);
+ }
+
+ i = *(in++);
+ if (i == 0) {
+ memcpy(out, in, ilen - 1);
+ }
+ return (ilen - 1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/comp/c_zlib.c b/Cryptlib/OpenSSL/crypto/comp/c_zlib.c
new file mode 100644
index 00000000..9c32614d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/comp/c_zlib.c
@@ -0,0 +1,763 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+#include <openssl/err.h>
+
+COMP_METHOD *COMP_zlib(void);
+
+static COMP_METHOD zlib_method_nozlib = {
+ NID_undef,
+ "(undef)",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#ifndef ZLIB
+# undef ZLIB_SHARED
+#else
+
+# include <zlib.h>
+
+static int zlib_stateful_init(COMP_CTX *ctx);
+static void zlib_stateful_finish(COMP_CTX *ctx);
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen);
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen);
+
+/* memory allocations functions for zlib intialization */
+static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
+{
+ void *p;
+
+ p = OPENSSL_malloc(no * size);
+ if (p)
+ memset(p, 0, no * size);
+ return p;
+}
+
+static void zlib_zfree(void *opaque, void *address)
+{
+ OPENSSL_free(address);
+}
+
+# if 0
+static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen);
+static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen);
+
+static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source,
+ uLong sourceLen);
+
+static COMP_METHOD zlib_stateless_method = {
+ NID_zlib_compression,
+ LN_zlib_compression,
+ NULL,
+ NULL,
+ zlib_compress_block,
+ zlib_expand_block,
+ NULL,
+ NULL,
+};
+# endif
+
+static COMP_METHOD zlib_stateful_method = {
+ NID_zlib_compression,
+ LN_zlib_compression,
+ zlib_stateful_init,
+ zlib_stateful_finish,
+ zlib_stateful_compress_block,
+ zlib_stateful_expand_block,
+ NULL,
+ NULL,
+};
+
+/*
+ * When OpenSSL is built on Windows, we do not want to require that
+ * the ZLIB.DLL be available in order for the OpenSSL DLLs to
+ * work. Therefore, all ZLIB routines are loaded at run time
+ * and we do not link to a .LIB file when ZLIB_SHARED is set.
+ */
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+# include <windows.h>
+# endif /* !(OPENSSL_SYS_WINDOWS ||
+ * OPENSSL_SYS_WIN32) */
+
+# ifdef ZLIB_SHARED
+# include <openssl/dso.h>
+
+/* Function pointers */
+typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
+ const Bytef *source, uLong sourceLen);
+typedef int (*inflateEnd_ft) (z_streamp strm);
+typedef int (*inflate_ft) (z_streamp strm, int flush);
+typedef int (*inflateInit__ft) (z_streamp strm,
+ const char *version, int stream_size);
+typedef int (*deflateEnd_ft) (z_streamp strm);
+typedef int (*deflate_ft) (z_streamp strm, int flush);
+typedef int (*deflateInit__ft) (z_streamp strm, int level,
+ const char *version, int stream_size);
+typedef const char *(*zError__ft) (int err);
+static compress_ft p_compress = NULL;
+static inflateEnd_ft p_inflateEnd = NULL;
+static inflate_ft p_inflate = NULL;
+static inflateInit__ft p_inflateInit_ = NULL;
+static deflateEnd_ft p_deflateEnd = NULL;
+static deflate_ft p_deflate = NULL;
+static deflateInit__ft p_deflateInit_ = NULL;
+static zError__ft p_zError = NULL;
+
+static int zlib_loaded = 0; /* only attempt to init func pts once */
+static DSO *zlib_dso = NULL;
+
+# define compress p_compress
+# define inflateEnd p_inflateEnd
+# define inflate p_inflate
+# define inflateInit_ p_inflateInit_
+# define deflateEnd p_deflateEnd
+# define deflate p_deflate
+# define deflateInit_ p_deflateInit_
+# define zError p_zError
+# endif /* ZLIB_SHARED */
+
+struct zlib_state {
+ z_stream istream;
+ z_stream ostream;
+};
+
+static int zlib_stateful_ex_idx = -1;
+
+static int zlib_stateful_init(COMP_CTX *ctx)
+{
+ int err;
+ struct zlib_state *state =
+ (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
+
+ if (state == NULL)
+ goto err;
+
+ state->istream.zalloc = zlib_zalloc;
+ state->istream.zfree = zlib_zfree;
+ state->istream.opaque = Z_NULL;
+ state->istream.next_in = Z_NULL;
+ state->istream.next_out = Z_NULL;
+ state->istream.avail_in = 0;
+ state->istream.avail_out = 0;
+ err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
+ if (err != Z_OK)
+ goto err;
+
+ state->ostream.zalloc = zlib_zalloc;
+ state->ostream.zfree = zlib_zfree;
+ state->ostream.opaque = Z_NULL;
+ state->ostream.next_in = Z_NULL;
+ state->ostream.next_out = Z_NULL;
+ state->ostream.avail_in = 0;
+ state->ostream.avail_out = 0;
+ err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
+ ZLIB_VERSION, sizeof(z_stream));
+ if (err != Z_OK)
+ goto err;
+
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
+ CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state);
+ return 1;
+ err:
+ if (state)
+ OPENSSL_free(state);
+ return 0;
+}
+
+static void zlib_stateful_finish(COMP_CTX *ctx)
+{
+ struct zlib_state *state =
+ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+ zlib_stateful_ex_idx);
+ inflateEnd(&state->istream);
+ deflateEnd(&state->ostream);
+ OPENSSL_free(state);
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
+}
+
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen)
+{
+ int err = Z_OK;
+ struct zlib_state *state =
+ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+ zlib_stateful_ex_idx);
+
+ if (state == NULL)
+ return -1;
+
+ state->ostream.next_in = in;
+ state->ostream.avail_in = ilen;
+ state->ostream.next_out = out;
+ state->ostream.avail_out = olen;
+ if (ilen > 0)
+ err = deflate(&state->ostream, Z_SYNC_FLUSH);
+ if (err != Z_OK)
+ return -1;
+# ifdef DEBUG_ZLIB
+ fprintf(stderr, "compress(%4d)->%4d %s\n",
+ ilen, olen - state->ostream.avail_out,
+ (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear");
+# endif
+ return olen - state->ostream.avail_out;
+}
+
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen)
+{
+ int err = Z_OK;
+
+ struct zlib_state *state =
+ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+ zlib_stateful_ex_idx);
+
+ if (state == NULL)
+ return 0;
+
+ state->istream.next_in = in;
+ state->istream.avail_in = ilen;
+ state->istream.next_out = out;
+ state->istream.avail_out = olen;
+ if (ilen > 0)
+ err = inflate(&state->istream, Z_SYNC_FLUSH);
+ if (err != Z_OK)
+ return -1;
+# ifdef DEBUG_ZLIB
+ fprintf(stderr, "expand(%4d)->%4d %s\n",
+ ilen, olen - state->istream.avail_out,
+ (ilen != olen - state->istream.avail_out) ? "zlib" : "clear");
+# endif
+ return olen - state->istream.avail_out;
+}
+
+# if 0
+static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen)
+{
+ unsigned long l;
+ int i;
+ int clear = 1;
+
+ if (ilen > 128) {
+ out[0] = 1;
+ l = olen - 1;
+ i = compress(&(out[1]), &l, in, (unsigned long)ilen);
+ if (i != Z_OK)
+ return (-1);
+ if (ilen > l) {
+ clear = 0;
+ l++;
+ }
+ }
+ if (clear) {
+ out[0] = 0;
+ memcpy(&(out[1]), in, ilen);
+ l = ilen + 1;
+ }
+# ifdef DEBUG_ZLIB
+ fprintf(stderr, "compress(%4d)->%4d %s\n",
+ ilen, (int)l, (clear) ? "clear" : "zlib");
+# endif
+ return ((int)l);
+}
+
+static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in,
+ unsigned int ilen)
+{
+ unsigned long l;
+ int i;
+
+ if (in[0]) {
+ l = olen;
+ i = zz_uncompress(out, &l, &(in[1]), (unsigned long)ilen - 1);
+ if (i != Z_OK)
+ return (-1);
+ } else {
+ memcpy(out, &(in[1]), ilen - 1);
+ l = ilen - 1;
+ }
+# ifdef DEBUG_ZLIB
+ fprintf(stderr, "expand (%4d)->%4d %s\n",
+ ilen, (int)l, in[0] ? "zlib" : "clear");
+# endif
+ return ((int)l);
+}
+
+static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source,
+ uLong sourceLen)
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef *)source;
+ stream.avail_in = (uInt) sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong) stream.avail_in != sourceLen)
+ return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt) * destLen;
+ if ((uLong) stream.avail_out != *destLen)
+ return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func) 0;
+ stream.zfree = (free_func) 0;
+
+ err = inflateInit_(&stream, ZLIB_VERSION, sizeof(z_stream));
+ if (err != Z_OK)
+ return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
+# endif
+
+#endif
+
+COMP_METHOD *COMP_zlib(void)
+{
+ COMP_METHOD *meth = &zlib_method_nozlib;
+
+#ifdef ZLIB_SHARED
+ if (!zlib_loaded) {
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+ zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
+# else
+ zlib_dso = DSO_load(NULL, "z", NULL, 0);
+# endif
+ if (zlib_dso != NULL) {
+ p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
+ p_inflateEnd
+ = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
+ p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
+ p_inflateInit_
+ = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
+ p_deflateEnd
+ = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
+ p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
+ p_deflateInit_
+ = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
+ p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
+
+ if (p_compress && p_inflateEnd && p_inflate
+ && p_inflateInit_ && p_deflateEnd
+ && p_deflate && p_deflateInit_ && p_zError)
+ zlib_loaded++;
+ }
+ }
+#endif
+#ifdef ZLIB_SHARED
+ if (zlib_loaded)
+#endif
+#if defined(ZLIB) || defined(ZLIB_SHARED)
+ {
+ /*
+ * init zlib_stateful_ex_idx here so that in a multi-process
+ * application it's enough to intialize openssl before forking (idx
+ * will be inherited in all the children)
+ */
+ if (zlib_stateful_ex_idx == -1) {
+ CRYPTO_w_lock(CRYPTO_LOCK_COMP);
+ if (zlib_stateful_ex_idx == -1)
+ zlib_stateful_ex_idx =
+ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
+ 0, NULL, NULL, NULL, NULL);
+ CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
+ if (zlib_stateful_ex_idx == -1)
+ goto err;
+ }
+
+ meth = &zlib_stateful_method;
+ }
+ err:
+#endif
+
+ return (meth);
+}
+
+void COMP_zlib_cleanup(void)
+{
+#ifdef ZLIB_SHARED
+ if (zlib_dso != NULL)
+ DSO_free(zlib_dso);
+ zlib_dso = NULL;
+#endif
+}
+
+#ifdef ZLIB
+
+/* Zlib based compression/decompression filter BIO */
+
+typedef struct {
+ unsigned char *ibuf; /* Input buffer */
+ int ibufsize; /* Buffer size */
+ z_stream zin; /* Input decompress context */
+ unsigned char *obuf; /* Output buffer */
+ int obufsize; /* Output buffer size */
+ unsigned char *optr; /* Position in output buffer */
+ int ocount; /* Amount of data in output buffer */
+ int odone; /* deflate EOF */
+ int comp_level; /* Compression level to use */
+ z_stream zout; /* Output compression context */
+} BIO_ZLIB_CTX;
+
+# define ZLIB_DEFAULT_BUFSIZE 1024
+
+static int bio_zlib_new(BIO *bi);
+static int bio_zlib_free(BIO *bi);
+static int bio_zlib_read(BIO *b, char *out, int outl);
+static int bio_zlib_write(BIO *b, const char *in, int inl);
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD bio_meth_zlib = {
+ BIO_TYPE_COMP,
+ "zlib",
+ bio_zlib_write,
+ bio_zlib_read,
+ NULL,
+ NULL,
+ bio_zlib_ctrl,
+ bio_zlib_new,
+ bio_zlib_free,
+ bio_zlib_callback_ctrl
+};
+
+BIO_METHOD *BIO_f_zlib(void)
+{
+ return &bio_meth_zlib;
+}
+
+static int bio_zlib_new(BIO *bi)
+{
+ BIO_ZLIB_CTX *ctx;
+# ifdef ZLIB_SHARED
+ (void)COMP_zlib();
+ if (!zlib_loaded) {
+ COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
+ return 0;
+ }
+# endif
+ ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
+ if (!ctx) {
+ COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ctx->ibuf = NULL;
+ ctx->obuf = NULL;
+ ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
+ ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
+ ctx->zin.zalloc = Z_NULL;
+ ctx->zin.zfree = Z_NULL;
+ ctx->zin.next_in = NULL;
+ ctx->zin.avail_in = 0;
+ ctx->zin.next_out = NULL;
+ ctx->zin.avail_out = 0;
+ ctx->zout.zalloc = Z_NULL;
+ ctx->zout.zfree = Z_NULL;
+ ctx->zout.next_in = NULL;
+ ctx->zout.avail_in = 0;
+ ctx->zout.next_out = NULL;
+ ctx->zout.avail_out = 0;
+ ctx->odone = 0;
+ ctx->comp_level = Z_DEFAULT_COMPRESSION;
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return 1;
+}
+
+static int bio_zlib_free(BIO *bi)
+{
+ BIO_ZLIB_CTX *ctx;
+ if (!bi)
+ return 0;
+ ctx = (BIO_ZLIB_CTX *) bi->ptr;
+ if (ctx->ibuf) {
+ /* Destroy decompress context */
+ inflateEnd(&ctx->zin);
+ OPENSSL_free(ctx->ibuf);
+ }
+ if (ctx->obuf) {
+ /* Destroy compress context */
+ deflateEnd(&ctx->zout);
+ OPENSSL_free(ctx->obuf);
+ }
+ OPENSSL_free(ctx);
+ bi->ptr = NULL;
+ bi->init = 0;
+ bi->flags = 0;
+ return 1;
+}
+
+static int bio_zlib_read(BIO *b, char *out, int outl)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret;
+ z_stream *zin;
+ if (!out || !outl)
+ return 0;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ zin = &ctx->zin;
+ BIO_clear_retry_flags(b);
+ if (!ctx->ibuf) {
+ ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
+ if (!ctx->ibuf) {
+ COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ inflateInit(zin);
+ zin->next_in = ctx->ibuf;
+ zin->avail_in = 0;
+ }
+
+ /* Copy output data directly to supplied buffer */
+ zin->next_out = (unsigned char *)out;
+ zin->avail_out = (unsigned int)outl;
+ for (;;) {
+ /* Decompress while data available */
+ while (zin->avail_in) {
+ ret = inflate(zin, 0);
+ if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+ COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
+ ERR_add_error_data(2, "zlib error:", zError(ret));
+ return 0;
+ }
+ /* If EOF or we've read everything then return */
+ if ((ret == Z_STREAM_END) || !zin->avail_out)
+ return outl - zin->avail_out;
+ }
+
+ /*
+ * No data in input buffer try to read some in, if an error then
+ * return the total data read.
+ */
+ ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
+ if (ret <= 0) {
+ /* Total data read */
+ int tot = outl - zin->avail_out;
+ BIO_copy_next_retry(b);
+ if (ret < 0)
+ return (tot > 0) ? tot : ret;
+ return tot;
+ }
+ zin->avail_in = ret;
+ zin->next_in = ctx->ibuf;
+ }
+}
+
+static int bio_zlib_write(BIO *b, const char *in, int inl)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret;
+ z_stream *zout;
+ if (!in || !inl)
+ return 0;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ if (ctx->odone)
+ return 0;
+ zout = &ctx->zout;
+ BIO_clear_retry_flags(b);
+ if (!ctx->obuf) {
+ ctx->obuf = OPENSSL_malloc(ctx->obufsize);
+ /* Need error here */
+ if (!ctx->obuf) {
+ COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ctx->optr = ctx->obuf;
+ ctx->ocount = 0;
+ deflateInit(zout, ctx->comp_level);
+ zout->next_out = ctx->obuf;
+ zout->avail_out = ctx->obufsize;
+ }
+ /* Obtain input data directly from supplied buffer */
+ zout->next_in = (void *)in;
+ zout->avail_in = inl;
+ for (;;) {
+ /* If data in output buffer write it first */
+ while (ctx->ocount) {
+ ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+ if (ret <= 0) {
+ /* Total data written */
+ int tot = inl - zout->avail_in;
+ BIO_copy_next_retry(b);
+ if (ret < 0)
+ return (tot > 0) ? tot : ret;
+ return tot;
+ }
+ ctx->optr += ret;
+ ctx->ocount -= ret;
+ }
+
+ /* Have we consumed all supplied data? */
+ if (!zout->avail_in)
+ return inl;
+
+ /* Compress some more */
+
+ /* Reset buffer */
+ ctx->optr = ctx->obuf;
+ zout->next_out = ctx->obuf;
+ zout->avail_out = ctx->obufsize;
+ /* Compress some more */
+ ret = deflate(zout, 0);
+ if (ret != Z_OK) {
+ COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
+ ERR_add_error_data(2, "zlib error:", zError(ret));
+ return 0;
+ }
+ ctx->ocount = ctx->obufsize - zout->avail_out;
+ }
+}
+
+static int bio_zlib_flush(BIO *b)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret;
+ z_stream *zout;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ /* If no data written or already flush show success */
+ if (!ctx->obuf || (ctx->odone && !ctx->ocount))
+ return 1;
+ zout = &ctx->zout;
+ BIO_clear_retry_flags(b);
+ /* No more input data */
+ zout->next_in = NULL;
+ zout->avail_in = 0;
+ for (;;) {
+ /* If data in output buffer write it first */
+ while (ctx->ocount) {
+ ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+ if (ret <= 0) {
+ BIO_copy_next_retry(b);
+ return ret;
+ }
+ ctx->optr += ret;
+ ctx->ocount -= ret;
+ }
+ if (ctx->odone)
+ return 1;
+
+ /* Compress some more */
+
+ /* Reset buffer */
+ ctx->optr = ctx->obuf;
+ zout->next_out = ctx->obuf;
+ zout->avail_out = ctx->obufsize;
+ /* Compress some more */
+ ret = deflate(zout, Z_FINISH);
+ if (ret == Z_STREAM_END)
+ ctx->odone = 1;
+ else if (ret != Z_OK) {
+ COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
+ ERR_add_error_data(2, "zlib error:", zError(ret));
+ return 0;
+ }
+ ctx->ocount = ctx->obufsize - zout->avail_out;
+ }
+}
+
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret, *ip;
+ int ibs, obs;
+ if (!b->next_bio)
+ return 0;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ switch (cmd) {
+
+ case BIO_CTRL_RESET:
+ ctx->ocount = 0;
+ ctx->odone = 0;
+ ret = 1;
+ break;
+
+ case BIO_CTRL_FLUSH:
+ ret = bio_zlib_flush(b);
+ if (ret > 0)
+ ret = BIO_flush(b->next_bio);
+ break;
+
+ case BIO_C_SET_BUFF_SIZE:
+ ibs = -1;
+ obs = -1;
+ if (ptr != NULL) {
+ ip = ptr;
+ if (*ip == 0)
+ ibs = (int)num;
+ else
+ obs = (int)num;
+ } else {
+ ibs = (int)num;
+ obs = ibs;
+ }
+
+ if (ibs != -1) {
+ if (ctx->ibuf) {
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = NULL;
+ }
+ ctx->ibufsize = ibs;
+ }
+
+ if (obs != -1) {
+ if (ctx->obuf) {
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf = NULL;
+ }
+ ctx->obufsize = obs;
+ }
+ ret = 1;
+ break;
+
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ }
+
+ return ret;
+}
+
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ if (!b->next_bio)
+ return 0;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/comp/comp_err.c b/Cryptlib/OpenSSL/crypto/comp/comp_err.c
new file mode 100644
index 00000000..8ca159b6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/comp/comp_err.c
@@ -0,0 +1,98 @@
+/* crypto/comp/comp_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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/comp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason)
+
+static ERR_STRING_DATA COMP_str_functs[] = {
+ {ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH), "BIO_ZLIB_FLUSH"},
+ {ERR_FUNC(COMP_F_BIO_ZLIB_NEW), "BIO_ZLIB_NEW"},
+ {ERR_FUNC(COMP_F_BIO_ZLIB_READ), "BIO_ZLIB_READ"},
+ {ERR_FUNC(COMP_F_BIO_ZLIB_WRITE), "BIO_ZLIB_WRITE"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA COMP_str_reasons[] = {
+ {ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"},
+ {ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"},
+ {ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_COMP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, COMP_str_functs);
+ ERR_load_strings(0, COMP_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/comp/comp_lib.c b/Cryptlib/OpenSSL/crypto/comp/comp_lib.c
new file mode 100644
index 00000000..bd4eb7a1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/comp/comp_lib.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth)
+{
+ COMP_CTX *ret;
+
+ if ((ret = (COMP_CTX *)OPENSSL_malloc(sizeof(COMP_CTX))) == NULL) {
+ /* ZZZZZZZZZZZZZZZZ */
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(COMP_CTX));
+ ret->meth = meth;
+ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+ return (ret);
+}
+
+void COMP_CTX_free(COMP_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ if (ctx->meth->finish != NULL)
+ ctx->meth->finish(ctx);
+
+ OPENSSL_free(ctx);
+}
+
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+ unsigned char *in, int ilen)
+{
+ int ret;
+ if (ctx->meth->compress == NULL) {
+ /* ZZZZZZZZZZZZZZZZZ */
+ return (-1);
+ }
+ ret = ctx->meth->compress(ctx, out, olen, in, ilen);
+ if (ret > 0) {
+ ctx->compress_in += ilen;
+ ctx->compress_out += ret;
+ }
+ return (ret);
+}
+
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+ unsigned char *in, int ilen)
+{
+ int ret;
+
+ if (ctx->meth->expand == NULL) {
+ /* ZZZZZZZZZZZZZZZZZ */
+ return (-1);
+ }
+ ret = ctx->meth->expand(ctx, out, olen, in, ilen);
+ if (ret > 0) {
+ ctx->expand_in += ilen;
+ ctx->expand_out += ret;
+ }
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_api.c b/Cryptlib/OpenSSL/crypto/conf/conf_api.c
new file mode 100644
index 00000000..4cf75533
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_api.c
@@ -0,0 +1,305 @@
+/* conf_api.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.]
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#ifndef CONF_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include "e_os.h"
+
+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)
+{
+ CONF_VALUE *v, vv;
+
+ if ((conf == NULL) || (section == NULL))
+ return (NULL);
+ vv.name = NULL;
+ vv.section = (char *)section;
+ v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+ return (v);
+}
+
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+ const char *section)
+{
+ CONF_VALUE *v;
+
+ v = _CONF_get_section(conf, section);
+ if (v != NULL)
+ return ((STACK_OF(CONF_VALUE) *)v->value);
+ else
+ return (NULL);
+}
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
+{
+ CONF_VALUE *v = NULL;
+ STACK_OF(CONF_VALUE) *ts;
+
+ ts = (STACK_OF(CONF_VALUE) *)section->value;
+
+ value->section = section->section;
+ if (!sk_CONF_VALUE_push(ts, value)) {
+ return 0;
+ }
+
+ v = lh_CONF_VALUE_insert(conf->data, value);
+ if (v != NULL) {
+ (void)sk_CONF_VALUE_delete_ptr(ts, v);
+ OPENSSL_free(v->name);
+ OPENSSL_free(v->value);
+ OPENSSL_free(v);
+ }
+ return 1;
+}
+
+char *_CONF_get_string(const CONF *conf, const char *section,
+ const char *name)
+{
+ CONF_VALUE *v, vv;
+ char *p;
+
+ if (name == NULL)
+ return (NULL);
+ if (conf != NULL) {
+ if (section != NULL) {
+ vv.name = (char *)name;
+ vv.section = (char *)section;
+ v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+ if (v != NULL)
+ return (v->value);
+ if (strcmp(section, "ENV") == 0) {
+ p = getenv(name);
+ if (p != NULL)
+ return (p);
+ }
+ }
+ vv.section = "default";
+ vv.name = (char *)name;
+ v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+ if (v != NULL)
+ return (v->value);
+ else
+ return (NULL);
+ } else
+ return (getenv(name));
+}
+
+#if 0 /* There's no way to provide error checking
+ * with this function, so force implementors
+ * of the higher levels to get a string and
+ * read the number themselves. */
+long _CONF_get_number(CONF *conf, char *section, char *name)
+{
+ char *str;
+ long ret = 0;
+
+ str = _CONF_get_string(conf, section, name);
+ if (str == NULL)
+ return (0);
+ for (;;) {
+ if (conf->meth->is_number(conf, *str))
+ ret = ret * 10 + conf->meth->to_int(conf, *str);
+ else
+ return (ret);
+ str++;
+ }
+}
+#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) {
+ return 0;
+ }
+ if (conf->data == NULL)
+ if ((conf->data = lh_CONF_VALUE_new()) == NULL) {
+ return 0;
+ }
+ return 1;
+}
+
+void _CONF_free_data(CONF *conf)
+{
+ if (conf == NULL || conf->data == NULL)
+ return;
+
+ 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_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
+ lh_CONF_VALUE_free(conf->data);
+}
+
+static void value_free_hash_doall_arg(CONF_VALUE *a,
+ LHASH_OF(CONF_VALUE) *conf)
+{
+ if (a->name != NULL)
+ (void)lh_CONF_VALUE_delete(conf, a);
+}
+
+static void value_free_stack_doall(CONF_VALUE *a)
+{
+ CONF_VALUE *vv;
+ STACK_OF(CONF_VALUE) *sk;
+ int i;
+
+ if (a->name != NULL)
+ return;
+
+ sk = (STACK_OF(CONF_VALUE) *)a->value;
+ for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
+ vv = sk_CONF_VALUE_value(sk, i);
+ OPENSSL_free(vv->value);
+ OPENSSL_free(vv->name);
+ OPENSSL_free(vv);
+ }
+ if (sk != NULL)
+ sk_CONF_VALUE_free(sk);
+ OPENSSL_free(a->section);
+ OPENSSL_free(a);
+}
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
+{
+ STACK_OF(CONF_VALUE) *sk = NULL;
+ int ok = 0, i;
+ CONF_VALUE *v = NULL, *vv;
+
+ if ((sk = sk_CONF_VALUE_new_null()) == NULL)
+ goto err;
+ if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
+ goto err;
+ i = strlen(section) + 1;
+ if ((v->section = OPENSSL_malloc(i)) == NULL)
+ goto err;
+
+ memcpy(v->section, section, i);
+ v->name = NULL;
+ v->value = (char *)sk;
+
+ vv = lh_CONF_VALUE_insert(conf->data, v);
+ OPENSSL_assert(vv == NULL);
+ ok = 1;
+ err:
+ if (!ok) {
+ if (sk != NULL)
+ sk_CONF_VALUE_free(sk);
+ if (v != NULL)
+ OPENSSL_free(v);
+ v = NULL;
+ }
+ return (v);
+}
+
+IMPLEMENT_STACK_OF(CONF_VALUE)
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_def.c b/Cryptlib/OpenSSL/crypto/conf/conf_def.c
new file mode 100644
index 00000000..3d308c7e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_def.c
@@ -0,0 +1,711 @@
+/* crypto/conf/conf.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.]
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include "conf_def.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static char *eat_ws(CONF *conf, char *p);
+static char *eat_alpha_numeric(CONF *conf, char *p);
+static void clear_comments(CONF *conf, char *p);
+static int str_copy(CONF *conf, char *section, char **to, char *from);
+static char *scan_quote(CONF *conf, char *p);
+static char *scan_dquote(CONF *conf, char *p);
+#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
+
+static CONF *def_create(CONF_METHOD *meth);
+static int def_init_default(CONF *conf);
+static int def_init_WIN32(CONF *conf);
+static int def_destroy(CONF *conf);
+static int def_destroy_data(CONF *conf);
+static int def_load(CONF *conf, const char *name, long *eline);
+static int def_load_bio(CONF *conf, BIO *bp, long *eline);
+static int def_dump(const CONF *conf, BIO *bp);
+static int def_is_number(const CONF *conf, char c);
+static int def_to_int(const CONF *conf, char c);
+
+const char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT;
+
+static CONF_METHOD default_method = {
+ "OpenSSL default",
+ def_create,
+ def_init_default,
+ def_destroy,
+ def_destroy_data,
+ def_load_bio,
+ def_dump,
+ def_is_number,
+ def_to_int,
+ def_load
+};
+
+static CONF_METHOD WIN32_method = {
+ "WIN32",
+ def_create,
+ def_init_WIN32,
+ def_destroy,
+ def_destroy_data,
+ def_load_bio,
+ def_dump,
+ def_is_number,
+ def_to_int,
+ def_load
+};
+
+CONF_METHOD *NCONF_default()
+{
+ return &default_method;
+}
+
+CONF_METHOD *NCONF_WIN32()
+{
+ return &WIN32_method;
+}
+
+static CONF *def_create(CONF_METHOD *meth)
+{
+ CONF *ret;
+
+ ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
+ if (ret)
+ if (meth->init(ret) == 0) {
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+ return ret;
+}
+
+static int def_init_default(CONF *conf)
+{
+ if (conf == NULL)
+ return 0;
+
+ conf->meth = &default_method;
+ conf->meth_data = CONF_type_default;
+ conf->data = NULL;
+
+ return 1;
+}
+
+static int def_init_WIN32(CONF *conf)
+{
+ if (conf == NULL)
+ return 0;
+
+ conf->meth = &WIN32_method;
+ conf->meth_data = (void *)CONF_type_win32;
+ conf->data = NULL;
+
+ return 1;
+}
+
+static int def_destroy(CONF *conf)
+{
+ if (def_destroy_data(conf)) {
+ OPENSSL_free(conf);
+ return 1;
+ }
+ return 0;
+}
+
+static int def_destroy_data(CONF *conf)
+{
+ if (conf == NULL)
+ return 0;
+ _CONF_free_data(conf);
+ return 1;
+}
+
+static int def_load(CONF *conf, const char *name, long *line)
+{
+#ifdef OPENSSL_NO_STDIO
+ CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
+ return 0;
+#else
+ int ret;
+ BIO *in = NULL;
+
+#ifdef OPENSSL_SYS_VMS
+ in = BIO_new_file(name, "r");
+#else
+ in = BIO_new_file(name, "rb");
+#endif
+ if (in == NULL) {
+ if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
+ CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
+ else
+ CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
+ return 0;
+ }
+
+ ret = def_load_bio(conf, in, line);
+ BIO_free(in);
+
+ return ret;
+#endif
+}
+
+static int def_load_bio(CONF *conf, BIO *in, long *line)
+{
+/* The macro BUFSIZE conflicts with a system macro in VxWorks */
+#define CONFBUFSIZE 512
+ int bufnum = 0, i, ii;
+ BUF_MEM *buff = NULL;
+ char *s, *p, *end;
+ int again;
+ long eline = 0;
+ char btmp[DECIMAL_SIZE(eline) + 1];
+ CONF_VALUE *v = NULL, *tv;
+ CONF_VALUE *sv = NULL;
+ char *section = NULL, *buf;
+ char *start, *psection, *pname;
+ void *h = (void *)(conf->data);
+
+ if ((buff = BUF_MEM_new()) == NULL) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
+ goto err;
+ }
+
+ section = BUF_strdup("default");
+ if (section == NULL) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (_CONF_new_data(conf) == 0) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ sv = _CONF_new_section(conf, section);
+ if (sv == NULL) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ goto err;
+ }
+
+ bufnum = 0;
+ again = 0;
+ for (;;) {
+ if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
+ goto err;
+ }
+ p = &(buff->data[bufnum]);
+ *p = '\0';
+ BIO_gets(in, p, CONFBUFSIZE - 1);
+ p[CONFBUFSIZE - 1] = '\0';
+ ii = i = strlen(p);
+ if (i == 0 && !again)
+ break;
+ again = 0;
+ while (i > 0) {
+ if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
+ break;
+ else
+ i--;
+ }
+ /*
+ * we removed some trailing stuff so there is a new line on the end.
+ */
+ if (ii && i == ii)
+ again = 1; /* long line */
+ else {
+ p[i] = '\0';
+ eline++; /* another input line */
+ }
+
+ /* we now have a line with trailing \r\n removed */
+
+ /* i is the number of bytes */
+ bufnum += i;
+
+ v = NULL;
+ /* check for line continuation */
+ if (bufnum >= 1) {
+ /*
+ * If we have bytes and the last char '\\' and second last char
+ * is not '\\'
+ */
+ p = &(buff->data[bufnum - 1]);
+ if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
+ bufnum--;
+ again = 1;
+ }
+ }
+ if (again)
+ continue;
+ bufnum = 0;
+ buf = buff->data;
+
+ clear_comments(conf, buf);
+ s = eat_ws(conf, buf);
+ if (IS_EOF(conf, *s))
+ continue; /* blank line */
+ if (*s == '[') {
+ char *ss;
+
+ s++;
+ start = eat_ws(conf, s);
+ ss = start;
+ again:
+ end = eat_alpha_numeric(conf, ss);
+ p = eat_ws(conf, end);
+ if (*p != ']') {
+ if (*p != '\0' && ss != p) {
+ ss = p;
+ goto again;
+ }
+ CONFerr(CONF_F_DEF_LOAD_BIO,
+ CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+ goto err;
+ }
+ *end = '\0';
+ if (!str_copy(conf, NULL, &section, start))
+ goto err;
+ if ((sv = _CONF_get_section(conf, section)) == NULL)
+ sv = _CONF_new_section(conf, section);
+ if (sv == NULL) {
+ CONFerr(CONF_F_DEF_LOAD_BIO,
+ CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ goto err;
+ }
+ continue;
+ } else {
+ pname = s;
+ psection = NULL;
+ end = eat_alpha_numeric(conf, s);
+ if ((end[0] == ':') && (end[1] == ':')) {
+ *end = '\0';
+ end += 2;
+ psection = pname;
+ pname = end;
+ end = eat_alpha_numeric(conf, end);
+ }
+ p = eat_ws(conf, end);
+ if (*p != '=') {
+ CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
+ goto err;
+ }
+ *end = '\0';
+ p++;
+ start = eat_ws(conf, p);
+ while (!IS_EOF(conf, *p))
+ p++;
+ p--;
+ while ((p != start) && (IS_WS(conf, *p)))
+ p--;
+ p++;
+ *p = '\0';
+
+ if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (psection == NULL)
+ psection = section;
+ v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
+ v->value = NULL;
+ if (v->name == NULL) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ BUF_strlcpy(v->name, pname, strlen(pname) + 1);
+ if (!str_copy(conf, psection, &(v->value), start))
+ goto err;
+
+ if (strcmp(psection, section) != 0) {
+ if ((tv = _CONF_get_section(conf, psection))
+ == NULL)
+ tv = _CONF_new_section(conf, psection);
+ if (tv == NULL) {
+ CONFerr(CONF_F_DEF_LOAD_BIO,
+ CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ goto err;
+ }
+ } else
+ tv = sv;
+#if 1
+ if (_CONF_add_string(conf, tv, v) == 0) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+#else
+ v->section = tv->section;
+ if (!sk_CONF_VALUE_push(ts, v)) {
+ CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ vv = (CONF_VALUE *)lh_insert(conf->data, v);
+ if (vv != NULL) {
+ sk_CONF_VALUE_delete_ptr(ts, vv);
+ OPENSSL_free(vv->name);
+ OPENSSL_free(vv->value);
+ OPENSSL_free(vv);
+ }
+#endif
+ v = NULL;
+ }
+ }
+ if (buff != NULL)
+ BUF_MEM_free(buff);
+ if (section != NULL)
+ OPENSSL_free(section);
+ return (1);
+ err:
+ if (buff != NULL)
+ BUF_MEM_free(buff);
+ if (section != NULL)
+ OPENSSL_free(section);
+ if (line != NULL)
+ *line = eline;
+ BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
+ ERR_add_error_data(2, "line ", btmp);
+ if ((h != conf->data) && (conf->data != NULL)) {
+ CONF_free(conf->data);
+ conf->data = NULL;
+ }
+ if (v != NULL) {
+ if (v->name != NULL)
+ OPENSSL_free(v->name);
+ if (v->value != NULL)
+ OPENSSL_free(v->value);
+ if (v != NULL)
+ OPENSSL_free(v);
+ }
+ return (0);
+}
+
+static void clear_comments(CONF *conf, char *p)
+{
+ for (;;) {
+ if (IS_FCOMMENT(conf, *p)) {
+ *p = '\0';
+ return;
+ }
+ if (!IS_WS(conf, *p)) {
+ break;
+ }
+ p++;
+ }
+
+ for (;;) {
+ if (IS_COMMENT(conf, *p)) {
+ *p = '\0';
+ return;
+ }
+ if (IS_DQUOTE(conf, *p)) {
+ p = scan_dquote(conf, p);
+ continue;
+ }
+ if (IS_QUOTE(conf, *p)) {
+ p = scan_quote(conf, p);
+ continue;
+ }
+ if (IS_ESC(conf, *p)) {
+ p = scan_esc(conf, p);
+ continue;
+ }
+ if (IS_EOF(conf, *p))
+ return;
+ else
+ p++;
+ }
+}
+
+static int str_copy(CONF *conf, char *section, char **pto, char *from)
+{
+ int q, r, rr = 0, to = 0, len = 0;
+ char *s, *e, *rp, *p, *rrp, *np, *cp, v;
+ BUF_MEM *buf;
+
+ if ((buf = BUF_MEM_new()) == NULL)
+ return (0);
+
+ len = strlen(from) + 1;
+ if (!BUF_MEM_grow(buf, len))
+ goto err;
+
+ for (;;) {
+ if (IS_QUOTE(conf, *from)) {
+ q = *from;
+ from++;
+ while (!IS_EOF(conf, *from) && (*from != q)) {
+ if (IS_ESC(conf, *from)) {
+ from++;
+ if (IS_EOF(conf, *from))
+ break;
+ }
+ buf->data[to++] = *(from++);
+ }
+ if (*from == q)
+ from++;
+ } else if (IS_DQUOTE(conf, *from)) {
+ q = *from;
+ from++;
+ while (!IS_EOF(conf, *from)) {
+ if (*from == q) {
+ if (*(from + 1) == q) {
+ from++;
+ } else {
+ break;
+ }
+ }
+ buf->data[to++] = *(from++);
+ }
+ if (*from == q)
+ from++;
+ } else if (IS_ESC(conf, *from)) {
+ from++;
+ v = *(from++);
+ if (IS_EOF(conf, v))
+ break;
+ else if (v == 'r')
+ v = '\r';
+ else if (v == 'n')
+ v = '\n';
+ else if (v == 'b')
+ v = '\b';
+ else if (v == 't')
+ v = '\t';
+ buf->data[to++] = v;
+ } else if (IS_EOF(conf, *from))
+ break;
+ else if (*from == '$') {
+ /* try to expand it */
+ rrp = NULL;
+ s = &(from[1]);
+ if (*s == '{')
+ q = '}';
+ else if (*s == '(')
+ q = ')';
+ else
+ q = 0;
+
+ if (q)
+ s++;
+ cp = section;
+ e = np = s;
+ while (IS_ALPHA_NUMERIC(conf, *e))
+ e++;
+ if ((e[0] == ':') && (e[1] == ':')) {
+ cp = np;
+ rrp = e;
+ rr = *e;
+ *rrp = '\0';
+ e += 2;
+ np = e;
+ while (IS_ALPHA_NUMERIC(conf, *e))
+ e++;
+ }
+ r = *e;
+ *e = '\0';
+ rp = e;
+ if (q) {
+ if (r != q) {
+ CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
+ goto err;
+ }
+ e++;
+ }
+ /*-
+ * So at this point we have
+ * np which is the start of the name string which is
+ * '\0' terminated.
+ * cp which is the start of the section string which is
+ * '\0' terminated.
+ * e is the 'next point after'.
+ * r and rr are the chars replaced by the '\0'
+ * rp and rrp is where 'r' and 'rr' came from.
+ */
+ p = _CONF_get_string(conf, cp, np);
+ if (rrp != NULL)
+ *rrp = rr;
+ *rp = r;
+ if (p == NULL) {
+ CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
+ goto err;
+ }
+ if (!BUF_MEM_grow_clean(buf,
+ (strlen(p) + buf->length - (e - from)))) {
+ CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ while (*p)
+ buf->data[to++] = *(p++);
+
+ /*
+ * Since we change the pointer 'from', we also have to change the
+ * perceived length of the string it points at. /RL
+ */
+ len -= e - from;
+ from = e;
+
+ /*
+ * In case there were no braces or parenthesis around the
+ * variable reference, we have to put back the character that was
+ * replaced with a '\0'. /RL
+ */
+ *rp = r;
+ } else
+ buf->data[to++] = *(from++);
+ }
+ buf->data[to] = '\0';
+ if (*pto != NULL)
+ OPENSSL_free(*pto);
+ *pto = buf->data;
+ OPENSSL_free(buf);
+ return (1);
+ err:
+ if (buf != NULL)
+ BUF_MEM_free(buf);
+ return (0);
+}
+
+static char *eat_ws(CONF *conf, char *p)
+{
+ while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
+ p++;
+ return (p);
+}
+
+static char *eat_alpha_numeric(CONF *conf, char *p)
+{
+ for (;;) {
+ if (IS_ESC(conf, *p)) {
+ p = scan_esc(conf, p);
+ continue;
+ }
+ if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
+ return (p);
+ p++;
+ }
+}
+
+static char *scan_quote(CONF *conf, char *p)
+{
+ int q = *p;
+
+ p++;
+ while (!(IS_EOF(conf, *p)) && (*p != q)) {
+ if (IS_ESC(conf, *p)) {
+ p++;
+ if (IS_EOF(conf, *p))
+ return (p);
+ }
+ p++;
+ }
+ if (*p == q)
+ p++;
+ return (p);
+}
+
+static char *scan_dquote(CONF *conf, char *p)
+{
+ int q = *p;
+
+ p++;
+ while (!(IS_EOF(conf, *p))) {
+ if (*p == q) {
+ if (*(p + 1) == q) {
+ p++;
+ } else {
+ break;
+ }
+ }
+ p++;
+ }
+ if (*p == q)
+ p++;
+ return (p);
+}
+
+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);
+ else
+ BIO_printf(out, "[[%s]]\n", a->section);
+}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
+
+static int def_dump(const CONF *conf, BIO *out)
+{
+ lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
+ BIO, out);
+ return 1;
+}
+
+static int def_is_number(const CONF *conf, char c)
+{
+ return IS_NUMBER(conf, c);
+}
+
+static int def_to_int(const CONF *conf, char c)
+{
+ return c - '0';
+}
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_def.h b/Cryptlib/OpenSSL/crypto/conf/conf_def.h
new file mode 100644
index 00000000..7d897b89
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_def.h
@@ -0,0 +1,181 @@
+/* crypto/conf/conf_def.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.]
+ */
+
+/*
+ * THIS FILE WAS AUTOMAGICALLY GENERATED! Please modify and use keysets.pl to
+ * regenerate it.
+ */
+
+#define CONF_NUMBER 1
+#define CONF_UPPER 2
+#define CONF_LOWER 4
+#define CONF_UNDER 256
+#define CONF_PUNCTUATION 512
+#define CONF_WS 16
+#define CONF_ESC 32
+#define CONF_QUOTE 64
+#define CONF_DQUOTE 1024
+#define CONF_COMMENT 128
+#define CONF_FCOMMENT 2048
+#define CONF_EOF 8
+#define CONF_HIGHBIT 4096
+#define CONF_ALPHA (CONF_UPPER|CONF_LOWER)
+#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \
+ CONF_PUNCTUATION)
+
+#define KEYTYPES(c) ((unsigned short *)((c)->meth_data))
+#ifndef CHARSET_EBCDIC
+# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
+# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
+# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF)
+# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC)
+# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
+# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS)
+# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+ (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
+# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
+# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
+
+#else /* CHARSET_EBCDIC */
+
+# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
+# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
+# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
+# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
+# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
+# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
+# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+ (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
+# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
+# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
+#endif /* CHARSET_EBCDIC */
+
+static unsigned short CONF_type_default[256] = {
+ 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040,
+ 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
+ 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200,
+ 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100,
+ 0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+};
+
+static unsigned short CONF_type_win32[256] = {
+ 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000,
+ 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
+ 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200,
+ 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100,
+ 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+ 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+};
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_err.c b/Cryptlib/OpenSSL/crypto/conf/conf_err.c
new file mode 100644
index 00000000..bb5e2fe2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_err.c
@@ -0,0 +1,133 @@
+/* crypto/conf/conf_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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason)
+
+static ERR_STRING_DATA CONF_str_functs[] = {
+ {ERR_FUNC(CONF_F_CONF_DUMP_FP), "CONF_dump_fp"},
+ {ERR_FUNC(CONF_F_CONF_LOAD), "CONF_load"},
+ {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"},
+ {ERR_FUNC(CONF_F_MODULE_LOAD_DSO), "MODULE_LOAD_DSO"},
+ {ERR_FUNC(CONF_F_MODULE_RUN), "MODULE_RUN"},
+ {ERR_FUNC(CONF_F_NCONF_DUMP_BIO), "NCONF_dump_bio"},
+ {ERR_FUNC(CONF_F_NCONF_DUMP_FP), "NCONF_dump_fp"},
+ {ERR_FUNC(CONF_F_NCONF_GET_NUMBER), "NCONF_get_number"},
+ {ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E), "NCONF_get_number_e"},
+ {ERR_FUNC(CONF_F_NCONF_GET_SECTION), "NCONF_get_section"},
+ {ERR_FUNC(CONF_F_NCONF_GET_STRING), "NCONF_get_string"},
+ {ERR_FUNC(CONF_F_NCONF_LOAD), "NCONF_load"},
+ {ERR_FUNC(CONF_F_NCONF_LOAD_BIO), "NCONF_load_bio"},
+ {ERR_FUNC(CONF_F_NCONF_LOAD_FP), "NCONF_load_fp"},
+ {ERR_FUNC(CONF_F_NCONF_NEW), "NCONF_new"},
+ {ERR_FUNC(CONF_F_STR_COPY), "STR_COPY"},
+ {0, NULL}
+};
+
+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"},
+ {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"},
+ {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR),
+ "module initialization error"},
+ {ERR_REASON(CONF_R_NO_CLOSE_BRACE), "no close brace"},
+ {ERR_REASON(CONF_R_NO_CONF), "no conf"},
+ {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE),
+ "no conf or environment variable"},
+ {ERR_REASON(CONF_R_NO_SECTION), "no section"},
+ {ERR_REASON(CONF_R_NO_SUCH_FILE), "no such file"},
+ {ERR_REASON(CONF_R_NO_VALUE), "no value"},
+ {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),
+ "unable to create new section"},
+ {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"},
+ {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_CONF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, CONF_str_functs);
+ ERR_load_strings(0, CONF_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_lib.c b/Cryptlib/OpenSSL/crypto/conf/conf_lib.c
new file mode 100644
index 00000000..952b5452
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_lib.c
@@ -0,0 +1,395 @@
+/* conf_lib.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include <openssl/lhash.h>
+
+const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT;
+
+static CONF_METHOD *default_CONF_method = NULL;
+
+/* Init a 'CONF' structure from an old LHASH */
+
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
+{
+ if (default_CONF_method == NULL)
+ default_CONF_method = NCONF_default();
+
+ default_CONF_method->init(conf);
+ conf->data = hash;
+}
+
+/*
+ * The following section contains the "CONF classic" functions, rewritten in
+ * terms of the new CONF interface.
+ */
+
+int CONF_set_default_method(CONF_METHOD *meth)
+{
+ default_CONF_method = meth;
+ return 1;
+}
+
+#ifndef OPENSSL_NO_STDIO
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+ long *eline)
+{
+ LHASH_OF(CONF_VALUE) *ltmp;
+ BIO *in = NULL;
+
+#ifdef OPENSSL_SYS_VMS
+ in = BIO_new_file(file, "r");
+#else
+ in = BIO_new_file(file, "rb");
+#endif
+ if (in == NULL) {
+ CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
+ return NULL;
+ }
+
+ ltmp = CONF_load_bio(conf, in, eline);
+ BIO_free(in);
+
+ return ltmp;
+}
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+ long *eline)
+{
+ BIO *btmp;
+ 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;
+ }
+ ltmp = CONF_load_bio(conf, btmp, eline);
+ BIO_free(btmp);
+ return ltmp;
+}
+#endif
+
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+ long *eline)
+{
+ CONF ctmp;
+ int ret;
+
+ CONF_set_nconf(&ctmp, conf);
+
+ ret = NCONF_load_bio(&ctmp, bp, eline);
+ if (ret)
+ return ctmp.data;
+ return NULL;
+}
+
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+ const char *section)
+{
+ if (conf == NULL) {
+ return NULL;
+ } else {
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ return NCONF_get_section(&ctmp, section);
+ }
+}
+
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
+ const char *name)
+{
+ if (conf == NULL) {
+ return NCONF_get_string(NULL, group, name);
+ } else {
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ return NCONF_get_string(&ctmp, group, name);
+ }
+}
+
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
+ const char *name)
+{
+ int status;
+ long result = 0;
+
+ if (conf == NULL) {
+ status = NCONF_get_number_e(NULL, group, name, &result);
+ } else {
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ status = NCONF_get_number_e(&ctmp, group, name, &result);
+ }
+
+ if (status == 0) {
+ /* This function does not believe in errors... */
+ ERR_clear_error();
+ }
+ return result;
+}
+
+void CONF_free(LHASH_OF(CONF_VALUE) *conf)
+{
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ NCONF_free_data(&ctmp);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
+{
+ BIO *btmp;
+ int ret;
+
+ if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
+ CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
+ return 0;
+ }
+ ret = CONF_dump_bio(conf, btmp);
+ BIO_free(btmp);
+ return ret;
+}
+#endif
+
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
+{
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ return NCONF_dump_bio(&ctmp, out);
+}
+
+/*
+ * The following section contains the "New CONF" functions. They are
+ * completely centralised around a new CONF structure that may contain
+ * basically anything, but at least a method pointer and a table of data.
+ * These functions are also written in terms of the bridge functions used by
+ * the "CONF classic" functions, for consistency.
+ */
+
+CONF *NCONF_new(CONF_METHOD *meth)
+{
+ CONF *ret;
+
+ if (meth == NULL)
+ meth = NCONF_default();
+
+ ret = meth->create(meth);
+ if (ret == NULL) {
+ CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ return ret;
+}
+
+void NCONF_free(CONF *conf)
+{
+ if (conf == NULL)
+ return;
+ conf->meth->destroy(conf);
+}
+
+void NCONF_free_data(CONF *conf)
+{
+ if (conf == NULL)
+ return;
+ conf->meth->destroy_data(conf);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int NCONF_load(CONF *conf, const char *file, long *eline)
+{
+ if (conf == NULL) {
+ CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
+ return 0;
+ }
+
+ return conf->meth->load(conf, file, eline);
+}
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
+{
+ BIO *btmp;
+ int ret;
+ if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+ CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
+ return 0;
+ }
+ ret = NCONF_load_bio(conf, btmp, eline);
+ BIO_free(btmp);
+ return ret;
+}
+#endif
+
+int NCONF_load_bio(CONF *conf, BIO *bp, long *eline)
+{
+ if (conf == NULL) {
+ CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF);
+ return 0;
+ }
+
+ return conf->meth->load_bio(conf, bp, eline);
+}
+
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section)
+{
+ if (conf == NULL) {
+ CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
+ return NULL;
+ }
+
+ if (section == NULL) {
+ CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
+ return NULL;
+ }
+
+ return _CONF_get_section_values(conf, section);
+}
+
+char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
+{
+ char *s = _CONF_get_string(conf, group, name);
+
+ /*
+ * Since we may get a value from an environment variable even if conf is
+ * NULL, let's check the value first
+ */
+ if (s)
+ return s;
+
+ if (conf == NULL) {
+ CONFerr(CONF_F_NCONF_GET_STRING,
+ CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
+ return NULL;
+ }
+ CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE);
+ ERR_add_error_data(4, "group=", group, " name=", name);
+ return NULL;
+}
+
+int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
+ long *result)
+{
+ char *str;
+
+ if (result == NULL) {
+ CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ str = NCONF_get_string(conf, group, name);
+
+ if (str == NULL)
+ return 0;
+
+ for (*result = 0; conf->meth->is_number(conf, *str);) {
+ *result = (*result) * 10 + conf->meth->to_int(conf, *str);
+ str++;
+ }
+
+ return 1;
+}
+
+#ifndef OPENSSL_NO_FP_API
+int NCONF_dump_fp(const CONF *conf, FILE *out)
+{
+ BIO *btmp;
+ int ret;
+ if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
+ CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
+ return 0;
+ }
+ ret = NCONF_dump_bio(conf, btmp);
+ BIO_free(btmp);
+ return ret;
+}
+#endif
+
+int NCONF_dump_bio(const CONF *conf, BIO *out)
+{
+ if (conf == NULL) {
+ CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
+ return 0;
+ }
+
+ return conf->meth->dump(conf, out);
+}
+
+/* This function should be avoided */
+#if 0
+long NCONF_get_number(CONF *conf, char *group, char *name)
+{
+ int status;
+ long ret = 0;
+
+ status = NCONF_get_number_e(conf, group, name, &ret);
+ if (status == 0) {
+ /* This function does not believe in errors... */
+ ERR_get_error();
+ }
+ return ret;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_mall.c b/Cryptlib/OpenSSL/crypto/conf/conf_mall.c
new file mode 100644
index 00000000..b4dbd662
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_mall.c
@@ -0,0 +1,81 @@
+/* conf_mall.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+/* Load all OpenSSL builtin modules */
+
+void OPENSSL_load_builtin_modules(void)
+{
+ /* Add builtin modules here */
+ ASN1_add_oid_module();
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_add_conf_module();
+#endif
+ EVP_add_alg_module();
+}
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_mod.c b/Cryptlib/OpenSSL/crypto/conf/conf_mod.c
new file mode 100644
index 00000000..5e0a482a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_mod.c
@@ -0,0 +1,599 @@
+/* conf_mod.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+
+#define DSO_mod_init_name "OPENSSL_init"
+#define DSO_mod_finish_name "OPENSSL_finish"
+
+/*
+ * This structure contains a data about supported modules. entries in this
+ * table correspond to either dynamic or static modules.
+ */
+
+struct conf_module_st {
+ /* DSO of this module or NULL if static */
+ DSO *dso;
+ /* Name of the module */
+ char *name;
+ /* Init function */
+ conf_init_func *init;
+ /* Finish function */
+ conf_finish_func *finish;
+ /* Number of successfully initialized modules */
+ int links;
+ void *usr_data;
+};
+
+/*
+ * This structure contains information about modules that have been
+ * successfully initialized. There may be more than one entry for a given
+ * module.
+ */
+
+struct conf_imodule_st {
+ CONF_MODULE *pmod;
+ char *name;
+ char *value;
+ unsigned long flags;
+ void *usr_data;
+};
+
+static STACK_OF(CONF_MODULE) *supported_modules = NULL;
+static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
+
+static void module_free(CONF_MODULE *md);
+static void module_finish(CONF_IMODULE *imod);
+static int module_run(const CONF *cnf, char *name, char *value,
+ unsigned long flags);
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+ conf_init_func *ifunc,
+ conf_finish_func *ffunc);
+static CONF_MODULE *module_find(char *name);
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+ const CONF *cnf);
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+ unsigned long flags);
+
+/* Main function: load modules from a CONF structure */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+ unsigned long flags)
+{
+ STACK_OF(CONF_VALUE) *values;
+ CONF_VALUE *vl;
+ char *vsection = NULL;
+
+ int ret, i;
+
+ if (!cnf)
+ return 1;
+
+ if (appname)
+ vsection = NCONF_get_string(cnf, NULL, appname);
+
+ if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
+ vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
+
+ if (!vsection) {
+ ERR_clear_error();
+ return 1;
+ }
+
+ values = NCONF_get_section(cnf, vsection);
+
+ if (!values)
+ return 0;
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ vl = sk_CONF_VALUE_value(values, i);
+ ret = module_run(cnf, vl->name, vl->value, flags);
+ if (ret <= 0)
+ if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
+ return ret;
+ }
+
+ return 1;
+
+}
+
+#ifndef OPENSSL_NO_STDIO
+int CONF_modules_load_file(const char *filename, const char *appname,
+ unsigned long flags)
+{
+ char *file = NULL;
+ CONF *conf = NULL;
+ int ret = 0;
+ conf = NCONF_new(NULL);
+ if (!conf)
+ goto err;
+
+ if (filename == NULL) {
+ file = CONF_get1_default_config_file();
+ if (!file)
+ goto err;
+ } else
+ file = (char *)filename;
+
+ if (NCONF_load(conf, file, NULL) <= 0) {
+ if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
+ (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
+ ERR_clear_error();
+ ret = 1;
+ }
+ goto err;
+ }
+
+ ret = CONF_modules_load(conf, appname, flags);
+
+ err:
+ if (filename == NULL)
+ OPENSSL_free(file);
+ NCONF_free(conf);
+
+ return ret;
+}
+#endif
+
+static int module_run(const CONF *cnf, char *name, char *value,
+ unsigned long flags)
+{
+ CONF_MODULE *md;
+ int ret;
+
+ md = module_find(name);
+
+ /* Module not found: try to load DSO */
+ if (!md && !(flags & CONF_MFLAGS_NO_DSO))
+ md = module_load_dso(cnf, name, value, flags);
+
+ if (!md) {
+ if (!(flags & CONF_MFLAGS_SILENT)) {
+ CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
+ ERR_add_error_data(2, "module=", name);
+ }
+ return -1;
+ }
+
+ ret = module_init(md, name, value, cnf);
+
+ if (ret <= 0) {
+ if (!(flags & CONF_MFLAGS_SILENT)) {
+ char rcode[DECIMAL_SIZE(ret) + 1];
+ CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
+ BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
+ ERR_add_error_data(6, "module=", name, ", value=", value,
+ ", retcode=", rcode);
+ }
+ }
+
+ return ret;
+}
+
+/* Load a module from a DSO */
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+ unsigned long flags)
+{
+ DSO *dso = NULL;
+ conf_init_func *ifunc;
+ conf_finish_func *ffunc;
+ char *path = NULL;
+ int errcode = 0;
+ CONF_MODULE *md;
+ /* Look for alternative path in module section */
+ path = NCONF_get_string(cnf, value, "path");
+ if (!path) {
+ ERR_clear_error();
+ path = name;
+ }
+ dso = DSO_load(NULL, path, NULL, 0);
+ if (!dso) {
+ errcode = CONF_R_ERROR_LOADING_DSO;
+ goto err;
+ }
+ ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
+ if (!ifunc) {
+ errcode = CONF_R_MISSING_INIT_FUNCTION;
+ goto err;
+ }
+ ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
+ /* All OK, add module */
+ md = module_add(dso, name, ifunc, ffunc);
+
+ if (!md)
+ goto err;
+
+ return md;
+
+ err:
+ if (dso)
+ DSO_free(dso);
+ CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
+ ERR_add_error_data(4, "module=", name, ", path=", path);
+ return NULL;
+}
+
+/* add module to list */
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+ conf_init_func *ifunc, conf_finish_func *ffunc)
+{
+ CONF_MODULE *tmod = NULL;
+ if (supported_modules == NULL)
+ supported_modules = sk_CONF_MODULE_new_null();
+ if (supported_modules == NULL)
+ return NULL;
+ tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
+ if (tmod == NULL)
+ return NULL;
+
+ tmod->dso = dso;
+ tmod->name = BUF_strdup(name);
+ tmod->init = ifunc;
+ tmod->finish = ffunc;
+ tmod->links = 0;
+
+ if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
+ OPENSSL_free(tmod);
+ return NULL;
+ }
+
+ return tmod;
+}
+
+/*
+ * Find a module from the list. We allow module names of the form
+ * modname.XXXX to just search for modname to allow the same module to be
+ * initialized more than once.
+ */
+
+static CONF_MODULE *module_find(char *name)
+{
+ CONF_MODULE *tmod;
+ int i, nchar;
+ char *p;
+ p = strrchr(name, '.');
+
+ if (p)
+ nchar = p - name;
+ else
+ nchar = strlen(name);
+
+ for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
+ tmod = sk_CONF_MODULE_value(supported_modules, i);
+ if (!strncmp(tmod->name, name, nchar))
+ return tmod;
+ }
+
+ return NULL;
+
+}
+
+/* initialize a module */
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+ const CONF *cnf)
+{
+ int ret = 1;
+ int init_called = 0;
+ CONF_IMODULE *imod = NULL;
+
+ /* Otherwise add initialized module to list */
+ imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
+ if (!imod)
+ goto err;
+
+ imod->pmod = pmod;
+ imod->name = BUF_strdup(name);
+ imod->value = BUF_strdup(value);
+ imod->usr_data = NULL;
+
+ if (!imod->name || !imod->value)
+ goto memerr;
+
+ /* Try to initialize module */
+ if (pmod->init) {
+ ret = pmod->init(imod, cnf);
+ init_called = 1;
+ /* Error occurred, exit */
+ if (ret <= 0)
+ goto err;
+ }
+
+ if (initialized_modules == NULL) {
+ initialized_modules = sk_CONF_IMODULE_new_null();
+ if (!initialized_modules) {
+ CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
+ CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pmod->links++;
+
+ return ret;
+
+ err:
+
+ /* We've started the module so we'd better finish it */
+ if (pmod->finish && init_called)
+ pmod->finish(imod);
+
+ memerr:
+ if (imod) {
+ if (imod->name)
+ OPENSSL_free(imod->name);
+ if (imod->value)
+ OPENSSL_free(imod->value);
+ OPENSSL_free(imod);
+ }
+
+ return -1;
+
+}
+
+/*
+ * Unload any dynamic modules that have a link count of zero: i.e. have no
+ * active initialized modules. If 'all' is set then all modules are unloaded
+ * including static ones.
+ */
+
+void CONF_modules_unload(int all)
+{
+ int i;
+ CONF_MODULE *md;
+ CONF_modules_finish();
+ /* unload modules in reverse order */
+ for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
+ md = sk_CONF_MODULE_value(supported_modules, i);
+ /* If static or in use and 'all' not set ignore it */
+ if (((md->links > 0) || !md->dso) && !all)
+ continue;
+ /* Since we're working in reverse this is OK */
+ (void)sk_CONF_MODULE_delete(supported_modules, i);
+ module_free(md);
+ }
+ if (sk_CONF_MODULE_num(supported_modules) == 0) {
+ sk_CONF_MODULE_free(supported_modules);
+ supported_modules = NULL;
+ }
+}
+
+/* unload a single module */
+static void module_free(CONF_MODULE *md)
+{
+ if (md->dso)
+ DSO_free(md->dso);
+ OPENSSL_free(md->name);
+ OPENSSL_free(md);
+}
+
+/* finish and free up all modules instances */
+
+void CONF_modules_finish(void)
+{
+ CONF_IMODULE *imod;
+ while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
+ imod = sk_CONF_IMODULE_pop(initialized_modules);
+ module_finish(imod);
+ }
+ sk_CONF_IMODULE_free(initialized_modules);
+ initialized_modules = NULL;
+}
+
+/* finish a module instance */
+
+static void module_finish(CONF_IMODULE *imod)
+{
+ if (imod->pmod->finish)
+ imod->pmod->finish(imod);
+ imod->pmod->links--;
+ OPENSSL_free(imod->name);
+ OPENSSL_free(imod->value);
+ OPENSSL_free(imod);
+}
+
+/* Add a static module to OpenSSL */
+
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+ conf_finish_func *ffunc)
+{
+ if (module_add(NULL, name, ifunc, ffunc))
+ return 1;
+ else
+ return 0;
+}
+
+void CONF_modules_free(void)
+{
+ CONF_modules_finish();
+ CONF_modules_unload(1);
+}
+
+/* Utility functions */
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md)
+{
+ return md->name;
+}
+
+const char *CONF_imodule_get_value(const CONF_IMODULE *md)
+{
+ return md->value;
+}
+
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
+{
+ return md->usr_data;
+}
+
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
+{
+ md->usr_data = usr_data;
+}
+
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
+{
+ return md->pmod;
+}
+
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
+{
+ return md->flags;
+}
+
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
+{
+ md->flags = flags;
+}
+
+void *CONF_module_get_usr_data(CONF_MODULE *pmod)
+{
+ return pmod->usr_data;
+}
+
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
+{
+ pmod->usr_data = usr_data;
+}
+
+/* Return default config file name */
+
+char *CONF_get1_default_config_file(void)
+{
+ char *file;
+ int len;
+
+ file = getenv("OPENSSL_CONF");
+ if (file)
+ return BUF_strdup(file);
+
+ len = strlen(X509_get_default_cert_area());
+#ifndef OPENSSL_SYS_VMS
+ len++;
+#endif
+ len += strlen(OPENSSL_CONF);
+
+ file = OPENSSL_malloc(len + 1);
+
+ if (!file)
+ return NULL;
+ BUF_strlcpy(file, X509_get_default_cert_area(), len + 1);
+#ifndef OPENSSL_SYS_VMS
+ BUF_strlcat(file, "/", len + 1);
+#endif
+ BUF_strlcat(file, OPENSSL_CONF, len + 1);
+
+ return file;
+}
+
+/*
+ * This function takes a list separated by 'sep' and calls the callback
+ * function giving the start and length of each member optionally stripping
+ * leading and trailing whitespace. This can be used to parse comma separated
+ * lists for example.
+ */
+
+int CONF_parse_list(const char *list_, int sep, int nospc,
+ int (*list_cb) (const char *elem, int len, void *usr),
+ void *arg)
+{
+ int ret;
+ const char *lstart, *tmpend, *p;
+
+ if (list_ == NULL) {
+ CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
+ return 0;
+ }
+
+ lstart = list_;
+ for (;;) {
+ if (nospc) {
+ while (*lstart && isspace((unsigned char)*lstart))
+ lstart++;
+ }
+ p = strchr(lstart, sep);
+ if (p == lstart || !*lstart)
+ ret = list_cb(NULL, 0, arg);
+ else {
+ if (p)
+ tmpend = p - 1;
+ else
+ tmpend = lstart + strlen(lstart) - 1;
+ if (nospc) {
+ while (isspace((unsigned char)*tmpend))
+ tmpend--;
+ }
+ ret = list_cb(lstart, tmpend - lstart + 1, arg);
+ }
+ if (ret <= 0)
+ return ret;
+ if (p == NULL)
+ return 1;
+ lstart = p + 1;
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/conf/conf_sap.c b/Cryptlib/OpenSSL/crypto/conf/conf_sap.c
new file mode 100644
index 00000000..a25b6365
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/conf/conf_sap.c
@@ -0,0 +1,101 @@
+/* conf_sap.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+/*
+ * This is the automatic configuration loader: it is called automatically by
+ * OpenSSL when any of a number of standard initialisation functions are
+ * called, unless this is overridden by calling OPENSSL_no_config()
+ */
+
+static int openssl_configured = 0;
+
+void OPENSSL_config(const char *config_name)
+{
+ if (openssl_configured)
+ return;
+
+ OPENSSL_load_builtin_modules();
+#ifndef OPENSSL_NO_ENGINE
+ /* Need to load ENGINEs */
+ ENGINE_load_builtin_engines();
+#endif
+ ERR_clear_error();
+#ifndef OPENSSL_NO_STDIO
+ CONF_modules_load_file(NULL, config_name,
+ CONF_MFLAGS_DEFAULT_SECTION |
+ CONF_MFLAGS_IGNORE_MISSING_FILE);
+#endif
+ openssl_configured = 1;
+}
+
+void OPENSSL_no_config()
+{
+ openssl_configured = 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/constant_time_locl.h b/Cryptlib/OpenSSL/crypto/constant_time_locl.h
new file mode 100644
index 00000000..c786aea9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/constant_time_locl.h
@@ -0,0 +1,211 @@
+/* crypto/constant_time_locl.h */
+/*-
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper (emilia@openssl.org)
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 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 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_CONSTANT_TIME_LOCL_H
+# define HEADER_CONSTANT_TIME_LOCL_H
+
+# include "e_os.h" /* For 'inline' */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
+ * and 0 for false. This is useful for choosing a value based on the result
+ * of a conditional in constant time. For example,
+ *
+ * if (a < b) {
+ * c = a;
+ * } else {
+ * c = b;
+ * }
+ *
+ * can be written as
+ *
+ * unsigned int lt = constant_time_lt(a, b);
+ * c = constant_time_select(lt, a, b);
+ */
+
+/*
+ * Returns the given value with the MSB copied to all the other
+ * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to
+ * replace this with something else on odd CPUs.
+ */
+static inline unsigned int constant_time_msb(unsigned int a);
+
+/*
+ * Returns 0xff..f if a < b and 0 otherwise.
+ */
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_lt_8(unsigned int a,
+ unsigned int b);
+
+/*
+ * Returns 0xff..f if a >= b and 0 otherwise.
+ */
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_ge_8(unsigned int a,
+ unsigned int b);
+
+/*
+ * Returns 0xff..f if a == 0 and 0 otherwise.
+ */
+static inline unsigned int constant_time_is_zero(unsigned int a);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_is_zero_8(unsigned int a);
+
+/*
+ * Returns 0xff..f if a == b and 0 otherwise.
+ */
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_8(unsigned int a,
+ unsigned int b);
+/* Signed integers. */
+static inline unsigned int constant_time_eq_int(int a, int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_int_8(int a, int b);
+
+/*-
+ * Returns (mask & a) | (~mask & b).
+ *
+ * When |mask| is all 1s or all 0s (as returned by the methods above),
+ * the select methods return either |a| (if |mask| is nonzero) or |b|
+ * (if |mask| is zero).
+ */
+static inline unsigned int constant_time_select(unsigned int mask,
+ unsigned int a,
+ unsigned int b);
+/* Convenience method for unsigned chars. */
+static inline unsigned char constant_time_select_8(unsigned char mask,
+ unsigned char a,
+ unsigned char b);
+/* Convenience method for signed integers. */
+static inline int constant_time_select_int(unsigned int mask, int a, int b);
+
+static inline unsigned int constant_time_msb(unsigned int a)
+{
+ return 0 - (a >> (sizeof(a) * 8 - 1));
+}
+
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
+{
+ return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
+}
+
+static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
+{
+ return (unsigned char)(constant_time_lt(a, b));
+}
+
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
+{
+ return ~constant_time_lt(a, b);
+}
+
+static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
+{
+ return (unsigned char)(constant_time_ge(a, b));
+}
+
+static inline unsigned int constant_time_is_zero(unsigned int a)
+{
+ return constant_time_msb(~a & (a - 1));
+}
+
+static inline unsigned char constant_time_is_zero_8(unsigned int a)
+{
+ return (unsigned char)(constant_time_is_zero(a));
+}
+
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b)
+{
+ return constant_time_is_zero(a ^ b);
+}
+
+static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
+{
+ return (unsigned char)(constant_time_eq(a, b));
+}
+
+static inline unsigned int constant_time_eq_int(int a, int b)
+{
+ return constant_time_eq((unsigned)(a), (unsigned)(b));
+}
+
+static inline unsigned char constant_time_eq_int_8(int a, int b)
+{
+ return constant_time_eq_8((unsigned)(a), (unsigned)(b));
+}
+
+static inline unsigned int constant_time_select(unsigned int mask,
+ unsigned int a,
+ unsigned int b)
+{
+ return (mask & a) | (~mask & b);
+}
+
+static inline unsigned char constant_time_select_8(unsigned char mask,
+ unsigned char a,
+ unsigned char b)
+{
+ return (unsigned char)(constant_time_select(mask, a, b));
+}
+
+static inline int constant_time_select_int(unsigned int mask, int a, int b)
+{
+ return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_CONSTANT_TIME_LOCL_H */
diff --git a/Cryptlib/OpenSSL/crypto/cpt_err.c b/Cryptlib/OpenSSL/crypto/cpt_err.c
new file mode 100644
index 00000000..a5138381
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cpt_err.c
@@ -0,0 +1,104 @@
+/* crypto/cpt_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason)
+
+static ERR_STRING_DATA CRYPTO_str_functs[] = {
+ {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"},
+ {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID), "CRYPTO_get_new_dynlockid"},
+ {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID), "CRYPTO_get_new_lockid"},
+ {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"},
+ {ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX), "DEF_ADD_INDEX"},
+ {ERR_FUNC(CRYPTO_F_DEF_GET_CLASS), "DEF_GET_CLASS"},
+ {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
+ {ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"},
+ {ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"},
+ {ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA CRYPTO_str_reasons[] = {
+ {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+ {ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK),
+ "no dynlock create callback"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_CRYPTO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, CRYPTO_str_functs);
+ ERR_load_strings(0, CRYPTO_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/cryptlib.c b/Cryptlib/OpenSSL/crypto/cryptlib.c
new file mode 100644
index 00000000..da4b34dc
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cryptlib.c
@@ -0,0 +1,1035 @@
+/* crypto/cryptlib.c */
+/* ====================================================================
+ * 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 (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 <openssl/safestack.h>
+
+#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)
+
+/* real #defines in crypto.h, keep these upto date */
+static const char *const lock_names[CRYPTO_NUM_LOCKS] = {
+ "<<ERROR>>",
+ "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) = 0;
+static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
+ 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(OPENSSL_FILE, OPENSSL_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, OPENSSL_FILE, OPENSSL_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, OPENSSL_FILE, OPENSSL_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) {
+ return (locking_callback);
+}
+
+int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
+ const char *file, int line) {
+ return (add_lock_callback);
+}
+
+void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
+ const char *file, int line))
+{
+ /*
+ * Calling this here ensures initialisation before any threads are
+ * started.
+ */
+ OPENSSL_init();
+ locking_callback = func;
+}
+
+void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
+ const char *file, int line))
+{
+ 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, (void *)&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);
+}
+
+void CRYPTO_set_id_callback(unsigned long (*func) (void))
+{
+ id_callback = func;
+}
+
+unsigned long CRYPTO_thread_id(void)
+{
+ unsigned long ret = 0;
+
+ if (id_callback == NULL) {
+# ifdef OPENSSL_SYS_WIN16
+ ret = (unsigned long)GetCurrentTask();
+# elif defined(OPENSSL_SYS_WIN32)
+ 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
+ } else
+ ret = id_callback();
+ return (ret);
+}
+#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)
+ operation_text = "lock ";
+ else if (mode & CRYPTO_UNLOCK)
+ operation_text = "unlock";
+ else
+ operation_text = "ERROR ";
+
+ if (mode & CRYPTO_READ)
+ rw_text = "r";
+ else if (mode & CRYPTO_WRITE)
+ rw_text = "w";
+ else
+ rw_text = "ERROR";
+
+ CRYPTO_THREADID_current(&id);
+ fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
+ CRYPTO_THREADID_hash(&id), rw_text, operation_text,
+ CRYPTO_get_lock_name(type), file, line);
+ }
+#endif
+ if (type < 0) {
+ 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)
+ locking_callback(mode, type, file, line);
+}
+
+int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+ int line)
+{
+ int ret = 0;
+
+ if (add_lock_callback != NULL) {
+#ifdef LOCK_DEBUG
+ int before = *pointer;
+#endif
+
+ 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_THREADID_hash(&id), before, amount, ret,
+ CRYPTO_get_lock_name(type), file, line);
+ }
+#endif
+ } else {
+ CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
+
+ 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_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);
+ }
+ 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)
+
+extern unsigned int OPENSSL_ia32cap_P[4];
+unsigned long *OPENSSL_ia32cap_loc(void)
+{
+ if (sizeof(long) == 4)
+ /*
+ * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
+ * clear second element to maintain the illusion that vector
+ * is 32-bit.
+ */
+ OPENSSL_ia32cap_P[1] = 0;
+
+ OPENSSL_ia32cap_P[2] = 0;
+
+ return (unsigned long *)OPENSSL_ia32cap_P;
+}
+
+# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
+#include <stdio.h>
+# define OPENSSL_CPUID_SETUP
+# if defined(_WIN32)
+typedef unsigned __int64 IA32CAP;
+# else
+typedef unsigned long long IA32CAP;
+# endif
+void OPENSSL_cpuid_setup(void)
+{
+ static int trigger = 0;
+ IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
+ IA32CAP vec;
+ char *env;
+
+ if (trigger)
+ return;
+
+ trigger = 1;
+ if ((env = getenv("OPENSSL_ia32cap"))) {
+ int off = (env[0] == '~') ? 1 : 0;
+# if defined(_WIN32)
+ if (!sscanf(env + off, "%I64i", &vec))
+ vec = strtoul(env + off, NULL, 0);
+# else
+ if (!sscanf(env + off, "%lli", (long long *)&vec))
+ vec = strtoul(env + off, NULL, 0);
+# endif
+ if (off)
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
+ else if (env[0] == ':')
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+ OPENSSL_ia32cap_P[2] = 0;
+ if ((env = strchr(env, ':'))) {
+ unsigned int vecx;
+ env++;
+ off = (env[0] == '~') ? 1 : 0;
+ vecx = strtoul(env + off, NULL, 0);
+ if (off)
+ OPENSSL_ia32cap_P[2] &= ~vecx;
+ else
+ OPENSSL_ia32cap_P[2] = vecx;
+ }
+ } else
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+ /*
+ * |(1<<10) sets a reserved bit to signal that variable
+ * was initialized already... This is to avoid interference
+ * with cpuid snippets in ELF .init segment.
+ */
+ OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
+ OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
+}
+# else
+unsigned int OPENSSL_ia32cap_P[4];
+# endif
+
+#else
+unsigned long *OPENSSL_ia32cap_loc(void)
+{
+ return NULL;
+}
+#endif
+int OPENSSL_NONPIC_relocated = 0;
+#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
+void OPENSSL_cpuid_setup(void)
+{
+}
+#endif
+
+#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
+# ifdef __CYGWIN__
+/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
+# include <windows.h>
+/*
+ * 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
+ * detaches
+ */
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ OPENSSL_cpuid_setup();
+# if defined(_WIN32_WINNT)
+ {
+ IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL;
+ IMAGE_NT_HEADERS *nt_headers;
+
+ if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
+ nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header
+ + dos_header->e_lfanew);
+ if (nt_headers->Signature == IMAGE_NT_SIGNATURE &&
+ hinstDLL !=
+ (HINSTANCE) (nt_headers->OptionalHeader.ImageBase))
+ OPENSSL_NONPIC_relocated = 1;
+ }
+ }
+# endif
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return (TRUE);
+}
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <tchar.h>
+# include <signal.h>
+# ifdef __WATCOMC__
+# if defined(_UNICODE) || defined(__UNICODE__)
+# define _vsntprintf _vsnwprintf
+# else
+# define _vsntprintf _vsnprintf
+# endif
+# endif
+# ifdef _MSC_VER
+# define alloca _alloca
+# endif
+
+# 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) ();
+
+ h = GetProcessWindowStation();
+ if (h == NULL)
+ return -1;
+
+ if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return -1;
+
+ if (len > 512)
+ return -1; /* paranoia */
+ len++, len &= ~1; /* paranoia */
+ name = (WCHAR *)alloca(len + sizeof(WCHAR));
+ if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
+ return -1;
+
+ len++, len &= ~1; /* paranoia */
+ name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
+# if 1
+ /*
+ * This doesn't cover "interactive" services [working with real
+ * WinSta0's] nor programs started non-interactively by Task Scheduler
+ * [those are working with SAWinSta].
+ */
+ if (wcsstr(name, L"Service-0x"))
+ return 1;
+# else
+ /* This covers all non-interactive programs such as services. */
+ if (!wcsstr(name, L"WinSta0"))
+ return 1;
+# endif
+ else
+ return 0;
+}
+# else
+int OPENSSL_isservice(void)
+{
+ return 0;
+}
+# endif
+
+void OPENSSL_showfatal(const char *fmta, ...)
+{
+ va_list ap;
+ TCHAR buf[256];
+ const TCHAR *fmt;
+# ifdef STD_ERROR_HANDLE /* what a dirty trick! */
+ HANDLE h;
+
+ if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
+ GetFileType(h) != FILE_TYPE_UNKNOWN) {
+ /* must be console application */
+ int len;
+ DWORD out;
+
+ va_start(ap, fmta);
+ len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
+ WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
+ va_end(ap);
+ return;
+ }
+# endif
+
+ if (sizeof(TCHAR) == sizeof(char))
+ fmt = (const TCHAR *)fmta;
+ else
+ do {
+ int keepgoing;
+ size_t len_0 = strlen(fmta) + 1, i;
+ WCHAR *fmtw;
+
+ fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
+ if (fmtw == NULL) {
+ fmt = (const TCHAR *)L"no stack?";
+ break;
+ }
+# ifndef OPENSSL_NO_MULTIBYTE
+ if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
+# endif
+ for (i = 0; i < len_0; i++)
+ fmtw[i] = (WCHAR)fmta[i];
+
+ for (i = 0; i < len_0; i++) {
+ if (fmtw[i] == L'%')
+ do {
+ keepgoing = 0;
+ switch (fmtw[i + 1]) {
+ case L'0':
+ case L'1':
+ case L'2':
+ case L'3':
+ case L'4':
+ case L'5':
+ case L'6':
+ case L'7':
+ case L'8':
+ case L'9':
+ case L'.':
+ case L'*':
+ case L'-':
+ i++;
+ keepgoing = 1;
+ break;
+ case L's':
+ fmtw[i + 1] = L'S';
+ break;
+ case L'S':
+ fmtw[i + 1] = L's';
+ break;
+ case L'c':
+ fmtw[i + 1] = L'C';
+ break;
+ case L'C':
+ fmtw[i + 1] = L'c';
+ break;
+ }
+ } while (keepgoing);
+ }
+ fmt = (const TCHAR *)fmtw;
+ } while (0);
+
+ va_start(ap, fmta);
+ _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap);
+ buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0');
+ va_end(ap);
+
+# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+ /* this -------------v--- guards NT-specific calls */
+ if (check_winnt() && OPENSSL_isservice() > 0) {
+ HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
+
+ if (hEventLog != NULL) {
+ const TCHAR *pmsg = buf;
+
+ if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
+ 1, 0, &pmsg, NULL)) {
+#if defined(DEBUG)
+ /*
+ * We are in a situation where we tried to report a critical
+ * error and this failed for some reason. As a last resort,
+ * in debug builds, send output to the debugger or any other
+ * tool like DebugView which can monitor the output.
+ */
+ OutputDebugString(pmsg);
+#endif
+ }
+
+ (void)DeregisterEventSource(hEventLog);
+ }
+ } else
+# endif
+ MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
+}
+#else
+void OPENSSL_showfatal(const char *fmta, ...)
+{
+#ifndef OPENSSL_NO_STDIO
+ va_list ap;
+
+ va_start(ap, fmta);
+ vfprintf(stderr, fmta, ap);
+ va_end(ap);
+#endif
+}
+
+int OPENSSL_isservice(void)
+{
+ return 0;
+}
+#endif
+
+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...
+ */
+# if !defined(_WIN32_WCE)
+ raise(SIGABRT);
+# endif
+ _exit(3);
+#endif
+}
+
+#ifndef OPENSSL_NO_STDIO
+void *OPENSSL_stderr(void)
+{
+ return stderr;
+}
+#endif
+
+int CRYPTO_memcmp(const volatile void *in_a, const volatile void *in_b, size_t len)
+{
+ size_t i;
+ const volatile unsigned char *a = in_a;
+ const volatile unsigned char *b = in_b;
+ unsigned char x = 0;
+
+ for (i = 0; i < len; i++)
+ x |= a[i] ^ b[i];
+
+ return x;
+}
diff --git a/Cryptlib/OpenSSL/crypto/cryptlib.h b/Cryptlib/OpenSSL/crypto/cryptlib.h
new file mode 100644
index 00000000..3e3ea5e3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cryptlib.h
@@ -0,0 +1,113 @@
+/* crypto/cryptlib.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_CRYPTLIB_H
+# define HEADER_CRYPTLIB_H
+
+# include <stdlib.h>
+# include <string.h>
+
+# include "e_os.h"
+
+# ifdef OPENSSL_USE_APPLINK
+# define BIO_FLAGS_UPLINK 0x8000
+# include "ms/uplink.h"
+# endif
+
+# include <openssl/crypto.h>
+# include <openssl/buffer.h>
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/opensslconf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_SYS_VMS
+# define X509_CERT_AREA OPENSSLDIR
+# define X509_CERT_DIR OPENSSLDIR "/certs"
+# define X509_CERT_FILE OPENSSLDIR "/cert.pem"
+# define X509_PRIVATE_DIR OPENSSLDIR "/private"
+# else
+# define X509_CERT_AREA "SSLROOT:[000000]"
+# define X509_CERT_DIR "SSLCERTS:"
+# define X509_CERT_FILE "SSLCERTS:cert.pem"
+# define X509_PRIVATE_DIR "SSLPRIVATE:"
+# endif
+
+# define X509_CERT_DIR_EVP "SSL_CERT_DIR"
+# define X509_CERT_FILE_EVP "SSL_CERT_FILE"
+
+/* size of string representations */
+# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1)
+# define HEX_SIZE(type) (sizeof(type)*2)
+
+void OPENSSL_cpuid_setup(void);
+extern unsigned int OPENSSL_ia32cap_P[];
+void OPENSSL_showfatal(const char *fmta, ...);
+#ifndef OPENSSL_NO_STDIO
+void *OPENSSL_stderr(void);
+#endif
+extern int OPENSSL_NONPIC_relocated;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/cversion.c b/Cryptlib/OpenSSL/crypto/cversion.c
new file mode 100644
index 00000000..bfff6995
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/cversion.c
@@ -0,0 +1,107 @@
+/* crypto/cversion.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 "cryptlib.h"
+
+#ifndef NO_WINDOWS_BRAINDEATH
+# include "buildinf.h"
+#endif
+
+const char *SSLeay_version(int t)
+{
+ if (t == SSLEAY_VERSION)
+ return OPENSSL_VERSION_TEXT;
+ if (t == SSLEAY_BUILT_ON) {
+#ifdef DATE
+# ifdef OPENSSL_USE_BUILD_DATE
+ return (DATE);
+# else
+ return ("built on: reproducible build, date unspecified");
+# endif
+#else
+ return ("built on: date not available");
+#endif
+ }
+ if (t == SSLEAY_CFLAGS) {
+#ifdef CFLAGS
+ return (CFLAGS);
+#else
+ return ("compiler: information not available");
+#endif
+ }
+ if (t == SSLEAY_PLATFORM) {
+#ifdef PLATFORM
+ return (PLATFORM);
+#else
+ return ("platform: information not available");
+#endif
+ }
+ if (t == SSLEAY_DIR) {
+#ifdef OPENSSLDIR
+ return "OPENSSLDIR: \"" OPENSSLDIR "\"";
+#else
+ return "OPENSSLDIR: N/A";
+#endif
+ }
+ return ("not available");
+}
+
+unsigned long SSLeay(void)
+{
+ return (SSLEAY_VERSION_NUMBER);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/cbc_cksm.c b/Cryptlib/OpenSSL/crypto/des/cbc_cksm.c
new file mode 100644
index 00000000..f89b5b98
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/cbc_cksm.c
@@ -0,0 +1,103 @@
+/* crypto/des/cbc_cksm.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"
+
+DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output,
+ long length, DES_key_schedule *schedule,
+ const_DES_cblock *ivec)
+{
+ register DES_LONG tout0, tout1, tin0, tin1;
+ register long l = length;
+ DES_LONG tin[2];
+ unsigned char *out = &(*output)[0];
+ const unsigned char *iv = &(*ivec)[0];
+
+ c2l(iv, tout0);
+ c2l(iv, tout1);
+ for (; l > 0; l -= 8) {
+ if (l >= 8) {
+ c2l(in, tin0);
+ c2l(in, tin1);
+ } else
+ c2ln(in, tin0, tin1, l);
+
+ tin0 ^= tout0;
+ tin[0] = tin0;
+ tin1 ^= tout1;
+ tin[1] = tin1;
+ DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT);
+ /* fix 15/10/91 eay - thanks to keithr@sco.COM */
+ tout0 = tin[0];
+ tout1 = tin[1];
+ }
+ if (out != NULL) {
+ l2c(tout0, out);
+ l2c(tout1, out);
+ }
+ tout0 = tin0 = tin1 = tin[0] = tin[1] = 0;
+ /*
+ * Transform the data in tout1 so that it will match the return value
+ * that the MIT Kerberos mit_des_cbc_cksum API returns.
+ */
+ tout1 = ((tout1 >> 24L) & 0x000000FF)
+ | ((tout1 >> 8L) & 0x0000FF00)
+ | ((tout1 << 8L) & 0x00FF0000)
+ | ((tout1 << 24L) & 0xFF000000);
+ return (tout1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/cbc_enc.c b/Cryptlib/OpenSSL/crypto/des/cbc_enc.c
new file mode 100644
index 00000000..7ee35992
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/cbc_enc.c
@@ -0,0 +1,61 @@
+/* crypto/des/cbc_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.]
+ */
+
+#define CBC_ENC_C__DONT_UPDATE_IV
+
+#include "ncbc_enc.c" /* des_cbc_encrypt */
diff --git a/Cryptlib/OpenSSL/crypto/des/cfb64ede.c b/Cryptlib/OpenSSL/crypto/des/cfb64ede.c
new file mode 100644
index 00000000..5d709c12
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/cfb64ede.c
@@ -0,0 +1,249 @@
+/* crypto/des/cfb64ede.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 "e_os.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 DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int *num, int enc)
+{
+ register DES_LONG v0, v1;
+ register long l = length;
+ register int n = *num;
+ DES_LONG ti[2];
+ unsigned char *iv, c, cc;
+
+ iv = &(*ivec)[0];
+ if (enc) {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ iv = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ iv = &(*ivec)[0];
+ }
+ c = *(in++) ^ iv[n];
+ *(out++) = c;
+ iv[n] = c;
+ n = (n + 1) & 0x07;
+ }
+ } else {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ iv = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ iv = &(*ivec)[0];
+ }
+ cc = *(in++);
+ c = iv[n];
+ iv[n] = cc;
+ *(out++) = c ^ cc;
+ n = (n + 1) & 0x07;
+ }
+ }
+ v0 = v1 = ti[0] = ti[1] = c = cc = 0;
+ *num = n;
+}
+
+#ifdef undef /* MACRO */
+void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, DES_key_schedule ks1,
+ DES_key_schedule ks2, DES_cblock (*ivec),
+ int *num, int enc)
+{
+ DES_ede3_cfb64_encrypt(in, out, length, ks1, ks2, ks1, ivec, num, enc);
+}
+#endif
+
+/*
+ * This is compatible with the single key CFB-r for DES, even thought that's
+ * not what EVP needs.
+ */
+
+void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out,
+ int numbits, long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int enc)
+{
+ register DES_LONG d0, d1, v0, v1;
+ register unsigned long l = length, n = ((unsigned int)numbits + 7) / 8;
+ register int num = numbits, i;
+ DES_LONG ti[2];
+ unsigned char *iv;
+ unsigned char ovec[16];
+
+ if (num > 64)
+ return;
+ iv = &(*ivec)[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ if (enc) {
+ while (l >= n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ c2ln(in, d0, d1, n);
+ in += n;
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ /*
+ * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-(
+ */
+ if (num == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (num == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+ /* shift ovec left most of the bits... */
+ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+ /* now the remaining bits */
+ if (num % 8 != 0)
+ for (i = 0; i < 8; ++i) {
+ ovec[i] <<= num % 8;
+ ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+ }
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ }
+ }
+ } else {
+ while (l >= n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ c2ln(in, d0, d1, n);
+ in += n;
+ /*
+ * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-(
+ */
+ if (num == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (num == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+ /* shift ovec left most of the bits... */
+ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+ /* now the remaining bits */
+ if (num % 8 != 0)
+ for (i = 0; i < 8; ++i) {
+ ovec[i] <<= num % 8;
+ ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+ }
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ }
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ }
+ }
+ iv = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/cfb64enc.c b/Cryptlib/OpenSSL/crypto/des/cfb64enc.c
new file mode 100644
index 00000000..7346774e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/cfb64enc.c
@@ -0,0 +1,122 @@
+/* crypto/des/cfb64enc.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"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+ long length, DES_key_schedule *schedule,
+ DES_cblock *ivec, int *num, int enc)
+{
+ register DES_LONG v0, v1;
+ register long l = length;
+ register int n = *num;
+ DES_LONG ti[2];
+ unsigned char *iv, c, cc;
+
+ iv = &(*ivec)[0];
+ if (enc) {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ ti[0] = v0;
+ c2l(iv, v1);
+ ti[1] = v1;
+ DES_encrypt1(ti, schedule, DES_ENCRYPT);
+ iv = &(*ivec)[0];
+ v0 = ti[0];
+ l2c(v0, iv);
+ v0 = ti[1];
+ l2c(v0, iv);
+ iv = &(*ivec)[0];
+ }
+ 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;
+ DES_encrypt1(ti, schedule, DES_ENCRYPT);
+ iv = &(*ivec)[0];
+ v0 = ti[0];
+ l2c(v0, iv);
+ v0 = ti[1];
+ l2c(v0, iv);
+ iv = &(*ivec)[0];
+ }
+ cc = *(in++);
+ c = iv[n];
+ iv[n] = cc;
+ *(out++) = c ^ cc;
+ n = (n + 1) & 0x07;
+ }
+ }
+ v0 = v1 = ti[0] = ti[1] = c = cc = 0;
+ *num = n;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/cfb_enc.c b/Cryptlib/OpenSSL/crypto/des/cfb_enc.c
new file mode 100644
index 00000000..bd0e2997
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/cfb_enc.c
@@ -0,0 +1,199 @@
+/* crypto/des/cfb_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 "e_os.h"
+#include "des_locl.h"
+#include <assert.h>
+
+/*
+ * The input and output are loaded in multiples of 8 bits. What this means is
+ * that if you hame numbits=12 and length=2 the first 12 bits will be
+ * retrieved from the first byte and half the second. The second 12 bits
+ * will come from the 3rd and half the 4th byte.
+ */
+/*
+ * Until Aug 1 2003 this function did not correctly implement CFB-r, so it
+ * will not be compatible with any encryption prior to that date. Ben.
+ */
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+ long length, DES_key_schedule *schedule,
+ DES_cblock *ivec, int enc)
+{
+ register DES_LONG d0, d1, v0, v1;
+ register unsigned long l = length;
+ register int num = numbits / 8, n = (numbits + 7) / 8, i, rem =
+ numbits % 8;
+ DES_LONG ti[2];
+ unsigned char *iv;
+#ifndef L_ENDIAN
+ unsigned char ovec[16];
+#else
+ unsigned int sh[4];
+ unsigned char *ovec = (unsigned char *)sh;
+
+ /* I kind of count that compiler optimizes away this assertioni, */
+ assert(sizeof(sh[0]) == 4); /* as this holds true for all, */
+ /* but 16-bit platforms... */
+
+#endif
+
+ if (numbits <= 0 || numbits > 64)
+ return;
+ iv = &(*ivec)[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ if (enc) {
+ while (l >= (unsigned long)n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
+ c2ln(in, d0, d1, n);
+ in += n;
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ /*
+ * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-(
+ */
+ if (numbits == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (numbits == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+#ifndef L_ENDIAN
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+#else
+ sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1;
+#endif
+ if (rem == 0)
+ memmove(ovec, ovec + num, 8);
+ else
+ for (i = 0; i < 8; ++i)
+ ovec[i] = ovec[i + num] << rem |
+ ovec[i + num + 1] >> (8 - rem);
+#ifdef L_ENDIAN
+ v0 = sh[0], v1 = sh[1];
+#else
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+#endif
+ }
+ }
+ } else {
+ while (l >= (unsigned long)n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
+ c2ln(in, d0, d1, n);
+ in += n;
+ /*
+ * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-(
+ */
+ if (numbits == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (numbits == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+#ifndef L_ENDIAN
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+#else
+ sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1;
+#endif
+ if (rem == 0)
+ memmove(ovec, ovec + num, 8);
+ else
+ for (i = 0; i < 8; ++i)
+ ovec[i] = ovec[i + num] << rem |
+ ovec[i + num + 1] >> (8 - rem);
+#ifdef L_ENDIAN
+ v0 = sh[0], v1 = sh[1];
+#else
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+#endif
+ }
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ }
+ }
+ iv = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/des_enc.c b/Cryptlib/OpenSSL/crypto/des/des_enc.c
new file mode 100644
index 00000000..c0b062da
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/des_enc.c
@@ -0,0 +1,389 @@
+/* crypto/des/des_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 "spr.h"
+
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
+{
+ register DES_LONG l, r, t, u;
+#ifdef DES_PTR
+ register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+ register int i;
+#endif
+ register DES_LONG *s;
+
+ r = data[0];
+ l = data[1];
+
+ IP(r, l);
+ /*
+ * Things have been modified so that the initial rotate is done outside
+ * the loop. This required the DES_SPtrans values in sp.h to be rotated
+ * 1 bit to the right. One perl script later and things have a 5% speed
+ * up on a sparc2. Thanks to Richard Outerbridge
+ * <71755.204@CompuServe.COM> for pointing this out.
+ */
+ /* clear the top bits on machines with 8byte longs */
+ /* shift left by 2 */
+ r = ROTATE(r, 29) & 0xffffffffL;
+ l = ROTATE(l, 29) & 0xffffffffL;
+
+ s = ks->ks->deslong;
+ /*
+ * I don't know if it is worth the effort of loop unrolling the inner
+ * loop
+ */
+ if (enc) {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l, r, 0); /* 1 */
+ D_ENCRYPT(r, l, 2); /* 2 */
+ D_ENCRYPT(l, r, 4); /* 3 */
+ D_ENCRYPT(r, l, 6); /* 4 */
+ D_ENCRYPT(l, r, 8); /* 5 */
+ D_ENCRYPT(r, l, 10); /* 6 */
+ D_ENCRYPT(l, r, 12); /* 7 */
+ D_ENCRYPT(r, l, 14); /* 8 */
+ D_ENCRYPT(l, r, 16); /* 9 */
+ D_ENCRYPT(r, l, 18); /* 10 */
+ D_ENCRYPT(l, r, 20); /* 11 */
+ D_ENCRYPT(r, l, 22); /* 12 */
+ D_ENCRYPT(l, r, 24); /* 13 */
+ D_ENCRYPT(r, l, 26); /* 14 */
+ D_ENCRYPT(l, r, 28); /* 15 */
+ D_ENCRYPT(r, l, 30); /* 16 */
+#else
+ for (i = 0; i < 32; i += 4) {
+ D_ENCRYPT(l, r, i + 0); /* 1 */
+ D_ENCRYPT(r, l, i + 2); /* 2 */
+ }
+#endif
+ } else {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l, r, 30); /* 16 */
+ D_ENCRYPT(r, l, 28); /* 15 */
+ D_ENCRYPT(l, r, 26); /* 14 */
+ D_ENCRYPT(r, l, 24); /* 13 */
+ D_ENCRYPT(l, r, 22); /* 12 */
+ D_ENCRYPT(r, l, 20); /* 11 */
+ D_ENCRYPT(l, r, 18); /* 10 */
+ D_ENCRYPT(r, l, 16); /* 9 */
+ D_ENCRYPT(l, r, 14); /* 8 */
+ D_ENCRYPT(r, l, 12); /* 7 */
+ D_ENCRYPT(l, r, 10); /* 6 */
+ D_ENCRYPT(r, l, 8); /* 5 */
+ D_ENCRYPT(l, r, 6); /* 4 */
+ D_ENCRYPT(r, l, 4); /* 3 */
+ D_ENCRYPT(l, r, 2); /* 2 */
+ D_ENCRYPT(r, l, 0); /* 1 */
+#else
+ for (i = 30; i > 0; i -= 4) {
+ D_ENCRYPT(l, r, i - 0); /* 16 */
+ D_ENCRYPT(r, l, i - 2); /* 15 */
+ }
+#endif
+ }
+
+ /* rotate and clear the top bits on machines with 8byte longs */
+ l = ROTATE(l, 3) & 0xffffffffL;
+ r = ROTATE(r, 3) & 0xffffffffL;
+
+ FP(r, l);
+ data[0] = l;
+ data[1] = r;
+ l = r = t = u = 0;
+}
+
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
+{
+ register DES_LONG l, r, t, u;
+#ifdef DES_PTR
+ register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+ register int i;
+#endif
+ register DES_LONG *s;
+
+ r = data[0];
+ l = data[1];
+
+ /*
+ * Things have been modified so that the initial rotate is done outside
+ * the loop. This required the DES_SPtrans values in sp.h to be rotated
+ * 1 bit to the right. One perl script later and things have a 5% speed
+ * up on a sparc2. Thanks to Richard Outerbridge
+ * <71755.204@CompuServe.COM> for pointing this out.
+ */
+ /* clear the top bits on machines with 8byte longs */
+ r = ROTATE(r, 29) & 0xffffffffL;
+ l = ROTATE(l, 29) & 0xffffffffL;
+
+ s = ks->ks->deslong;
+ /*
+ * I don't know if it is worth the effort of loop unrolling the inner
+ * loop
+ */
+ if (enc) {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l, r, 0); /* 1 */
+ D_ENCRYPT(r, l, 2); /* 2 */
+ D_ENCRYPT(l, r, 4); /* 3 */
+ D_ENCRYPT(r, l, 6); /* 4 */
+ D_ENCRYPT(l, r, 8); /* 5 */
+ D_ENCRYPT(r, l, 10); /* 6 */
+ D_ENCRYPT(l, r, 12); /* 7 */
+ D_ENCRYPT(r, l, 14); /* 8 */
+ D_ENCRYPT(l, r, 16); /* 9 */
+ D_ENCRYPT(r, l, 18); /* 10 */
+ D_ENCRYPT(l, r, 20); /* 11 */
+ D_ENCRYPT(r, l, 22); /* 12 */
+ D_ENCRYPT(l, r, 24); /* 13 */
+ D_ENCRYPT(r, l, 26); /* 14 */
+ D_ENCRYPT(l, r, 28); /* 15 */
+ D_ENCRYPT(r, l, 30); /* 16 */
+#else
+ for (i = 0; i < 32; i += 4) {
+ D_ENCRYPT(l, r, i + 0); /* 1 */
+ D_ENCRYPT(r, l, i + 2); /* 2 */
+ }
+#endif
+ } else {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l, r, 30); /* 16 */
+ D_ENCRYPT(r, l, 28); /* 15 */
+ D_ENCRYPT(l, r, 26); /* 14 */
+ D_ENCRYPT(r, l, 24); /* 13 */
+ D_ENCRYPT(l, r, 22); /* 12 */
+ D_ENCRYPT(r, l, 20); /* 11 */
+ D_ENCRYPT(l, r, 18); /* 10 */
+ D_ENCRYPT(r, l, 16); /* 9 */
+ D_ENCRYPT(l, r, 14); /* 8 */
+ D_ENCRYPT(r, l, 12); /* 7 */
+ D_ENCRYPT(l, r, 10); /* 6 */
+ D_ENCRYPT(r, l, 8); /* 5 */
+ D_ENCRYPT(l, r, 6); /* 4 */
+ D_ENCRYPT(r, l, 4); /* 3 */
+ D_ENCRYPT(l, r, 2); /* 2 */
+ D_ENCRYPT(r, l, 0); /* 1 */
+#else
+ for (i = 30; i > 0; i -= 4) {
+ D_ENCRYPT(l, r, i - 0); /* 16 */
+ D_ENCRYPT(r, l, i - 2); /* 15 */
+ }
+#endif
+ }
+ /* rotate and clear the top bits on machines with 8byte longs */
+ data[0] = ROTATE(l, 3) & 0xffffffffL;
+ data[1] = ROTATE(r, 3) & 0xffffffffL;
+ l = r = t = u = 0;
+}
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3)
+{
+ register DES_LONG l, r;
+
+ l = data[0];
+ r = data[1];
+ IP(l, r);
+ data[0] = l;
+ data[1] = r;
+ DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
+ DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
+ DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
+ l = data[0];
+ r = data[1];
+ FP(r, l);
+ data[0] = l;
+ data[1] = r;
+}
+
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3)
+{
+ register DES_LONG l, r;
+
+ l = data[0];
+ r = data[1];
+ IP(l, r);
+ data[0] = l;
+ data[1] = r;
+ DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
+ DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
+ DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
+ l = data[0];
+ r = data[1];
+ FP(r, l);
+ data[0] = l;
+ data[1] = r;
+}
+
+#ifndef DES_DEFAULT_OPTIONS
+
+# undef CBC_ENC_C__DONT_UPDATE_IV
+# include "ncbc_enc.c" /* DES_ncbc_encrypt */
+
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int enc)
+{
+ register DES_LONG tin0, tin1;
+ register DES_LONG tout0, tout1, xor0, xor1;
+ register const unsigned char *in;
+ unsigned char *out;
+ register long l = length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in = input;
+ out = output;
+ iv = &(*ivec)[0];
+
+ if (enc) {
+ c2l(iv, tout0);
+ c2l(iv, tout1);
+ for (l -= 8; l >= 0; l -= 8) {
+ c2l(in, tin0);
+ c2l(in, tin1);
+ tin0 ^= tout0;
+ tin1 ^= tout1;
+
+ tin[0] = tin0;
+ tin[1] = tin1;
+ DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+ tout0 = tin[0];
+ tout1 = tin[1];
+
+ l2c(tout0, out);
+ l2c(tout1, out);
+ }
+ if (l != -8) {
+ c2ln(in, tin0, tin1, l + 8);
+ tin0 ^= tout0;
+ tin1 ^= tout1;
+
+ tin[0] = tin0;
+ tin[1] = tin1;
+ DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+ tout0 = tin[0];
+ tout1 = tin[1];
+
+ l2c(tout0, out);
+ l2c(tout1, out);
+ }
+ iv = &(*ivec)[0];
+ l2c(tout0, iv);
+ l2c(tout1, iv);
+ } else {
+ register DES_LONG t0, t1;
+
+ c2l(iv, xor0);
+ c2l(iv, xor1);
+ for (l -= 8; l >= 0; l -= 8) {
+ c2l(in, tin0);
+ c2l(in, tin1);
+
+ t0 = tin0;
+ t1 = tin1;
+
+ tin[0] = tin0;
+ tin[1] = tin1;
+ DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+ tout0 = tin[0];
+ tout1 = tin[1];
+
+ tout0 ^= xor0;
+ tout1 ^= xor1;
+ l2c(tout0, out);
+ l2c(tout1, out);
+ xor0 = t0;
+ xor1 = t1;
+ }
+ if (l != -8) {
+ c2l(in, tin0);
+ c2l(in, tin1);
+
+ t0 = tin0;
+ t1 = tin1;
+
+ tin[0] = tin0;
+ tin[1] = tin1;
+ DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+ tout0 = tin[0];
+ tout1 = tin[1];
+
+ tout0 ^= xor0;
+ tout1 ^= xor1;
+ l2cn(tout0, tout1, out, l + 8);
+ xor0 = t0;
+ xor1 = t1;
+ }
+
+ iv = &(*ivec)[0];
+ l2c(xor0, iv);
+ l2c(xor1, iv);
+ }
+ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+ tin[0] = tin[1] = 0;
+}
+
+#endif /* DES_DEFAULT_OPTIONS */
diff --git a/Cryptlib/OpenSSL/crypto/des/des_locl.h b/Cryptlib/OpenSSL/crypto/des/des_locl.h
new file mode 100644
index 00000000..23ea9d32
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/des_locl.h
@@ -0,0 +1,443 @@
+/* crypto/des/des_locl.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_DES_LOCL_H
+# define HEADER_DES_LOCL_H
+
+# include <openssl/e_os2.h>
+
+# if defined(OPENSSL_SYS_WIN32)
+# ifndef OPENSSL_SYS_MSDOS
+# define OPENSSL_SYS_MSDOS
+# endif
+# endif
+
+# include <stdio.h>
+# include <stdlib.h>
+
+# ifndef OPENSSL_SYS_MSDOS
+# if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
+# ifdef OPENSSL_UNISTD
+# include OPENSSL_UNISTD
+# else
+# include <unistd.h>
+# endif
+# include <math.h>
+# endif
+# endif
+# include <openssl/des.h>
+
+# ifdef OPENSSL_SYS_MSDOS /* Visual C++ 2.1 (Windows NT/95) */
+# include <stdlib.h>
+# include <errno.h>
+# include <time.h>
+# include <io.h>
+# endif
+
+# if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
+# include <string.h>
+# endif
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+# define ITERATIONS 16
+# define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+# define MAXWRITE (1024*16)
+# define BSIZE (MAXWRITE+4)
+
+# define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
+ l|=((DES_LONG)(*((c)++)))<<16L, \
+ l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+# define c2ln(c,l1,l2,n) { \
+ c+=n; \
+ l1=l2=0; \
+ switch (n) { \
+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+ case 5: l2|=((DES_LONG)(*(--(c)))); \
+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+ case 1: l1|=((DES_LONG)(*(--(c)))); \
+ } \
+ }
+
+# 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))
+
+/*
+ * replacements for htonl and ntohl since I have no idea what to do when
+ * faced with machines with 8 byte longs.
+ */
+# define HDRSIZE 4
+
+# define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
+ l|=((DES_LONG)(*((c)++)))<<16L, \
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
+ l|=((DES_LONG)(*((c)++))))
+
+# 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))
+
+/* NOTE - c is not incremented as per l2c */
+# 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); \
+ } \
+ }
+
+# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER))
+# define ROTATE(a,n) (_lrotr(a,n))
+# elif defined(__ICC)
+# define ROTATE(a,n) (_rotr(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(a,n) ({ register unsigned int ret; \
+ asm ("rorl %1,%0" \
+ : "=r"(ret) \
+ : "I"(n),"0"(a) \
+ : "cc"); \
+ ret; \
+ })
+# endif
+# endif
+# ifndef ROTATE
+# define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
+# endif
+
+/*
+ * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add
+ * it's little bit to the front
+ */
+
+# ifdef DES_FCRYPT
+
+# define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+ t=R^(R>>16L); \
+ u=t&E0; t&=E1; \
+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+# else
+# define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+ u=R^s[S ]; \
+ t=R^s[S+1]
+# endif
+
+/*
+ * The changes to this macro may help or hinder, depending on the compiler
+ * and the architecture. gcc2 always seems to do well :-). Inspired by Dana
+ * How <how@isl.stanford.edu> DO NOT use the alternative version on machines
+ * with 8 byte longs. It does not seem to work on the Alpha, even when
+ * DES_LONG is 4 bytes, probably an issue of accessing non-word aligned
+ * objects :-(
+ */
+# ifdef DES_PTR
+
+/*
+ * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason
+ * to not xor all the sub items together. This potentially saves a register
+ * since things can be xored directly into L
+ */
+
+# if defined(DES_RISC1) || defined(DES_RISC2)
+# ifdef DES_RISC1
+# define D_ENCRYPT(LL,R,S) { \
+ unsigned int u1,u2,u3; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0xfc; \
+ u2&=0xfc; \
+ t=ROTATE(t,4); \
+ u>>=16L; \
+ LL^= *(const DES_LONG *)(des_SP +u1); \
+ LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+ u3=(int)(u>>8L); \
+ u1=(int)u&0xfc; \
+ u3&=0xfc; \
+ LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
+ LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
+ u2=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u2&=0xfc; \
+ t>>=16L; \
+ LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+ LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+ u3=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u3&=0xfc; \
+ LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
+ LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
+# endif
+# ifdef DES_RISC2
+# define D_ENCRYPT(LL,R,S) { \
+ unsigned int u1,u2,s1,s2; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0xfc; \
+ u2&=0xfc; \
+ t=ROTATE(t,4); \
+ LL^= *(const DES_LONG *)(des_SP +u1); \
+ LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+ s1=(int)(u>>16L); \
+ s2=(int)(u>>24L); \
+ s1&=0xfc; \
+ s2&=0xfc; \
+ LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
+ LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
+ u2=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u2&=0xfc; \
+ LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+ LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+ s1=(int)(t>>16L); \
+ s2=(int)(t>>24L); \
+ s1&=0xfc; \
+ s2&=0xfc; \
+ LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
+ LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
+# endif
+# else
+# define D_ENCRYPT(LL,R,S) { \
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+ t=ROTATE(t,4); \
+ LL^= \
+ *(const DES_LONG *)(des_SP +((u )&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
+ *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
+# endif
+
+# else /* original version */
+
+# if defined(DES_RISC1) || defined(DES_RISC2)
+# ifdef DES_RISC1
+# define D_ENCRYPT(LL,R,S) {\
+ unsigned int u1,u2,u3; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u>>=2L; \
+ t=ROTATE(t,6); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u2&=0x3f; \
+ u>>=16L; \
+ LL^=DES_SPtrans[0][u1]; \
+ LL^=DES_SPtrans[2][u2]; \
+ u3=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u3&=0x3f; \
+ LL^=DES_SPtrans[4][u1]; \
+ LL^=DES_SPtrans[6][u3]; \
+ u2=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u2&=0x3f; \
+ t>>=16L; \
+ LL^=DES_SPtrans[1][u1]; \
+ LL^=DES_SPtrans[3][u2]; \
+ u3=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u3&=0x3f; \
+ LL^=DES_SPtrans[5][u1]; \
+ LL^=DES_SPtrans[7][u3]; }
+# endif
+# ifdef DES_RISC2
+# define D_ENCRYPT(LL,R,S) {\
+ unsigned int u1,u2,s1,s2; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u>>=2L; \
+ t=ROTATE(t,6); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u2&=0x3f; \
+ LL^=DES_SPtrans[0][u1]; \
+ LL^=DES_SPtrans[2][u2]; \
+ s1=(int)u>>16L; \
+ s2=(int)u>>24L; \
+ s1&=0x3f; \
+ s2&=0x3f; \
+ LL^=DES_SPtrans[4][s1]; \
+ LL^=DES_SPtrans[6][s2]; \
+ u2=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u2&=0x3f; \
+ LL^=DES_SPtrans[1][u1]; \
+ LL^=DES_SPtrans[3][u2]; \
+ s1=(int)t>>16; \
+ s2=(int)t>>24L; \
+ s1&=0x3f; \
+ s2&=0x3f; \
+ LL^=DES_SPtrans[5][s1]; \
+ LL^=DES_SPtrans[7][s2]; }
+# endif
+
+# else
+
+# define D_ENCRYPT(LL,R,S) {\
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+ t=ROTATE(t,4); \
+ LL^=\
+ DES_SPtrans[0][(u>> 2L)&0x3f]^ \
+ DES_SPtrans[2][(u>>10L)&0x3f]^ \
+ DES_SPtrans[4][(u>>18L)&0x3f]^ \
+ DES_SPtrans[6][(u>>26L)&0x3f]^ \
+ DES_SPtrans[1][(t>> 2L)&0x3f]^ \
+ DES_SPtrans[3][(t>>10L)&0x3f]^ \
+ DES_SPtrans[5][(t>>18L)&0x3f]^ \
+ DES_SPtrans[7][(t>>26L)&0x3f]; }
+# endif
+# endif
+
+ /*-
+ * IP and FP
+ * The problem is more of a geometric problem that random bit fiddling.
+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
+
+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
+
+ The output has been subject to swaps of the form
+ 0 1 -> 3 1 but the odd and even bits have been put into
+ 2 3 2 0
+ different words. The main trick is to remember that
+ t=((l>>size)^r)&(mask);
+ r^=t;
+ l^=(t<<size);
+ can be used to swap and move bits between words.
+
+ So l = 0 1 2 3 r = 16 17 18 19
+ 4 5 6 7 20 21 22 23
+ 8 9 10 11 24 25 26 27
+ 12 13 14 15 28 29 30 31
+ becomes (for size == 2 and mask == 0x3333)
+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
+
+ Thanks for hints from Richard Outerbridge - he told me IP&FP
+ could be done in 15 xor, 10 shifts and 5 ands.
+ When I finally started to think of the problem in 2D
+ I first got ~42 operations without xors. When I remembered
+ how to use xors :-) I got it to its final state.
+ */
+# define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+# define IP(l,r) \
+ { \
+ register DES_LONG tt; \
+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+ PERM_OP(l,r,tt,16,0x0000ffffL); \
+ PERM_OP(r,l,tt, 2,0x33333333L); \
+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+ PERM_OP(r,l,tt, 1,0x55555555L); \
+ }
+
+# define FP(l,r) \
+ { \
+ register DES_LONG tt; \
+ PERM_OP(l,r,tt, 1,0x55555555L); \
+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+ PERM_OP(l,r,tt, 2,0x33333333L); \
+ PERM_OP(r,l,tt,16,0x0000ffffL); \
+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+ }
+
+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/Cryptlib/OpenSSL/crypto/des/des_old.c b/Cryptlib/OpenSSL/crypto/des/des_old.c
new file mode 100644
index 00000000..c5c5a00f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/des_old.c
@@ -0,0 +1,345 @@
+/* crypto/des/des_old.c */
+
+/*-
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * The function names in here are deprecated and are only present to
+ * provide an interface compatible with libdes. OpenSSL now provides
+ * functions where "des_" has been replaced with "DES_" in the names,
+ * to make it possible to make incompatible changes that are needed
+ * for C type security and other stuff.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones. The des_ functions will dissapear completely before
+ * OpenSSL 1.0!
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#define OPENSSL_DES_LIBDES_COMPATIBILITY
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+const char *_ossl_old_des_options(void)
+{
+ return DES_options();
+}
+
+void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output,
+ des_key_schedule ks1, des_key_schedule ks2,
+ des_key_schedule ks3, int enc)
+{
+ DES_ecb3_encrypt((const_DES_cblock *)input, output,
+ (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+ (DES_key_schedule *)ks3, enc);
+}
+
+DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec)
+{
+ return DES_cbc_cksum((unsigned char *)input, output, length,
+ (DES_key_schedule *)schedule, ivec);
+}
+
+void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec, int enc)
+{
+ DES_cbc_encrypt((unsigned char *)input, (unsigned char *)output,
+ length, (DES_key_schedule *)schedule, ivec, enc);
+}
+
+void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec, int enc)
+{
+ DES_ncbc_encrypt((unsigned char *)input, (unsigned char *)output,
+ length, (DES_key_schedule *)schedule, ivec, enc);
+}
+
+void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec,
+ _ossl_old_des_cblock *inw,
+ _ossl_old_des_cblock *outw, int enc)
+{
+ DES_xcbc_encrypt((unsigned char *)input, (unsigned char *)output,
+ length, (DES_key_schedule *)schedule, ivec, inw, outw,
+ enc);
+}
+
+void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out,
+ int numbits, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec, int enc)
+{
+ DES_cfb_encrypt(in, out, numbits, length,
+ (DES_key_schedule *)schedule, ivec, enc);
+}
+
+void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output,
+ des_key_schedule ks, int enc)
+{
+ DES_ecb_encrypt(input, output, (DES_key_schedule *)ks, enc);
+}
+
+void _ossl_old_des_encrypt(DES_LONG *data, des_key_schedule ks, int enc)
+{
+ DES_encrypt1(data, (DES_key_schedule *)ks, enc);
+}
+
+void _ossl_old_des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
+{
+ DES_encrypt2(data, (DES_key_schedule *)ks, enc);
+}
+
+void _ossl_old_des_encrypt3(DES_LONG *data, des_key_schedule ks1,
+ des_key_schedule ks2, des_key_schedule ks3)
+{
+ DES_encrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+ (DES_key_schedule *)ks3);
+}
+
+void _ossl_old_des_decrypt3(DES_LONG *data, des_key_schedule ks1,
+ des_key_schedule ks2, des_key_schedule ks3)
+{
+ DES_decrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+ (DES_key_schedule *)ks3);
+}
+
+void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ des_key_schedule ks1,
+ des_key_schedule ks2,
+ des_key_schedule ks3,
+ _ossl_old_des_cblock *ivec, int enc)
+{
+ DES_ede3_cbc_encrypt((unsigned char *)input, (unsigned char *)output,
+ length, (DES_key_schedule *)ks1,
+ (DES_key_schedule *)ks2, (DES_key_schedule *)ks3,
+ ivec, enc);
+}
+
+void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, des_key_schedule ks1,
+ des_key_schedule ks2,
+ des_key_schedule ks3,
+ _ossl_old_des_cblock *ivec, int *num,
+ int enc)
+{
+ DES_ede3_cfb64_encrypt(in, out, length,
+ (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+ (DES_key_schedule *)ks3, ivec, num, enc);
+}
+
+void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, des_key_schedule ks1,
+ des_key_schedule ks2,
+ des_key_schedule ks3,
+ _ossl_old_des_cblock *ivec, int *num)
+{
+ DES_ede3_ofb64_encrypt(in, out, length,
+ (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+ (DES_key_schedule *)ks3, ivec, num);
+}
+
+#if 0 /* broken code, preserved just in case anyone
+ * specifically looks for this */
+void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key),
+ _ossl_old_des_cblock (*in_white),
+ _ossl_old_des_cblock (*out_white))
+{
+ DES_xwhite_in2out(des_key, in_white, out_white);
+}
+#endif
+
+int _ossl_old_des_enc_read(int fd, char *buf, int len, des_key_schedule sched,
+ _ossl_old_des_cblock *iv)
+{
+ return DES_enc_read(fd, buf, len, (DES_key_schedule *)sched, iv);
+}
+
+int _ossl_old_des_enc_write(int fd, char *buf, int len,
+ des_key_schedule sched, _ossl_old_des_cblock *iv)
+{
+ return DES_enc_write(fd, buf, len, (DES_key_schedule *)sched, iv);
+}
+
+char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret)
+{
+ return DES_fcrypt(buf, salt, ret);
+}
+
+char *_ossl_old_des_crypt(const char *buf, const char *salt)
+{
+ return DES_crypt(buf, salt);
+}
+
+char *_ossl_old_crypt(const char *buf, const char *salt)
+{
+ return DES_crypt(buf, salt);
+}
+
+void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out,
+ int numbits, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec)
+{
+ DES_ofb_encrypt(in, out, numbits, length, (DES_key_schedule *)schedule,
+ ivec);
+}
+
+void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec, int enc)
+{
+ DES_pcbc_encrypt((unsigned char *)input, (unsigned char *)output,
+ length, (DES_key_schedule *)schedule, ivec, enc);
+}
+
+DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,
+ _ossl_old_des_cblock *output, long length,
+ int out_count, _ossl_old_des_cblock *seed)
+{
+ return DES_quad_cksum((unsigned char *)input, output, length,
+ out_count, seed);
+}
+
+void _ossl_old_des_random_seed(_ossl_old_des_cblock key)
+{
+ RAND_seed(key, sizeof(_ossl_old_des_cblock));
+}
+
+void _ossl_old_des_random_key(_ossl_old_des_cblock ret)
+{
+ DES_random_key((DES_cblock *)ret);
+}
+
+int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt,
+ int verify)
+{
+ return DES_read_password(key, prompt, verify);
+}
+
+int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,
+ _ossl_old_des_cblock *key2,
+ const char *prompt, int verify)
+{
+ return DES_read_2passwords(key1, key2, prompt, verify);
+}
+
+void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key)
+{
+ DES_set_odd_parity(key);
+}
+
+int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key)
+{
+ return DES_is_weak_key(key);
+}
+
+int _ossl_old_des_set_key(_ossl_old_des_cblock *key,
+ des_key_schedule schedule)
+{
+ return DES_set_key(key, (DES_key_schedule *)schedule);
+}
+
+int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,
+ des_key_schedule schedule)
+{
+ return DES_key_sched(key, (DES_key_schedule *)schedule);
+}
+
+void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key)
+{
+ DES_string_to_key(str, key);
+}
+
+void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1,
+ _ossl_old_des_cblock *key2)
+{
+ DES_string_to_2keys(str, key1, key2);
+}
+
+void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec, int *num,
+ int enc)
+{
+ DES_cfb64_encrypt(in, out, length, (DES_key_schedule *)schedule,
+ ivec, num, enc);
+}
+
+void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, des_key_schedule schedule,
+ _ossl_old_des_cblock *ivec, int *num)
+{
+ DES_ofb64_encrypt(in, out, length, (DES_key_schedule *)schedule,
+ ivec, num);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/des_old2.c b/Cryptlib/OpenSSL/crypto/des/des_old2.c
new file mode 100644
index 00000000..247ff8dc
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/des_old2.c
@@ -0,0 +1,80 @@
+/* crypto/des/des_old.c */
+
+/*
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING The
+ * function names in here are deprecated and are only present to provide an
+ * interface compatible with OpenSSL 0.9.6c. OpenSSL now provides functions
+ * where "des_" has been replaced with "DES_" in the names, to make it
+ * possible to make incompatible changes that are needed for C type security
+ * and other stuff. Please consider starting to use the DES_ functions
+ * rather than the des_ ones. The des_ functions will dissapear completely
+ * before OpenSSL 1.0! WARNING WARNING WARNING WARNING WARNING WARNING
+ * WARNING WARNING
+ */
+
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#undef OPENSSL_DES_LIBDES_COMPATIBILITY
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+void _ossl_096_des_random_seed(DES_cblock *key)
+{
+ RAND_seed(key, sizeof(DES_cblock));
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/des_ver.h b/Cryptlib/OpenSSL/crypto/des/des_ver.h
new file mode 100644
index 00000000..276de2b6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/des_ver.h
@@ -0,0 +1,73 @@
+/* crypto/des/des_ver.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 <openssl/e_os2.h>
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+/* The following macros make sure the names are different from libdes names */
+#define DES_version OSSL_DES_version
+#define libdes_version OSSL_libdes_version
+
+/* SSLeay version string */
+OPENSSL_EXTERN const char OSSL_DES_version[];
+/* old libdes version string */
+OPENSSL_EXTERN const char OSSL_libdes_version[];
diff --git a/Cryptlib/OpenSSL/crypto/des/ecb3_enc.c b/Cryptlib/OpenSSL/crypto/des/ecb3_enc.c
new file mode 100644
index 00000000..c49fbd41
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ecb3_enc.c
@@ -0,0 +1,82 @@
+/* crypto/des/ecb3_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"
+
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+ DES_key_schedule *ks1, DES_key_schedule *ks2,
+ DES_key_schedule *ks3, int enc)
+{
+ register DES_LONG l0, l1;
+ DES_LONG ll[2];
+ const unsigned char *in = &(*input)[0];
+ unsigned char *out = &(*output)[0];
+
+ c2l(in, l0);
+ c2l(in, l1);
+ ll[0] = l0;
+ ll[1] = l1;
+ if (enc)
+ DES_encrypt3(ll, ks1, ks2, ks3);
+ else
+ DES_decrypt3(ll, ks1, ks2, ks3);
+ l0 = ll[0];
+ l1 = ll[1];
+ l2c(l0, out);
+ l2c(l1, out);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/ecb_enc.c b/Cryptlib/OpenSSL/crypto/des/ecb_enc.c
new file mode 100644
index 00000000..f97fd971
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ecb_enc.c
@@ -0,0 +1,124 @@
+/* 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 <openssl/opensslv.h>
+#include <openssl/bio.h>
+
+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)
+{
+ register DES_LONG l;
+ DES_LONG ll[2];
+ const unsigned char *in = &(*input)[0];
+ unsigned char *out = &(*output)[0];
+
+ c2l(in, l);
+ ll[0] = l;
+ c2l(in, l);
+ ll[1] = l;
+ DES_encrypt1(ll, ks, enc);
+ l = ll[0];
+ l2c(l, out);
+ l = ll[1];
+ l2c(l, out);
+ l = ll[0] = ll[1] = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/ede_cbcm_enc.c b/Cryptlib/OpenSSL/crypto/des/ede_cbcm_enc.c
new file mode 100644
index 00000000..86f27d07
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ede_cbcm_enc.c
@@ -0,0 +1,189 @@
+/* ede_cbcm_enc.c */
+/*
+ * Written by Ben Laurie <ben@algroup.co.uk> for the OpenSSL project 13 Feb
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+/*
+ *
+ * This is an implementation of Triple DES Cipher Block Chaining with Output
+ * Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom).
+ *
+ * Note that there is a known attack on this by Biham and Knudsen but it
+ * takes a lot of work:
+ *
+ * http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz
+ *
+ */
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_DESCBCM is defined */
+
+#ifndef OPENSSL_NO_DESCBCM
+# include "des_locl.h"
+
+void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec1, DES_cblock *ivec2, int enc)
+{
+ register DES_LONG tin0, tin1;
+ register DES_LONG tout0, tout1, xor0, xor1, m0, m1;
+ register long l = length;
+ DES_LONG tin[2];
+ unsigned char *iv1, *iv2;
+
+ iv1 = &(*ivec1)[0];
+ iv2 = &(*ivec2)[0];
+
+ if (enc) {
+ c2l(iv1, m0);
+ c2l(iv1, m1);
+ c2l(iv2, tout0);
+ c2l(iv2, tout1);
+ for (l -= 8; l >= -7; l -= 8) {
+ tin[0] = m0;
+ tin[1] = m1;
+ DES_encrypt1(tin, ks3, 1);
+ m0 = tin[0];
+ m1 = tin[1];
+
+ if (l < 0) {
+ c2ln(in, tin0, tin1, l + 8);
+ } else {
+ c2l(in, tin0);
+ c2l(in, tin1);
+ }
+ tin0 ^= tout0;
+ tin1 ^= tout1;
+
+ tin[0] = tin0;
+ tin[1] = tin1;
+ DES_encrypt1(tin, ks1, 1);
+ tin[0] ^= m0;
+ tin[1] ^= m1;
+ DES_encrypt1(tin, ks2, 0);
+ tin[0] ^= m0;
+ tin[1] ^= m1;
+ DES_encrypt1(tin, ks1, 1);
+ tout0 = tin[0];
+ tout1 = tin[1];
+
+ l2c(tout0, out);
+ l2c(tout1, out);
+ }
+ iv1 = &(*ivec1)[0];
+ l2c(m0, iv1);
+ l2c(m1, iv1);
+
+ iv2 = &(*ivec2)[0];
+ l2c(tout0, iv2);
+ l2c(tout1, iv2);
+ } else {
+ register DES_LONG t0, t1;
+
+ c2l(iv1, m0);
+ c2l(iv1, m1);
+ c2l(iv2, xor0);
+ c2l(iv2, xor1);
+ for (l -= 8; l >= -7; l -= 8) {
+ tin[0] = m0;
+ tin[1] = m1;
+ DES_encrypt1(tin, ks3, 1);
+ m0 = tin[0];
+ m1 = tin[1];
+
+ c2l(in, tin0);
+ c2l(in, tin1);
+
+ t0 = tin0;
+ t1 = tin1;
+
+ tin[0] = tin0;
+ tin[1] = tin1;
+ DES_encrypt1(tin, ks1, 0);
+ tin[0] ^= m0;
+ tin[1] ^= m1;
+ DES_encrypt1(tin, ks2, 1);
+ tin[0] ^= m0;
+ tin[1] ^= m1;
+ DES_encrypt1(tin, ks1, 0);
+ tout0 = tin[0];
+ tout1 = tin[1];
+
+ tout0 ^= xor0;
+ tout1 ^= xor1;
+ if (l < 0) {
+ l2cn(tout0, tout1, out, l + 8);
+ } else {
+ l2c(tout0, out);
+ l2c(tout1, out);
+ }
+ xor0 = t0;
+ xor1 = t1;
+ }
+
+ iv1 = &(*ivec1)[0];
+ l2c(m0, iv1);
+ l2c(m1, iv1);
+
+ iv2 = &(*ivec2)[0];
+ l2c(xor0, iv2);
+ l2c(xor1, iv2);
+ }
+ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+ tin[0] = tin[1] = 0;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/des/enc_read.c b/Cryptlib/OpenSSL/crypto/des/enc_read.c
new file mode 100644
index 00000000..fcb66541
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/enc_read.c
@@ -0,0 +1,235 @@
+/* crypto/des/enc_read.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include "des_locl.h"
+
+/* 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)
+
+/*-
+ * WARNINGS:
+ *
+ * - The data format used by DES_enc_write() and DES_enc_read()
+ * has a cryptographic weakness: When asked to write more
+ * than MAXWRITE bytes, DES_enc_write will split the data
+ * into several chunks that are all encrypted
+ * using the same IV. So don't use these functions unless you
+ * are sure you know what you do (in which case you might
+ * not want to use them anyway).
+ *
+ * - This code cannot handle non-blocking sockets.
+ *
+ * - This function uses an internal state and thus cannot be
+ * used on multiple files.
+ */
+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;
+ /*
+ * extra unencrypted data for when a block of 100 comes in but is
+ * des_read one byte at a time.
+ */
+ static unsigned char *unnet = NULL;
+ static int unnet_start = 0;
+ static int unnet_left = 0;
+ static unsigned char *tmpbuf = NULL;
+ int i;
+ long num = 0, rnum;
+ unsigned char *p;
+
+ if (tmpbuf == NULL) {
+ tmpbuf = OPENSSL_malloc(BSIZE);
+ if (tmpbuf == NULL)
+ return (-1);
+ }
+ if (net == NULL) {
+ net = OPENSSL_malloc(BSIZE);
+ if (net == NULL)
+ return (-1);
+ }
+ if (unnet == NULL) {
+ unnet = OPENSSL_malloc(BSIZE);
+ if (unnet == NULL)
+ return (-1);
+ }
+ /* left over data from last decrypt */
+ if (unnet_left != 0) {
+ if (unnet_left < len) {
+ /*
+ * we still still need more data but will return with the number
+ * of bytes we have - should always check the return value
+ */
+ memcpy(buf, &(unnet[unnet_start]), unnet_left);
+ /*
+ * eay 26/08/92 I had the next 2 lines reversed :-(
+ */
+ i = unnet_left;
+ unnet_start = unnet_left = 0;
+ } else {
+ memcpy(buf, &(unnet[unnet_start]), len);
+ unnet_start += len;
+ unnet_left -= len;
+ i = len;
+ }
+ return (i);
+ }
+
+ /* We need to get more data. */
+ if (len > MAXWRITE)
+ len = MAXWRITE;
+
+ /* first - get the length */
+ while (net_num < HDRSIZE) {
+# 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);
+# endif
+# ifdef EINTR
+ if ((i == -1) && (errno == EINTR))
+ continue;
+# endif
+ if (i <= 0)
+ return (0);
+ net_num += i;
+ }
+
+ /* we now have at net_num bytes in net */
+ p = net;
+ /* num=0; */
+ n2l(p, num);
+ /*
+ * num should be rounded up to the next group of eight we make sure that
+ * we have read a multiple of 8 bytes from the net.
+ */
+ if ((num > MAXWRITE) || (num < 0)) /* error */
+ return (-1);
+ rnum = (num < 8) ? 8 : ((num + 7) / 8 * 8);
+
+ 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
+ if (i <= 0)
+ return (0);
+ net_num += i;
+ }
+
+ /* Check if there will be data left over. */
+ if (len < num) {
+ if (DES_rw_mode & DES_PCBC_MODE)
+ DES_pcbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT);
+ else
+ DES_cbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT);
+ memcpy(buf, unnet, len);
+ unnet_start = len;
+ unnet_left = num - len;
+
+ /*
+ * The following line is done because we return num as the number of
+ * bytes read.
+ */
+ num = len;
+ } else {
+ /*-
+ * >output is a multiple of 8 byes, if len < rnum
+ * >we must be careful. The user must be aware that this
+ * >routine will write more bytes than he asked for.
+ * >The length of the buffer must be correct.
+ * FIXED - Should be ok now 18-9-90 - eay */
+ if (len < rnum) {
+
+ if (DES_rw_mode & DES_PCBC_MODE)
+ DES_pcbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT);
+ else
+ DES_cbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT);
+
+ /*
+ * eay 26/08/92 fix a bug that returned more bytes than you asked
+ * for (returned len bytes :-(
+ */
+ memcpy(buf, tmpbuf, num);
+ } else {
+ if (DES_rw_mode & DES_PCBC_MODE)
+ DES_pcbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT);
+ else
+ DES_cbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT);
+ }
+ }
+ return num;
+#endif /* OPENSSL_NO_POSIX_IO */
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/enc_writ.c b/Cryptlib/OpenSSL/crypto/des/enc_writ.c
new file mode 100644
index 00000000..bfaabde5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/enc_writ.c
@@ -0,0 +1,182 @@
+/* crypto/des/enc_writ.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 <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "des_locl.h"
+#include <openssl/rand.h>
+
+/*-
+ * WARNINGS:
+ *
+ * - The data format used by DES_enc_write() and DES_enc_read()
+ * has a cryptographic weakness: When asked to write more
+ * than MAXWRITE bytes, DES_enc_write will split the data
+ * into several chunks that are all encrypted
+ * using the same IV. So don't use these functions unless you
+ * are sure you know what you do (in which case you might
+ * not want to use them anyway).
+ *
+ * - This code cannot handle non-blocking sockets.
+ */
+
+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();
+# endif
+ const unsigned char *buf = _buf;
+ long rnum;
+ int i, j, k, outnum;
+ static unsigned char *outbuf = NULL;
+ unsigned char shortbuf[8];
+ unsigned char *p;
+ const unsigned char *cp;
+ static int start = 1;
+
+ if (len < 0)
+ return -1;
+
+ if (outbuf == NULL) {
+ outbuf = OPENSSL_malloc(BSIZE + HDRSIZE);
+ if (outbuf == NULL)
+ return (-1);
+ }
+ /*
+ * If we are sending less than 8 bytes, the same char will look the same
+ * if we don't pad it out with random bytes
+ */
+ if (start) {
+ start = 0;
+ }
+
+ /* lets recurse if we want to send the data in small chunks */
+ if (len > MAXWRITE) {
+ j = 0;
+ for (i = 0; i < len; i += k) {
+ k = DES_enc_write(fd, &(buf[i]),
+ ((len - i) > MAXWRITE) ? MAXWRITE : (len - i),
+ sched, iv);
+ if (k < 0)
+ return (k);
+ else
+ j += k;
+ }
+ return (j);
+ }
+
+ /* write length first */
+ p = outbuf;
+ l2n(len, p);
+
+ /* pad short strings */
+ if (len < 8) {
+ cp = shortbuf;
+ memcpy(shortbuf, buf, len);
+ if (RAND_pseudo_bytes(shortbuf + len, 8 - len) < 0) {
+ return -1;
+ }
+ rnum = 8;
+ } else {
+ cp = buf;
+ rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */
+ }
+
+ if (DES_rw_mode & DES_PCBC_MODE)
+ DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched,
+ iv, DES_ENCRYPT);
+ else
+ DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched,
+ iv, DES_ENCRYPT);
+
+ /* output */
+ outnum = rnum + HDRSIZE;
+
+ for (j = 0; j < outnum; j += i) {
+ /*
+ * eay 26/08/92 I was not doing writing from where we got up to.
+ */
+# ifndef _WIN32
+ i = write(fd, (void *)&(outbuf[j]), outnum - j);
+# else
+ i = _write(fd, (void *)&(outbuf[j]), outnum - j);
+# endif
+ if (i == -1) {
+# ifdef EINTR
+ if (errno == EINTR)
+ i = 0;
+ else
+# endif
+ /*
+ * This is really a bad error - very bad It will stuff-up
+ * both ends.
+ */
+ return (-1);
+ }
+ }
+
+ return (len);
+#endif /* OPENSSL_NO_POSIX_IO */
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/fcrypt.c b/Cryptlib/OpenSSL/crypto/des/fcrypt.c
new file mode 100644
index 00000000..111f1e46
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/fcrypt.c
@@ -0,0 +1,167 @@
+/* NOCW */
+#include <stdio.h>
+#ifdef _OSD_POSIX
+# ifndef CHARSET_EBCDIC
+# define CHARSET_EBCDIC 1
+# endif
+#endif
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+/*
+ * This version of crypt has been developed from my MIT compatible DES
+ * library. Eric Young (eay@cryptsoft.com)
+ */
+
+/*
+ * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for
+ * shared memory computers. I have included a directive LONGCRYPT to using
+ * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it
+ * used. The MAXPLEN definition is the maximum of length of password and can
+ * changed. I have defined 24.
+ */
+
+#include "des_locl.h"
+
+/*
+ * Added more values to handle illegal salt values the way normal crypt()
+ * implementations do. The patch was sent by Bjorn Gronvall <bg@sics.se>
+ */
+static unsigned const char con_salt[128] = {
+ 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+ 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1,
+ 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
+ 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,
+ 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
+ 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
+ 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
+ 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
+ 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
+ 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
+};
+
+static unsigned const char cov_2char[64] = {
+ 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
+ 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
+ 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
+ 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
+ 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
+ 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
+};
+
+char *DES_crypt(const char *buf, const char *salt)
+{
+ static char buff[14];
+
+#ifndef CHARSET_EBCDIC
+ return (DES_fcrypt(buf, salt, buff));
+#else
+ char e_salt[2 + 1];
+ char e_buf[32 + 1]; /* replace 32 by 8 ? */
+ char *ret;
+
+ /* Copy at most 2 chars of salt */
+ if ((e_salt[0] = salt[0]) != '\0')
+ e_salt[1] = salt[1];
+
+ /* Copy at most 32 chars of password */
+ strncpy(e_buf, buf, sizeof(e_buf));
+
+ /* Make sure we have a delimiter */
+ e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0';
+
+ /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */
+ ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
+
+ /* Convert the cleartext password to ASCII */
+ ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
+
+ /* Encrypt it (from/to ASCII) */
+ ret = DES_fcrypt(e_buf, e_salt, buff);
+
+ /* Convert the result back to EBCDIC */
+ ascii2ebcdic(ret, ret, strlen(ret));
+
+ return ret;
+#endif
+}
+
+char *DES_fcrypt(const char *buf, const char *salt, char *ret)
+{
+ unsigned int i, j, x, y;
+ DES_LONG Eswap0, Eswap1;
+ DES_LONG out[2], ll;
+ DES_cblock key;
+ DES_key_schedule ks;
+ unsigned char bb[9];
+ unsigned char *b = bb;
+ unsigned char c, u;
+
+ /*
+ * eay 25/08/92 If you call crypt("pwd","*") as often happens when you
+ * have * as the pwd field in /etc/passwd, the function returns
+ * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would
+ * crypt to "*". This was found when replacing the crypt in our shared
+ * libraries. People found that the disabled accounts effectively had no
+ * passwd :-(.
+ */
+#ifndef CHARSET_EBCDIC
+ x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]);
+ Eswap0 = con_salt[x] << 2;
+ x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]);
+ Eswap1 = con_salt[x] << 6;
+#else
+ x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]);
+ Eswap0 = con_salt[x] << 2;
+ x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]);
+ Eswap1 = con_salt[x] << 6;
+#endif
+
+ /*
+ * EAY r=strlen(buf); r=(r+7)/8;
+ */
+ for (i = 0; i < 8; i++) {
+ c = *(buf++);
+ if (!c)
+ break;
+ key[i] = (c << 1);
+ }
+ for (; i < 8; i++)
+ key[i] = 0;
+
+ DES_set_key_unchecked(&key, &ks);
+ fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1);
+
+ ll = out[0];
+ l2c(ll, b);
+ ll = out[1];
+ l2c(ll, b);
+ y = 0;
+ u = 0x80;
+ bb[8] = 0;
+ for (i = 2; i < 13; i++) {
+ c = 0;
+ for (j = 0; j < 6; j++) {
+ c <<= 1;
+ if (bb[y] & u)
+ c |= 1;
+ u >>= 1;
+ if (!u) {
+ y++;
+ u = 0x80;
+ }
+ }
+ ret[i] = cov_2char[c];
+ }
+ ret[13] = '\0';
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/fcrypt_b.c b/Cryptlib/OpenSSL/crypto/des/fcrypt_b.c
new file mode 100644
index 00000000..b9e87383
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/fcrypt_b.c
@@ -0,0 +1,140 @@
+/* crypto/des/fcrypt_b.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 <stdio.h>
+
+/*
+ * This version of crypt has been developed from my MIT compatible DES
+ * library. The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+#define DES_FCRYPT
+#include "des_locl.h"
+#undef DES_FCRYPT
+
+#undef PERM_OP
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#undef HPERM_OP
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))\
+
+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
+ DES_LONG Eswap1)
+{
+ register DES_LONG l, r, t, u;
+#ifdef DES_PTR
+ register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
+#endif
+ register DES_LONG *s;
+ register int j;
+ register DES_LONG E0, E1;
+
+ l = 0;
+ r = 0;
+
+ s = (DES_LONG *)ks;
+ E0 = Eswap0;
+ E1 = Eswap1;
+
+ for (j = 0; j < 25; j++) {
+#ifndef DES_UNROLL
+ register int i;
+
+ for (i = 0; i < 32; i += 4) {
+ D_ENCRYPT(l, r, i + 0); /* 1 */
+ D_ENCRYPT(r, l, i + 2); /* 2 */
+ }
+#else
+ D_ENCRYPT(l, r, 0); /* 1 */
+ D_ENCRYPT(r, l, 2); /* 2 */
+ D_ENCRYPT(l, r, 4); /* 3 */
+ D_ENCRYPT(r, l, 6); /* 4 */
+ D_ENCRYPT(l, r, 8); /* 5 */
+ D_ENCRYPT(r, l, 10); /* 6 */
+ D_ENCRYPT(l, r, 12); /* 7 */
+ D_ENCRYPT(r, l, 14); /* 8 */
+ D_ENCRYPT(l, r, 16); /* 9 */
+ D_ENCRYPT(r, l, 18); /* 10 */
+ D_ENCRYPT(l, r, 20); /* 11 */
+ D_ENCRYPT(r, l, 22); /* 12 */
+ D_ENCRYPT(l, r, 24); /* 13 */
+ D_ENCRYPT(r, l, 26); /* 14 */
+ D_ENCRYPT(l, r, 28); /* 15 */
+ D_ENCRYPT(r, l, 30); /* 16 */
+#endif
+
+ t = l;
+ l = r;
+ r = t;
+ }
+ l = ROTATE(l, 3) & 0xffffffffL;
+ r = ROTATE(r, 3) & 0xffffffffL;
+
+ PERM_OP(l, r, t, 1, 0x55555555L);
+ PERM_OP(r, l, t, 8, 0x00ff00ffL);
+ PERM_OP(l, r, t, 2, 0x33333333L);
+ PERM_OP(r, l, t, 16, 0x0000ffffL);
+ PERM_OP(l, r, t, 4, 0x0f0f0f0fL);
+
+ out[0] = r;
+ out[1] = l;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/ncbc_enc.c b/Cryptlib/OpenSSL/crypto/des/ncbc_enc.c
new file mode 100644
index 00000000..ab267cbf
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ncbc_enc.c
@@ -0,0 +1,154 @@
+/* crypto/des/ncbc_enc.c */
+/*-
+ * #included by:
+ * cbc_enc.c (DES_cbc_encrypt)
+ * des_enc.c (DES_ncbc_encrypt)
+ */
+/* 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"
+
+#ifdef CBC_ENC_C__DONT_UPDATE_IV
+void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+ DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#else
+void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out,
+ long length, DES_key_schedule *_schedule,
+ DES_cblock *ivec, int enc)
+#endif
+{
+ register DES_LONG tin0, tin1;
+ register DES_LONG tout0, tout1, xor0, xor1;
+ register long l = length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ iv = &(*ivec)[0];
+
+ if (enc) {
+ c2l(iv, tout0);
+ c2l(iv, tout1);
+ for (l -= 8; l >= 0; l -= 8) {
+ c2l(in, tin0);
+ c2l(in, tin1);
+ tin0 ^= tout0;
+ tin[0] = tin0;
+ tin1 ^= tout1;
+ tin[1] = tin1;
+ DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
+ tout0 = tin[0];
+ l2c(tout0, out);
+ tout1 = tin[1];
+ l2c(tout1, out);
+ }
+ if (l != -8) {
+ c2ln(in, tin0, tin1, l + 8);
+ tin0 ^= tout0;
+ tin[0] = tin0;
+ tin1 ^= tout1;
+ tin[1] = tin1;
+ DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
+ tout0 = tin[0];
+ l2c(tout0, out);
+ tout1 = tin[1];
+ l2c(tout1, out);
+ }
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+ iv = &(*ivec)[0];
+ l2c(tout0, iv);
+ l2c(tout1, iv);
+#endif
+ } else {
+ c2l(iv, xor0);
+ c2l(iv, xor1);
+ for (l -= 8; l >= 0; l -= 8) {
+ c2l(in, tin0);
+ tin[0] = tin0;
+ c2l(in, tin1);
+ tin[1] = tin1;
+ DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
+ 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;
+ DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
+ tout0 = tin[0] ^ xor0;
+ tout1 = tin[1] ^ xor1;
+ l2cn(tout0, tout1, out, l + 8);
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+ xor0 = tin0;
+ xor1 = tin1;
+#endif
+ }
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+ iv = &(*ivec)[0];
+ l2c(xor0, iv);
+ l2c(xor1, iv);
+#endif
+ }
+ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+ tin[0] = tin[1] = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/ofb64ede.c b/Cryptlib/OpenSSL/crypto/des/ofb64ede.c
new file mode 100644
index 00000000..45c67505
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ofb64ede.c
@@ -0,0 +1,123 @@
+/* crypto/des/ofb64ede.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"
+
+/*
+ * 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 DES_ede3_ofb64_encrypt(register const unsigned char *in,
+ register unsigned char *out, long length,
+ DES_key_schedule *k1, DES_key_schedule *k2,
+ DES_key_schedule *k3, DES_cblock *ivec, int *num)
+{
+ register DES_LONG v0, v1;
+ register int n = *num;
+ register long l = length;
+ DES_cblock d;
+ register char *dp;
+ DES_LONG ti[2];
+ unsigned char *iv;
+ int save = 0;
+
+ iv = &(*ivec)[0];
+ 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) {
+ /* ti[0]=v0; */
+ /* ti[1]=v1; */
+ DES_encrypt3(ti, k1, k2, k3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ dp = (char *)d;
+ l2c(v0, dp);
+ l2c(v1, dp);
+ save++;
+ }
+ *(out++) = *(in++) ^ d[n];
+ n = (n + 1) & 0x07;
+ }
+ if (save) {
+/*- v0=ti[0];
+ v1=ti[1];*/
+ iv = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ }
+ v0 = v1 = ti[0] = ti[1] = 0;
+ *num = n;
+}
+
+#ifdef undef /* MACRO */
+void DES_ede2_ofb64_encrypt(register unsigned char *in,
+ register unsigned char *out, long length,
+ DES_key_schedule k1, DES_key_schedule k2,
+ DES_cblock (*ivec), int *num)
+{
+ DES_ede3_ofb64_encrypt(in, out, length, k1, k2, k1, ivec, num);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/des/ofb64enc.c b/Cryptlib/OpenSSL/crypto/des/ofb64enc.c
new file mode 100644
index 00000000..8e72dece
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ofb64enc.c
@@ -0,0 +1,109 @@
+/* crypto/des/ofb64enc.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"
+
+/*
+ * 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 DES_ofb64_encrypt(register const unsigned char *in,
+ register unsigned char *out, long length,
+ DES_key_schedule *schedule, DES_cblock *ivec, int *num)
+{
+ register DES_LONG v0, v1, t;
+ register int n = *num;
+ register long l = length;
+ DES_cblock d;
+ register unsigned char *dp;
+ DES_LONG ti[2];
+ unsigned char *iv;
+ int save = 0;
+
+ iv = &(*ivec)[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ ti[0] = v0;
+ ti[1] = v1;
+ dp = d;
+ l2c(v0, dp);
+ l2c(v1, dp);
+ while (l--) {
+ if (n == 0) {
+ DES_encrypt1(ti, schedule, DES_ENCRYPT);
+ dp = 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 = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ }
+ t = v0 = v1 = ti[0] = ti[1] = 0;
+ *num = n;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/ofb_enc.c b/Cryptlib/OpenSSL/crypto/des/ofb_enc.c
new file mode 100644
index 00000000..02a78775
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/ofb_enc.c
@@ -0,0 +1,131 @@
+/* crypto/des/ofb_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"
+
+/*
+ * The input and output are loaded in multiples of 8 bits. What this means is
+ * that if you hame numbits=12 and length=2 the first 12 bits will be
+ * retrieved from the first byte and half the second. The second 12 bits
+ * will come from the 3rd and half the 4th byte.
+ */
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+ long length, DES_key_schedule *schedule,
+ DES_cblock *ivec)
+{
+ register DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7) / 8;
+ register DES_LONG mask0, mask1;
+ register long l = length;
+ register int num = numbits;
+ DES_LONG ti[2];
+ unsigned char *iv;
+
+ if (num > 64)
+ return;
+ if (num > 32) {
+ mask0 = 0xffffffffL;
+ if (num >= 64)
+ mask1 = mask0;
+ else
+ mask1 = (1L << (num - 32)) - 1;
+ } else {
+ if (num == 32)
+ mask0 = 0xffffffffL;
+ else
+ mask0 = (1L << num) - 1;
+ mask1 = 0x00000000L;
+ }
+
+ iv = &(*ivec)[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ ti[0] = v0;
+ ti[1] = v1;
+ while (l-- > 0) {
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
+ vv0 = ti[0];
+ vv1 = ti[1];
+ c2ln(in, d0, d1, n);
+ in += n;
+ d0 = (d0 ^ vv0) & mask0;
+ d1 = (d1 ^ vv1) & mask1;
+ l2cn(d0, d1, out, n);
+ out += n;
+
+ if (num == 32) {
+ v0 = v1;
+ v1 = vv0;
+ } else if (num == 64) {
+ v0 = vv0;
+ v1 = vv1;
+ } else if (num > 32) { /* && num != 64 */
+ v0 = ((v1 >> (num - 32)) | (vv0 << (64 - num))) & 0xffffffffL;
+ v1 = ((vv0 >> (num - 32)) | (vv1 << (64 - num))) & 0xffffffffL;
+ } else { /* num < 32 */
+
+ v0 = ((v0 >> num) | (v1 << (32 - num))) & 0xffffffffL;
+ v1 = ((v1 >> num) | (vv0 << (32 - num))) & 0xffffffffL;
+ }
+ }
+ iv = &(*ivec)[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/pcbc_enc.c b/Cryptlib/OpenSSL/crypto/des/pcbc_enc.c
new file mode 100644
index 00000000..144d5ed8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/pcbc_enc.c
@@ -0,0 +1,115 @@
+/* crypto/des/pcbc_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"
+
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+ long length, DES_key_schedule *schedule,
+ DES_cblock *ivec, int enc)
+{
+ register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1;
+ DES_LONG tin[2];
+ const unsigned char *in;
+ unsigned char *out, *iv;
+
+ in = input;
+ out = output;
+ iv = &(*ivec)[0];
+
+ if (enc) {
+ c2l(iv, xor0);
+ c2l(iv, xor1);
+ for (; length > 0; length -= 8) {
+ if (length >= 8) {
+ c2l(in, sin0);
+ c2l(in, sin1);
+ } else
+ c2ln(in, sin0, sin1, length);
+ tin[0] = sin0 ^ xor0;
+ tin[1] = sin1 ^ xor1;
+ DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT);
+ tout0 = tin[0];
+ tout1 = tin[1];
+ xor0 = sin0 ^ tout0;
+ xor1 = sin1 ^ tout1;
+ l2c(tout0, out);
+ l2c(tout1, out);
+ }
+ } else {
+ c2l(iv, xor0);
+ c2l(iv, xor1);
+ for (; length > 0; length -= 8) {
+ c2l(in, sin0);
+ c2l(in, sin1);
+ tin[0] = sin0;
+ tin[1] = sin1;
+ DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT);
+ tout0 = tin[0] ^ xor0;
+ tout1 = tin[1] ^ xor1;
+ if (length >= 8) {
+ l2c(tout0, out);
+ l2c(tout1, out);
+ } else
+ l2cn(tout0, tout1, out, length);
+ xor0 = tout0 ^ sin0;
+ xor1 = tout1 ^ sin1;
+ }
+ }
+ tin[0] = tin[1] = 0;
+ sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/qud_cksm.c b/Cryptlib/OpenSSL/crypto/des/qud_cksm.c
new file mode 100644
index 00000000..2a168a57
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/qud_cksm.c
@@ -0,0 +1,143 @@
+/* crypto/des/qud_cksm.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.]
+ */
+
+/*
+ * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE
+ * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in
+ * only based on the code in this paper and is almost definitely not the same
+ * as the MIT implementation.
+ */
+#include "des_locl.h"
+
+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
+#define Q_B0(a) (((DES_LONG)(a)))
+#define Q_B1(a) (((DES_LONG)(a))<<8)
+#define Q_B2(a) (((DES_LONG)(a))<<16)
+#define Q_B3(a) (((DES_LONG)(a))<<24)
+
+/* used to scramble things a bit */
+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
+#define NOISE ((DES_LONG)83653421L)
+
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+ long length, int out_count, DES_cblock *seed)
+{
+ DES_LONG z0, z1, t0, t1;
+ int i;
+ long l;
+ const unsigned char *cp;
+#ifdef _CRAY
+ struct lp_st {
+ int a:32;
+ int b:32;
+ } *lp;
+#else
+ DES_LONG *lp;
+#endif
+
+ if (out_count < 1)
+ out_count = 1;
+#ifdef _CRAY
+ lp = (struct lp_st *)&(output[0])[0];
+#else
+ lp = (DES_LONG *)&(output[0])[0];
+#endif
+
+ z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) |
+ Q_B3((*seed)[3]);
+ z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) |
+ Q_B3((*seed)[7]);
+
+ for (i = 0; ((i < 4) && (i < out_count)); i++) {
+ cp = input;
+ l = length;
+ while (l > 0) {
+ if (l > 1) {
+ t0 = (DES_LONG)(*(cp++));
+ t0 |= (DES_LONG)Q_B1(*(cp++));
+ l--;
+ } else
+ t0 = (DES_LONG)(*(cp++));
+ l--;
+ /* add */
+ t0 += z0;
+ t0 &= 0xffffffffL;
+ t1 = z1;
+ /* square, well sort of square */
+ z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL))
+ & 0xffffffffL) % 0x7fffffffL;
+ z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) %
+ 0x7fffffffL;
+ }
+ if (lp != NULL) {
+ /*
+ * The MIT library assumes that the checksum is composed of
+ * 2*out_count 32 bit ints
+ */
+#ifdef _CRAY
+ (*lp).a = z0;
+ (*lp).b = z1;
+ lp++;
+#else
+ *lp++ = z0;
+ *lp++ = z1;
+#endif
+ }
+ }
+ return (z0);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/rand_key.c b/Cryptlib/OpenSSL/crypto/des/rand_key.c
new file mode 100644
index 00000000..b75cc5f9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/rand_key.c
@@ -0,0 +1,67 @@
+/* crypto/des/rand_key.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+int DES_random_key(DES_cblock *ret)
+{
+ do {
+ if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1)
+ return (0);
+ } while (DES_is_weak_key(ret));
+ DES_set_odd_parity(ret);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/read2pwd.c b/Cryptlib/OpenSSL/crypto/des/read2pwd.c
new file mode 100644
index 00000000..76331396
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/read2pwd.c
@@ -0,0 +1,144 @@
+/* crypto/des/read2pwd.c */
+/* ====================================================================
+ * Copyright (c) 2001-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).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <string.h>
+#include <openssl/des.h>
+#include <openssl/ui.h>
+#include <openssl/crypto.h>
+
+#ifndef BUFSIZ
+#define BUFSIZ 256
+#endif
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify)
+{
+ int ok;
+ char buf[BUFSIZ], buff[BUFSIZ];
+
+ if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0)
+ DES_string_to_key(buf, key);
+ OPENSSL_cleanse(buf, BUFSIZ);
+ OPENSSL_cleanse(buff, BUFSIZ);
+ return (ok);
+}
+
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2,
+ const char *prompt, int verify)
+{
+ int ok;
+ char buf[BUFSIZ], buff[BUFSIZ];
+
+ if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0)
+ DES_string_to_2keys(buf, key1, key2);
+ OPENSSL_cleanse(buf, BUFSIZ);
+ OPENSSL_cleanse(buff, BUFSIZ);
+ return (ok);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/rpc_des.h b/Cryptlib/OpenSSL/crypto/des/rpc_des.h
new file mode 100644
index 00000000..4db9062d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/rpc_des.h
@@ -0,0 +1,130 @@
+/* crypto/des/rpc_des.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.]
+ */
+
+/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */
+/*-
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */
+#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */
+
+#ifdef HEADER_DES_H
+# undef ENCRYPT
+# undef DECRYPT
+#endif
+
+enum desdir { ENCRYPT, DECRYPT };
+enum desmode { CBC, ECB };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams {
+ unsigned char des_key[8]; /* key (with low bit parity) */
+ enum desdir des_dir; /* direction */
+ enum desmode des_mode; /* mode */
+ unsigned char des_ivec[8]; /* input vector */
+ unsigned des_len; /* number of bytes to crypt */
+ union {
+ unsigned char UDES_data[DES_QUICKLEN];
+ unsigned char *UDES_buf;
+ } UDES;
+#define des_data UDES.UDES_data /* direct data here if quick */
+#define des_buf UDES.UDES_buf /* otherwise, pointer to data */
+};
+
+/*
+ * Encrypt an arbitrary sized buffer
+ */
+#define DESIOCBLOCK _IOWR('d', 6, struct desparams)
+
+/*
+ * Encrypt of small amount of data, quickly
+ */
+#define DESIOCQUICK _IOWR('d', 7, struct desparams)
diff --git a/Cryptlib/OpenSSL/crypto/des/rpc_enc.c b/Cryptlib/OpenSSL/crypto/des/rpc_enc.c
new file mode 100644
index 00000000..f5a84c5b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/rpc_enc.c
@@ -0,0 +1,100 @@
+/* crypto/des/rpc_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 "rpc_des.h"
+#include "des_locl.h"
+#include "des_ver.h"
+
+int _des_crypt(char *buf, int len, struct desparams *desp);
+int _des_crypt(char *buf, int len, struct desparams *desp)
+{
+ DES_key_schedule ks;
+ int enc;
+
+ DES_set_key_unchecked(&desp->des_key, &ks);
+ enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT;
+
+ if (desp->des_mode == CBC)
+ DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf,
+ (DES_cblock *)desp->UDES.UDES_buf, &ks, enc);
+ else {
+ DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf,
+ len, &ks, &desp->des_ivec, enc);
+#ifdef undef
+ /*
+ * len will always be %8 if called from common_crypt in secure_rpc.
+ * Libdes's cbc encrypt does not copy back the iv, so we have to do
+ * it here.
+ */
+ /* It does now :-) eay 20/09/95 */
+
+ a = (char *)&(desp->UDES.UDES_buf[len - 8]);
+ b = (char *)&(desp->des_ivec[0]);
+
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+ *(a++) = *(b++);
+#endif
+ }
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/set_key.c b/Cryptlib/OpenSSL/crypto/des/set_key.c
new file mode 100644
index 00000000..8fd8fe14
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/set_key.c
@@ -0,0 +1,447 @@
+/* crypto/des/set_key.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.]
+ */
+
+/*-
+ * set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include <openssl/crypto.h>
+#include "des_locl.h"
+
+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,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
+ 110,
+ 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
+ 127,
+ 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
+ 143,
+ 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
+ 158,
+ 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
+ 174,
+ 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
+ 191,
+ 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
+ 206,
+ 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
+ 223,
+ 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
+ 239,
+ 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
+ 254
+};
+
+void DES_set_odd_parity(DES_cblock *key)
+{
+ unsigned int i;
+
+ for (i = 0; i < DES_KEY_SZ; i++)
+ (*key)[i] = odd_parity[(*key)[i]];
+}
+
+int DES_check_key_parity(const_DES_cblock *key)
+{
+ unsigned int i;
+
+ for (i = 0; i < DES_KEY_SZ; i++) {
+ if ((*key)[i] != odd_parity[(*key)[i]])
+ return (0);
+ }
+ return (1);
+}
+
+/*-
+ * Weak and semi week keys as take from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY 16
+static const DES_cblock weak_keys[NUM_WEAK_KEY] = {
+ /* weak keys */
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+ {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
+ {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
+ {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1},
+ /* semi-weak keys */
+ {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE},
+ {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01},
+ {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1},
+ {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E},
+ {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1},
+ {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01},
+ {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE},
+ {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E},
+ {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E},
+ {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01},
+ {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
+ {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1}
+};
+
+int DES_is_weak_key(const_DES_cblock *key)
+{
+ int i;
+
+ for (i = 0; i < NUM_WEAK_KEY; i++)
+ /*
+ * Added == 0 to comparison, I obviously don't run this section very
+ * often :-(, thanks to engineering@MorningStar.Com for the fix eay
+ * 93/06/29 Another problem, I was comparing only the first 4 bytes,
+ * 97/03/18
+ */
+ if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0)
+ return (1);
+ return (0);
+}
+
+/*-
+ * NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros.
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ * (b)^=(t),\
+ * (a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))
+
+static const DES_LONG des_skb[8][64] = {
+ {
+ /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
+ 0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
+ 0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
+ 0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
+ 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
+ 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
+ 0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
+ 0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
+ 0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
+ 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
+ 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
+ 0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
+ 0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
+ 0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
+ 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
+ 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
+ },
+ {
+ /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+ 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
+ 0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
+ 0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
+ 0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
+ 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
+ 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
+ 0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
+ 0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
+ 0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
+ 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
+ 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
+ 0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
+ 0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
+ 0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
+ 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
+ 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
+ },
+ {
+ /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+ 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
+ 0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
+ 0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
+ 0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
+ 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
+ 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
+ 0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
+ 0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
+ 0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
+ 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
+ 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
+ 0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
+ 0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
+ 0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
+ 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
+ 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
+ },
+ {
+ /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+ 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
+ 0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
+ 0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
+ 0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
+ 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
+ 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
+ 0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
+ 0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
+ 0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
+ 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
+ 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
+ 0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
+ 0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
+ 0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
+ 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
+ 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
+ },
+ {
+ /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
+ 0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
+ 0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
+ 0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
+ 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
+ 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
+ 0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
+ 0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
+ 0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
+ 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
+ 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
+ 0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
+ 0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
+ 0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
+ 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
+ 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
+ },
+ {
+ /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+ 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
+ 0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
+ 0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
+ 0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
+ 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
+ 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
+ 0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
+ 0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
+ 0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
+ 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
+ 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
+ 0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
+ 0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
+ 0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
+ 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
+ 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
+ },
+ {
+ /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+ 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
+ 0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
+ 0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
+ 0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
+ 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
+ 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
+ 0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
+ 0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
+ 0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
+ 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
+ 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
+ 0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
+ 0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
+ 0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
+ 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
+ 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
+ },
+ {
+ /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+ 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
+ 0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
+ 0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
+ 0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
+ 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
+ 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
+ 0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
+ 0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
+ 0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
+ 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
+ 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
+ 0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
+ 0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
+ 0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
+ 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
+ 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
+ }
+};
+
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+ if (DES_check_key) {
+ return DES_set_key_checked(key, schedule);
+ } else {
+ DES_set_key_unchecked(key, schedule);
+ return 0;
+ }
+}
+
+/*-
+ * return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+ if (!DES_check_key_parity(key))
+ return (-1);
+ if (DES_is_weak_key(key))
+ return (-2);
+ DES_set_key_unchecked(key, schedule);
+ return 0;
+}
+
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+#ifdef OPENSSL_FIPS
+{
+ fips_cipher_abort(DES);
+ private_DES_set_key_unchecked(key, schedule);
+}
+
+void private_DES_set_key_unchecked(const_DES_cblock *key,
+ DES_key_schedule *schedule)
+#endif
+{
+ 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;
+ register int i;
+
+#ifdef OPENBSD_DEV_CRYPTO
+ memcpy(schedule->key, key, sizeof schedule->key);
+ schedule->session = NULL;
+#endif
+ k = &schedule->ks->deslong[0];
+ in = &(*key)[0];
+
+ c2l(in, c);
+ c2l(in, d);
+
+ /*
+ * do PC1 in 47 simple operations :-) Thanks to John Fletcher
+ * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-)
+ */
+ PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
+ HPERM_OP(c, t, -2, 0xcccc0000L);
+ HPERM_OP(d, t, -2, 0xcccc0000L);
+ PERM_OP(d, c, t, 1, 0x55555555L);
+ PERM_OP(c, d, t, 8, 0x00ff00ffL);
+ PERM_OP(d, c, t, 1, 0x55555555L);
+ d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
+ ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
+ c &= 0x0fffffffL;
+
+ for (i = 0; i < ITERATIONS; i++) {
+ if (shifts2[i]) {
+ c = ((c >> 2L) | (c << 26L));
+ d = ((d >> 2L) | (d << 26L));
+ } else {
+ c = ((c >> 1L) | (c << 27L));
+ d = ((d >> 1L) | (d << 27L));
+ }
+ c &= 0x0fffffffL;
+ d &= 0x0fffffffL;
+ /*
+ * could be a few less shifts but I am to lazy at this point in time
+ * to investigate
+ */
+ s = des_skb[0][(c) & 0x3f] |
+ des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
+ des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
+ des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
+ ((c >> 22L) & 0x38)];
+ t = des_skb[4][(d) & 0x3f] |
+ des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
+ des_skb[6][(d >> 15L) & 0x3f] |
+ des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
+
+ /* table contained 0213 4657 */
+ t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
+ *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+
+ t2 = ((s >> 16L) | (t & 0xffff0000L));
+ *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+ }
+}
+
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+ return (DES_set_key(key, schedule));
+}
+
+/*-
+#undef des_fixup_key_parity
+void des_fixup_key_parity(des_cblock *key)
+ {
+ des_set_odd_parity(key);
+ }
+*/
diff --git a/Cryptlib/OpenSSL/crypto/des/spr.h b/Cryptlib/OpenSSL/crypto/des/spr.h
new file mode 100644
index 00000000..e85d3100
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/spr.h
@@ -0,0 +1,212 @@
+/* crypto/des/spr.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.]
+ */
+
+OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64] = {
+ {
+ /* nibble 0 */
+ 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+ 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+ 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+ 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+ 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+ 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+ 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+ 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+ 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+ 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+ 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+ 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+ 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+ 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+ 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+ 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+ },
+ {
+ /* nibble 1 */
+ 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+ 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+ 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+ 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+ 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+ 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+ 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+ 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+ 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+ 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+ 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+ 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+ 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+ 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+ 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+ 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+ },
+ {
+ /* nibble 2 */
+ 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+ 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+ 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+ 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+ 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+ 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+ 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+ 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+ 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+ 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+ 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+ 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+ 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+ 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+ 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+ 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+ },
+ {
+ /* nibble 3 */
+ 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+ 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+ 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+ 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+ 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+ 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+ 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+ 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+ 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+ 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+ 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+ 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+ 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+ 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+ 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+ 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+ },
+ {
+ /* nibble 4 */
+ 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+ 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+ 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+ 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+ 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+ 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+ 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+ 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+ 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+ 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+ 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+ 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+ 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+ 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+ 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+ 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+ },
+ {
+ /* nibble 5 */
+ 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+ 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+ 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+ 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+ 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+ 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+ 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+ 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+ 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+ 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+ 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+ 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+ 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+ 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+ 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+ 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+ },
+ {
+ /* nibble 6 */
+ 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+ 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+ 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+ 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+ 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+ 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+ 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+ 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+ 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+ 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+ 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+ 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+ 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+ 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+ 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+ 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+ },
+ {
+ /* nibble 7 */
+ 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+ 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+ 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+ 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+ 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+ 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+ 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+ 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+ 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+ 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+ 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+ 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+ 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+ 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+ 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+ 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+ }
+};
diff --git a/Cryptlib/OpenSSL/crypto/des/str2key.c b/Cryptlib/OpenSSL/crypto/des/str2key.c
new file mode 100644
index 00000000..38a478cf
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/str2key.c
@@ -0,0 +1,164 @@
+/* crypto/des/str2key.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 <openssl/crypto.h>
+#include "des_locl.h"
+
+void DES_string_to_key(const char *str, DES_cblock *key)
+{
+ DES_key_schedule ks;
+ int i, length;
+ register unsigned char j;
+
+ memset(key, 0, 8);
+ length = strlen(str);
+#ifdef OLD_STR_TO_KEY
+ for (i = 0; i < length; i++)
+ (*key)[i % 8] ^= (str[i] << 1);
+#else /* MIT COMPATIBLE */
+ for (i = 0; i < length; i++) {
+ j = str[i];
+ if ((i % 16) < 8)
+ (*key)[i % 8] ^= (j << 1);
+ else {
+ /* Reverse the bit order 05/05/92 eay */
+ j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);
+ j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);
+ j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);
+ (*key)[7 - (i % 8)] ^= j;
+ }
+ }
+#endif
+ DES_set_odd_parity(key);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+ if (DES_is_weak_key(key))
+ (*key)[7] ^= 0xF0;
+ DES_set_key(key, &ks);
+#else
+ DES_set_key_unchecked(key, &ks);
+#endif
+ DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key);
+ OPENSSL_cleanse(&ks, sizeof(ks));
+ DES_set_odd_parity(key);
+}
+
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2)
+{
+ DES_key_schedule ks;
+ int i, length;
+ register unsigned char j;
+
+ memset(key1, 0, 8);
+ memset(key2, 0, 8);
+ length = strlen(str);
+#ifdef OLD_STR_TO_KEY
+ if (length <= 8) {
+ for (i = 0; i < length; i++) {
+ (*key2)[i] = (*key1)[i] = (str[i] << 1);
+ }
+ } else {
+ for (i = 0; i < length; i++) {
+ if ((i / 8) & 1)
+ (*key2)[i % 8] ^= (str[i] << 1);
+ else
+ (*key1)[i % 8] ^= (str[i] << 1);
+ }
+ }
+#else /* MIT COMPATIBLE */
+ for (i = 0; i < length; i++) {
+ j = str[i];
+ if ((i % 32) < 16) {
+ if ((i % 16) < 8)
+ (*key1)[i % 8] ^= (j << 1);
+ else
+ (*key2)[i % 8] ^= (j << 1);
+ } else {
+ j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);
+ j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);
+ j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);
+ if ((i % 16) < 8)
+ (*key1)[7 - (i % 8)] ^= j;
+ else
+ (*key2)[7 - (i % 8)] ^= j;
+ }
+ }
+ if (length <= 8)
+ memcpy(key2, key1, 8);
+#endif
+ DES_set_odd_parity(key1);
+ DES_set_odd_parity(key2);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+ if (DES_is_weak_key(key1))
+ (*key1)[7] ^= 0xF0;
+ DES_set_key(key1, &ks);
+#else
+ DES_set_key_unchecked(key1, &ks);
+#endif
+ DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+ if (DES_is_weak_key(key2))
+ (*key2)[7] ^= 0xF0;
+ DES_set_key(key2, &ks);
+#else
+ DES_set_key_unchecked(key2, &ks);
+#endif
+ DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2);
+ OPENSSL_cleanse(&ks, sizeof(ks));
+ DES_set_odd_parity(key1);
+ DES_set_odd_parity(key2);
+}
diff --git a/Cryptlib/OpenSSL/crypto/des/xcbc_enc.c b/Cryptlib/OpenSSL/crypto/des/xcbc_enc.c
new file mode 100644
index 00000000..6fe021be
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/des/xcbc_enc.c
@@ -0,0 +1,216 @@
+/* crypto/des/xcbc_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"
+
+/* RSA's DESX */
+
+#if 0 /* broken code, preserved just in case anyone
+ * specifically looks for this */
+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,
+ 0x3E, 0xEE, 0xFB, 0x95, 0x1A, 0xFE, 0xCE, 0xA8, 0x34, 0xA9, 0x13, 0xF0,
+ 0xA6, 0x3F, 0xD8, 0x0C,
+ 0x78, 0x24, 0xAF, 0x23, 0x52, 0xC1, 0x67, 0x17, 0xF5, 0x66, 0x90, 0xE7,
+ 0xE8, 0x07, 0xB8, 0x60,
+ 0x48, 0xE6, 0x1E, 0x53, 0xF3, 0x92, 0xA4, 0x72, 0x8C, 0x08, 0x15, 0x6E,
+ 0x86, 0x00, 0x84, 0xFA,
+ 0xF4, 0x7F, 0x8A, 0x42, 0x19, 0xF6, 0xDB, 0xCD, 0x14, 0x8D, 0x50, 0x12,
+ 0xBA, 0x3C, 0x06, 0x4E,
+ 0xEC, 0xB3, 0x35, 0x11, 0xA1, 0x88, 0x8E, 0x2B, 0x94, 0x99, 0xB7, 0x71,
+ 0x74, 0xD3, 0xE4, 0xBF,
+ 0x3A, 0xDE, 0x96, 0x0E, 0xBC, 0x0A, 0xED, 0x77, 0xFC, 0x37, 0x6B, 0x03,
+ 0x79, 0x89, 0x62, 0xC6,
+ 0xD7, 0xC0, 0xD2, 0x7C, 0x6A, 0x8B, 0x22, 0xA3, 0x5B, 0x05, 0x5D, 0x02,
+ 0x75, 0xD5, 0x61, 0xE3,
+ 0x18, 0x8F, 0x55, 0x51, 0xAD, 0x1F, 0x0B, 0x5E, 0x85, 0xE5, 0xC2, 0x57,
+ 0x63, 0xCA, 0x3D, 0x6C,
+ 0xB4, 0xC5, 0xCC, 0x70, 0xB2, 0x91, 0x59, 0x0D, 0x47, 0x20, 0xC8, 0x4F,
+ 0x58, 0xE0, 0x01, 0xE2,
+ 0x16, 0x38, 0xC4, 0x6F, 0x3B, 0x0F, 0x65, 0x46, 0xBE, 0x7E, 0x2D, 0x7B,
+ 0x82, 0xF9, 0x40, 0xB5,
+ 0x1D, 0x73, 0xF8, 0xEB, 0x26, 0xC7, 0x87, 0x97, 0x25, 0x54, 0xB1, 0x28,
+ 0xAA, 0x98, 0x9D, 0xA5,
+ 0x64, 0x6D, 0x7A, 0xD4, 0x10, 0x81, 0x44, 0xEF, 0x49, 0xD6, 0xAE, 0x2E,
+ 0xDD, 0x76, 0x5C, 0x2F,
+ 0xA7, 0x1C, 0xC9, 0x09, 0x69, 0x9A, 0x83, 0xCF, 0x29, 0x39, 0xB9, 0xE9,
+ 0x4C, 0xFF, 0x43, 0xAB,
+};
+
+void DES_xwhite_in2out(const_DES_cblock *des_key, const_DES_cblock *in_white,
+ DES_cblock *out_white)
+{
+ int out0, out1;
+ int i;
+ const unsigned char *key = &(*des_key)[0];
+ const unsigned char *in = &(*in_white)[0];
+ unsigned char *out = &(*out_white)[0];
+
+ out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0;
+ out0 = out1 = 0;
+ for (i = 0; i < 8; i++) {
+ out[i] = key[i] ^ desx_white_in2out[out0 ^ out1];
+ out0 = out1;
+ out1 = (int)out[i & 0x07];
+ }
+
+ out0 = out[0];
+ out1 = out[i]; /* BUG: out-of-bounds read */
+ for (i = 0; i < 8; i++) {
+ out[i] = in[i] ^ desx_white_in2out[out0 ^ out1];
+ out0 = out1;
+ out1 = (int)out[i & 0x07];
+ }
+}
+#endif
+
+void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
+ long length, DES_key_schedule *schedule,
+ DES_cblock *ivec, const_DES_cblock *inw,
+ const_DES_cblock *outw, int enc)
+{
+ register DES_LONG tin0, tin1;
+ register DES_LONG tout0, tout1, xor0, xor1;
+ register DES_LONG inW0, inW1, outW0, outW1;
+ register const unsigned char *in2;
+ register long l = length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in2 = &(*inw)[0];
+ c2l(in2, inW0);
+ c2l(in2, inW1);
+ in2 = &(*outw)[0];
+ c2l(in2, outW0);
+ c2l(in2, outW1);
+
+ iv = &(*ivec)[0];
+
+ if (enc) {
+ c2l(iv, tout0);
+ c2l(iv, tout1);
+ for (l -= 8; l >= 0; l -= 8) {
+ c2l(in, tin0);
+ c2l(in, tin1);
+ tin0 ^= tout0 ^ inW0;
+ tin[0] = tin0;
+ tin1 ^= tout1 ^ inW1;
+ tin[1] = tin1;
+ DES_encrypt1(tin, schedule, DES_ENCRYPT);
+ tout0 = tin[0] ^ outW0;
+ l2c(tout0, out);
+ tout1 = tin[1] ^ outW1;
+ l2c(tout1, out);
+ }
+ if (l != -8) {
+ c2ln(in, tin0, tin1, l + 8);
+ tin0 ^= tout0 ^ inW0;
+ tin[0] = tin0;
+ tin1 ^= tout1 ^ inW1;
+ tin[1] = tin1;
+ DES_encrypt1(tin, schedule, DES_ENCRYPT);
+ tout0 = tin[0] ^ outW0;
+ l2c(tout0, out);
+ tout1 = tin[1] ^ outW1;
+ l2c(tout1, out);
+ }
+ iv = &(*ivec)[0];
+ l2c(tout0, iv);
+ l2c(tout1, iv);
+ } else {
+ c2l(iv, xor0);
+ c2l(iv, xor1);
+ for (l -= 8; l > 0; l -= 8) {
+ c2l(in, tin0);
+ tin[0] = tin0 ^ outW0;
+ c2l(in, tin1);
+ tin[1] = tin1 ^ outW1;
+ DES_encrypt1(tin, schedule, DES_DECRYPT);
+ tout0 = tin[0] ^ xor0 ^ inW0;
+ tout1 = tin[1] ^ xor1 ^ inW1;
+ l2c(tout0, out);
+ l2c(tout1, out);
+ xor0 = tin0;
+ xor1 = tin1;
+ }
+ if (l != -8) {
+ c2l(in, tin0);
+ tin[0] = tin0 ^ outW0;
+ c2l(in, tin1);
+ tin[1] = tin1 ^ outW1;
+ DES_encrypt1(tin, schedule, DES_DECRYPT);
+ tout0 = tin[0] ^ xor0 ^ inW0;
+ tout1 = tin[1] ^ xor1 ^ inW1;
+ l2cn(tout0, tout1, out, l + 8);
+ xor0 = tin0;
+ xor1 = tin1;
+ }
+
+ iv = &(*ivec)[0];
+ l2c(xor0, iv);
+ l2c(xor1, iv);
+ }
+ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+ inW0 = inW1 = outW0 = outW1 = 0;
+ tin[0] = tin[1] = 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_ameth.c b/Cryptlib/OpenSSL/crypto/dh/dh_ameth.c
new file mode 100644
index 00000000..ac72468b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_ameth.c
@@ -0,0 +1,957 @@
+/*
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include "asn1_locl.h"
+#ifndef OPENSSL_NO_CMS
+# include <openssl/cms.h>
+#endif
+
+extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
+
+/*
+ * i2d/d2i like DH parameter functions which use the appropriate routine for
+ * PKCS#3 DH or X9.42 DH.
+ */
+
+static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp,
+ long length)
+{
+ if (pkey->ameth == &dhx_asn1_meth)
+ return d2i_DHxparams(NULL, pp, length);
+ return d2i_DHparams(NULL, pp, length);
+}
+
+static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
+{
+ if (pkey->ameth == &dhx_asn1_meth)
+ return i2d_DHxparams(a, pp);
+ return i2d_DHparams(a, pp);
+}
+
+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_dhp(pkey, &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(pkey, pkey->ameth->pkey_id, 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;
+ int ptype;
+ unsigned char *penc = NULL;
+ int penclen;
+ ASN1_STRING *str;
+ ASN1_INTEGER *pub_key = NULL;
+
+ dh = pkey->pkey.dh;
+
+ str = ASN1_STRING_new();
+ if (!str) {
+ DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ str->length = i2d_dhp(pkey, dh, &str->data);
+ if (str->length <= 0) {
+ DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ 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(pkey->ameth->pkey_id),
+ ptype, str, penc, penclen))
+ return 1;
+
+ err:
+ if (penc)
+ OPENSSL_free(penc);
+ if (str)
+ ASN1_STRING_free(str);
+
+ 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_dhp(pkey, &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(pkey, pkey->ameth->pkey_id, dh);
+
+ ASN1_STRING_clear_free(privkey);
+
+ return 1;
+
+ decerr:
+ DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+ dherr:
+ DH_free(dh);
+ ASN1_STRING_clear_free(privkey);
+ 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_dhp(pkey, pkey->pkey.dh, &params->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_STRING_clear_free(prkey);
+ prkey = NULL;
+
+ if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 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_STRING_clear_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_dhp(pkey, pder, derlen))) {
+ DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+ return 1;
+}
+
+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+ return i2d_dhp(pkey, 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(x->q, &buf_len);
+ update_buflen(x->j, &buf_len);
+ update_buflen(x->counter, &buf_len);
+ update_buflen(pub_key, &buf_len);
+ update_buflen(priv_key, &buf_len);
+
+ if (ptype == 2)
+ ktype = "DH Private-Key";
+ else if (ptype == 1)
+ ktype = "DH Public-Key";
+ else
+ ktype = "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->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent))
+ goto err;
+ if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent))
+ goto err;
+ if (x->seed) {
+ int i;
+ BIO_indent(bp, indent, 128);
+ BIO_puts(bp, "seed:");
+ for (i = 0; i < x->seedlen; i++) {
+ if ((i % 15) == 0) {
+ if (BIO_puts(bp, "\n") <= 0
+ || !BIO_indent(bp, indent + 4, 128))
+ goto err;
+ }
+ if (BIO_printf(bp, "%02x%s", x->seed[i],
+ ((i + 1) == x->seedlen) ? "" : ":") <= 0)
+ goto err;
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return (0);
+ }
+ if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, 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 if (a->ameth == &dhx_asn1_meth) {
+ if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q))
+ return 0;
+ }
+ return 1;
+}
+
+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
+{
+ BIGNUM *a;
+ if (src) {
+ a = BN_dup(src);
+ if (!a)
+ return 0;
+ } else
+ a = NULL;
+ if (*dst)
+ BN_free(*dst);
+ *dst = a;
+ return 1;
+}
+
+static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
+{
+ if (is_x942 == -1)
+ is_x942 = ! !from->q;
+ if (!int_dh_bn_cpy(&to->p, from->p))
+ return 0;
+ if (!int_dh_bn_cpy(&to->g, from->g))
+ return 0;
+ if (is_x942) {
+ if (!int_dh_bn_cpy(&to->q, from->q))
+ return 0;
+ if (!int_dh_bn_cpy(&to->j, from->j))
+ return 0;
+ if (to->seed) {
+ OPENSSL_free(to->seed);
+ to->seed = NULL;
+ to->seedlen = 0;
+ }
+ if (from->seed) {
+ to->seed = BUF_memdup(from->seed, from->seedlen);
+ if (!to->seed)
+ return 0;
+ to->seedlen = from->seedlen;
+ }
+ } else
+ to->length = from->length;
+ return 1;
+}
+
+DH *DHparams_dup(DH *dh)
+{
+ DH *ret;
+ ret = DH_new();
+ if (!ret)
+ return NULL;
+ if (!int_dh_param_copy(ret, dh, -1)) {
+ DH_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+ return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
+ from->ameth == &dhx_asn1_meth);
+}
+
+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);
+}
+
+#ifndef OPENSSL_NO_CMS
+static int dh_cms_decrypt(CMS_RecipientInfo *ri);
+static int dh_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+ switch (op) {
+#ifndef OPENSSL_NO_CMS
+
+ case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+ if (arg1 == 1)
+ return dh_cms_decrypt(arg2);
+ else if (arg1 == 0)
+ return dh_cms_encrypt(arg2);
+ return -2;
+
+ case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+ *(int *)arg2 = CMS_RECIPINFO_AGREE;
+ return 1;
+#endif
+ default:
+ return -2;
+ }
+
+}
+
+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,
+ 0,
+
+ int_dh_free,
+ 0
+};
+
+const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
+ EVP_PKEY_DHX,
+ EVP_PKEY_DHX,
+ 0,
+
+ "X9.42 DH",
+ "OpenSSL X9.42 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,
+ 0,
+
+ int_dh_free,
+ dh_pkey_ctrl
+};
+
+#ifndef OPENSSL_NO_CMS
+
+static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+ X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+ ASN1_OBJECT *aoid;
+ int atype;
+ void *aval;
+ ASN1_INTEGER *public_key = NULL;
+ int rv = 0;
+ EVP_PKEY *pkpeer = NULL, *pk = NULL;
+ DH *dhpeer = NULL;
+ const unsigned char *p;
+ int plen;
+
+ X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+ if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
+ goto err;
+ /* Only absent parameters allowed in RFC XXXX */
+ if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
+ goto err;
+
+ pk = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (!pk)
+ goto err;
+ if (pk->type != EVP_PKEY_DHX)
+ goto err;
+ /* Get parameters from parent key */
+ dhpeer = DHparams_dup(pk->pkey.dh);
+ /* We have parameters now set public key */
+ plen = ASN1_STRING_length(pubkey);
+ p = ASN1_STRING_data(pubkey);
+ if (!p || !plen)
+ goto err;
+
+ if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) {
+ DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* We have parameters now set public key */
+ if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
+ DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
+ goto err;
+ }
+
+ pkpeer = EVP_PKEY_new();
+ if (!pkpeer)
+ goto err;
+ EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
+ dhpeer = NULL;
+ if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+ rv = 1;
+ err:
+ if (public_key)
+ ASN1_INTEGER_free(public_key);
+ if (pkpeer)
+ EVP_PKEY_free(pkpeer);
+ if (dhpeer)
+ DH_free(dhpeer);
+ return rv;
+}
+
+static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+ int rv = 0;
+
+ X509_ALGOR *alg, *kekalg = NULL;
+ ASN1_OCTET_STRING *ukm;
+ const unsigned char *p;
+ unsigned char *dukm = NULL;
+ size_t dukmlen = 0;
+ int keylen, plen;
+ const EVP_CIPHER *kekcipher;
+ EVP_CIPHER_CTX *kekctx;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+ goto err;
+
+ /*
+ * For DH we only have one OID permissible. If ever any more get defined
+ * we will need something cleverer.
+ */
+ if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
+ DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
+ goto err;
+
+ if (alg->parameter->type != V_ASN1_SEQUENCE)
+ goto err;
+
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+ if (!kekalg)
+ goto err;
+ kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ if (!kekctx)
+ goto err;
+ kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+ if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+ goto err;
+ if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+ goto err;
+
+ keylen = EVP_CIPHER_CTX_key_length(kekctx);
+ if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+ /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
+ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
+ OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
+ <= 0)
+ goto err;
+
+ if (ukm) {
+ dukmlen = ASN1_STRING_length(ukm);
+ dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
+ if (!dukm)
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+ goto err;
+ dukm = NULL;
+
+ rv = 1;
+ err:
+ if (kekalg)
+ X509_ALGOR_free(kekalg);
+ if (dukm)
+ OPENSSL_free(dukm);
+ return rv;
+}
+
+static int dh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (!pctx)
+ return 0;
+ /* See if we need to set peer key */
+ if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+ X509_ALGOR *alg;
+ ASN1_BIT_STRING *pubkey;
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+ NULL, NULL, NULL))
+ return 0;
+ if (!alg || !pubkey)
+ return 0;
+ if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
+ DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
+ return 0;
+ }
+ }
+ /* Set DH derivation parameters and initialise unwrap context */
+ if (!dh_cms_set_shared_info(pctx, ri)) {
+ DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+static int dh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ EVP_PKEY *pkey;
+ EVP_CIPHER_CTX *ctx;
+ int keylen;
+ X509_ALGOR *talg, *wrap_alg = NULL;
+ ASN1_OBJECT *aoid;
+ ASN1_BIT_STRING *pubkey;
+ ASN1_STRING *wrap_str;
+ ASN1_OCTET_STRING *ukm;
+ unsigned char *penc = NULL, *dukm = NULL;
+ int penclen;
+ size_t dukmlen = 0;
+ int rv = 0;
+ int kdf_type, wrap_nid;
+ const EVP_MD *kdf_md;
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (!pctx)
+ return 0;
+ /* Get ephemeral key */
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+ NULL, NULL, NULL))
+ goto err;
+ X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+ /* Is everything uninitialised? */
+ if (aoid == OBJ_nid2obj(NID_undef)) {
+ ASN1_INTEGER *pubk;
+ pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
+ if (!pubk)
+ goto err;
+ /* Set the key */
+
+ penclen = i2d_ASN1_INTEGER(pubk, &penc);
+ ASN1_INTEGER_free(pubk);
+ if (penclen <= 0)
+ goto err;
+ ASN1_STRING_set0(pubkey, penc, penclen);
+ pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
+ V_ASN1_UNDEF, NULL);
+ }
+
+ /* See if custom paraneters set */
+ kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
+ if (kdf_type <= 0)
+ goto err;
+ if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
+ goto err;
+
+ if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
+ kdf_type = EVP_PKEY_DH_KDF_X9_42;
+ if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
+ goto err;
+ } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
+ /* Unknown KDF */
+ goto err;
+ if (kdf_md == NULL) {
+ /* Only SHA1 supported */
+ kdf_md = EVP_sha1();
+ if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
+ goto err;
+ } else if (EVP_MD_type(kdf_md) != NID_sha1)
+ /* Unsupported digest */
+ goto err;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+ goto err;
+
+ /* Get wrap NID */
+ ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ wrap_nid = EVP_CIPHER_CTX_type(ctx);
+ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
+ goto err;
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+ /* Package wrap algorithm in an AlgorithmIdentifier */
+
+ wrap_alg = X509_ALGOR_new();
+ if (!wrap_alg)
+ goto err;
+ wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+ wrap_alg->parameter = ASN1_TYPE_new();
+ if (!wrap_alg->parameter)
+ goto err;
+ if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+ goto err;
+ if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+ ASN1_TYPE_free(wrap_alg->parameter);
+ wrap_alg->parameter = NULL;
+ }
+
+ if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+
+ if (ukm) {
+ dukmlen = ASN1_STRING_length(ukm);
+ dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
+ if (!dukm)
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+ goto err;
+ dukm = NULL;
+
+ /*
+ * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+ * of another AlgorithmIdentifier.
+ */
+ penc = NULL;
+ penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+ if (!penc || !penclen)
+ goto err;
+ wrap_str = ASN1_STRING_new();
+ if (!wrap_str)
+ goto err;
+ ASN1_STRING_set0(wrap_str, penc, penclen);
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
+ V_ASN1_SEQUENCE, wrap_str);
+
+ rv = 1;
+
+ err:
+ if (penc)
+ OPENSSL_free(penc);
+ if (wrap_alg)
+ X509_ALGOR_free(wrap_alg);
+ return rv;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_asn1.c b/Cryptlib/OpenSSL/crypto/dh/dh_asn1.c
new file mode 100644
index 00000000..f4702143
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_asn1.c
@@ -0,0 +1,189 @@
+/* dh_asn1.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+
+/* Override the default free and new methods */
+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();
+ if (*pval)
+ return 2;
+ return 0;
+ } else if (operation == ASN1_OP_FREE_PRE) {
+ DH_free((DH *)*pval);
+ *pval = NULL;
+ return 2;
+ }
+ return 1;
+}
+
+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)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
+
+/*
+ * Internal only structures for handling X9.42 DH: this gets translated to or
+ * from a DH structure straight away.
+ */
+
+typedef struct {
+ ASN1_BIT_STRING *seed;
+ BIGNUM *counter;
+} int_dhvparams;
+
+typedef struct {
+ BIGNUM *p;
+ BIGNUM *q;
+ BIGNUM *g;
+ BIGNUM *j;
+ int_dhvparams *vparams;
+} int_dhx942_dh;
+
+ASN1_SEQUENCE(DHvparams) = {
+ ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
+ ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
+} ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
+
+ASN1_SEQUENCE(DHxparams) = {
+ ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
+ ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
+ ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM),
+ ASN1_OPT(int_dhx942_dh, j, BIGNUM),
+ ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
+} ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
+
+int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a,
+ const unsigned char **pp, long length);
+int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp);
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx)
+
+/* Application leve function: read in X9.42 DH parameters into DH structure */
+
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
+{
+ int_dhx942_dh *dhx = NULL;
+ DH *dh = NULL;
+ dh = DH_new();
+ if (!dh)
+ return NULL;
+ dhx = d2i_int_dhx(NULL, pp, length);
+ if (!dhx) {
+ DH_free(dh);
+ return NULL;
+ }
+
+ if (a) {
+ if (*a)
+ DH_free(*a);
+ *a = dh;
+ }
+
+ dh->p = dhx->p;
+ dh->q = dhx->q;
+ dh->g = dhx->g;
+ dh->j = dhx->j;
+
+ if (dhx->vparams) {
+ dh->seed = dhx->vparams->seed->data;
+ dh->seedlen = dhx->vparams->seed->length;
+ dh->counter = dhx->vparams->counter;
+ dhx->vparams->seed->data = NULL;
+ ASN1_BIT_STRING_free(dhx->vparams->seed);
+ OPENSSL_free(dhx->vparams);
+ dhx->vparams = NULL;
+ }
+
+ OPENSSL_free(dhx);
+ return dh;
+}
+
+int i2d_DHxparams(const DH *dh, unsigned char **pp)
+{
+ int_dhx942_dh dhx;
+ int_dhvparams dhv;
+ ASN1_BIT_STRING bs;
+ dhx.p = dh->p;
+ dhx.g = dh->g;
+ dhx.q = dh->q;
+ dhx.j = dh->j;
+ if (dh->counter && dh->seed && dh->seedlen > 0) {
+ bs.flags = ASN1_STRING_FLAG_BITS_LEFT;
+ bs.data = dh->seed;
+ bs.length = dh->seedlen;
+ dhv.seed = &bs;
+ dhv.counter = dh->counter;
+ dhx.vparams = &dhv;
+ } else
+ dhx.vparams = NULL;
+
+ return i2d_int_dhx(&dhx, pp);
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_check.c b/Cryptlib/OpenSSL/crypto/dh/dh_check.c
new file mode 100644
index 00000000..02770411
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_check.c
@@ -0,0 +1,187 @@
+/* crypto/dh/dh_check.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+/*-
+ * Check that p is a safe prime and
+ * if g is 2, 3 or 5, check that it is a suitable generator
+ * where
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5
+ * for 5, p mod 10 == 3 or 7
+ * should hold.
+ */
+
+int DH_check(const DH *dh, int *ret)
+{
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ BN_ULONG l;
+ BIGNUM *t1 = NULL, *t2 = NULL;
+
+ *ret = 0;
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ if (t1 == NULL)
+ goto err;
+ t2 = BN_CTX_get(ctx);
+ if (t2 == NULL)
+ goto err;
+
+ if (dh->q) {
+ if (BN_cmp(dh->g, BN_value_one()) <= 0)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ else if (BN_cmp(dh->g, dh->p) >= 0)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ else {
+ /* Check g^q == 1 mod p */
+ if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
+ goto err;
+ if (!BN_is_one(t1))
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ }
+ if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL))
+ *ret |= DH_CHECK_Q_NOT_PRIME;
+ /* Check p == 1 mod q i.e. q divides p - 1 */
+ if (!BN_div(t1, t2, dh->p, dh->q, ctx))
+ goto err;
+ if (!BN_is_one(t2))
+ *ret |= DH_CHECK_INVALID_Q_VALUE;
+ if (dh->j && BN_cmp(dh->j, t1))
+ *ret |= DH_CHECK_INVALID_J_VALUE;
+
+ } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
+ l = BN_mod_word(dh->p, 24);
+ if (l != 11)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ }
+#if 0
+ else if (BN_is_word(dh->g, DH_GENERATOR_3)) {
+ l = BN_mod_word(dh->p, 12);
+ if (l != 5)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ }
+#endif
+ else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
+ l = BN_mod_word(dh->p, 10);
+ if ((l != 3) && (l != 7))
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ } else
+ *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
+
+ if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
+ *ret |= DH_CHECK_P_NOT_PRIME;
+ else if (!dh->q) {
+ if (!BN_rshift1(t1, dh->p))
+ goto err;
+ if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL))
+ *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
+ }
+ ok = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ok);
+}
+
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+{
+ int ok = 0;
+ BIGNUM *tmp = NULL;
+ BN_CTX *ctx = NULL;
+
+ *ret = 0;
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL || !BN_set_word(tmp, 1))
+ goto err;
+ if (BN_cmp(pub_key, tmp) <= 0)
+ *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
+ if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+ goto err;
+ if (BN_cmp(pub_key, tmp) >= 0)
+ *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
+
+ if (dh->q != NULL) {
+ /* Check pub_key^q == 1 mod p */
+ if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
+ goto err;
+ if (!BN_is_one(tmp))
+ *ret |= DH_CHECK_PUBKEY_INVALID;
+ }
+
+ ok = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ok);
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_depr.c b/Cryptlib/OpenSSL/crypto/dh/dh_depr.c
new file mode 100644
index 00000000..b6221199
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_depr.c
@@ -0,0 +1,82 @@
+/* crypto/dh/dh_depr.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* This file contains deprecated functions as wrappers to the new ones */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+static void *dummy = &dummy;
+
+#ifndef OPENSSL_NO_DEPRECATED
+DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback) (int, int, void *), void *cb_arg)
+{
+ BN_GENCB cb;
+ DH *ret = NULL;
+
+ if ((ret = DH_new()) == NULL)
+ return NULL;
+
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+
+ if (DH_generate_parameters_ex(ret, prime_len, generator, &cb))
+ return ret;
+ DH_free(ret);
+ return NULL;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_err.c b/Cryptlib/OpenSSL/crypto/dh/dh_err.c
new file mode 100644
index 00000000..b890cca8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_err.c
@@ -0,0 +1,126 @@
+/* crypto/dh/dh_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2013 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
+
+static ERR_STRING_DATA DH_str_functs[] = {
+ {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"},
+ {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_CMS_DECRYPT), "DH_CMS_DECRYPT"},
+ {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "DH_CMS_SET_PEERKEY"},
+ {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "DH_CMS_SET_SHARED_INFO"},
+ {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_EX), "DH_generate_parameters_ex"},
+ {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_KDF_PARAMETER_ERROR), "kdf parameter error"},
+ {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"},
+ {ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL), "key size too small"},
+ {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"},
+ {ERR_REASON(DH_R_NON_FIPS_METHOD), "non fips method"},
+ {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"},
+ {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"},
+ {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_DH_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(DH_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, DH_str_functs);
+ ERR_load_strings(0, DH_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_gen.c b/Cryptlib/OpenSSL/crypto/dh/dh_gen.c
new file mode 100644
index 00000000..5bedb665
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_gen.c
@@ -0,0 +1,204 @@
+/* crypto/dh/dh_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.]
+ */
+
+/*
+ * NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones. - Geoff
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+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)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(ret->flags & DH_FLAG_NON_FIPS_ALLOW)) {
+ DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
+ if (ret->meth->generate_params)
+ return ret->meth->generate_params(ret, prime_len, generator, cb);
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb);
+#endif
+ return dh_builtin_genparams(ret, prime_len, generator, cb);
+}
+
+/*-
+ * We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/*
+ * Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
+ BN_GENCB *cb)
+{
+ BIGNUM *t1, *t2;
+ int g, ok = -1;
+ BN_CTX *ctx = NULL;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL)
+ goto err;
+
+ /* Make sure 'ret' has the necessary elements */
+ if (!ret->p && ((ret->p = BN_new()) == NULL))
+ goto err;
+ if (!ret->g && ((ret->g = BN_new()) == NULL))
+ goto err;
+
+ if (generator <= 1) {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+ goto err;
+ }
+ if (generator == DH_GENERATOR_2) {
+ if (!BN_set_word(t1, 24))
+ goto err;
+ if (!BN_set_word(t2, 11))
+ goto err;
+ g = 2;
+ }
+#if 0 /* does not work for safe primes */
+ else if (generator == DH_GENERATOR_3) {
+ if (!BN_set_word(t1, 12))
+ goto err;
+ if (!BN_set_word(t2, 5))
+ goto err;
+ g = 3;
+ }
+#endif
+ else if (generator == DH_GENERATOR_5) {
+ if (!BN_set_word(t1, 10))
+ goto err;
+ if (!BN_set_word(t2, 3))
+ goto err;
+ /*
+ * BN_set_word(t3,7); just have to miss out on these ones :-(
+ */
+ g = 5;
+ } else {
+ /*
+ * in the general case, don't worry if 'generator' is a generator or
+ * not: since we are using safe primes, it will generate either an
+ * order-q or an order-2q group, which both is OK
+ */
+ if (!BN_set_word(t1, 2))
+ goto err;
+ if (!BN_set_word(t2, 1))
+ goto err;
+ g = generator;
+ }
+
+ if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb))
+ goto err;
+ if (!BN_GENCB_call(cb, 3, 0))
+ goto err;
+ if (!BN_set_word(ret->g, g))
+ goto err;
+ ok = 1;
+ err:
+ if (ok == -1) {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB);
+ ok = 0;
+ }
+
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_key.c b/Cryptlib/OpenSSL/crypto/dh/dh_key.c
new file mode 100644
index 00000000..1d80fb2c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_key.c
@@ -0,0 +1,289 @@
+/* crypto/dh/dh_key.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/dh.h>
+
+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,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int dh_init(DH *dh);
+static int dh_finish(DH *dh);
+
+int DH_generate_key(DH *dh)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) {
+ DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
+ return dh->meth->generate_key(dh);
+}
+
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) {
+ DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
+ return dh->meth->compute_key(key, pub_key, dh);
+}
+
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+ int rv, pad;
+ rv = dh->meth->compute_key(key, pub_key, dh);
+ if (rv <= 0)
+ return rv;
+ pad = BN_num_bytes(dh->p) - rv;
+ if (pad > 0) {
+ memmove(key + pad, key, rv);
+ memset(key, 0, pad);
+ }
+ return rv + pad;
+}
+
+static DH_METHOD dh_ossl = {
+ "OpenSSL DH Method",
+ generate_key,
+ compute_key,
+ dh_bn_mod_exp,
+ dh_init,
+ dh_finish,
+ 0,
+ NULL,
+ NULL
+};
+
+const DH_METHOD *DH_OpenSSL(void)
+{
+ return &dh_ossl;
+}
+
+static int generate_key(DH *dh)
+{
+ int ok = 0;
+ int generate_new_key = 0;
+ unsigned l;
+ BN_CTX *ctx;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+
+ if (dh->priv_key == NULL) {
+ priv_key = BN_new();
+ if (priv_key == NULL)
+ goto err;
+ generate_new_key = 1;
+ } else
+ priv_key = dh->priv_key;
+
+ if (dh->pub_key == NULL) {
+ pub_key = BN_new();
+ if (pub_key == NULL)
+ goto err;
+ } else
+ pub_key = dh->pub_key;
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+ mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont)
+ goto err;
+ }
+
+ if (generate_new_key) {
+ if (dh->q) {
+ do {
+ if (!BN_rand_range(priv_key, dh->q))
+ goto err;
+ }
+ while (BN_is_zero(priv_key) || BN_is_one(priv_key));
+ } else {
+ /* secret exponent length */
+ l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
+ if (!BN_rand(priv_key, l, 0, 0))
+ goto err;
+ }
+ }
+
+ {
+ BIGNUM local_prk;
+ BIGNUM *prk;
+
+ if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
+ BN_init(&local_prk);
+ prk = &local_prk;
+ BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+ } else
+ prk = priv_key;
+
+ if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
+ goto err;
+ }
+
+ dh->pub_key = pub_key;
+ dh->priv_key = priv_key;
+ ok = 1;
+ err:
+ if (ok != 1)
+ DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
+
+ if ((pub_key != NULL) && (dh->pub_key == NULL))
+ BN_free(pub_key);
+ if ((priv_key != NULL) && (dh->priv_key == NULL))
+ BN_free(priv_key);
+ BN_CTX_free(ctx);
+ return (ok);
+}
+
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+ BN_CTX *ctx = NULL;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *tmp;
+ int ret = -1;
+ int check_result;
+
+ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+
+ if (dh->priv_key == NULL) {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+ mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
+ /* XXX */
+ BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
+ }
+ if (!mont)
+ goto err;
+ }
+
+ if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
+ goto err;
+ }
+
+ if (!dh->
+ meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) {
+ DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ ret = BN_bn2bin(tmp, key);
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ret);
+}
+
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+ /*
+ * If a is only one word long and constant time is false, use the faster
+ * exponenentiation function.
+ */
+ if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) {
+ BN_ULONG A = a->d[0];
+ return BN_mod_exp_mont_word(r, A, p, m, ctx, m_ctx);
+ } else
+ return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+static int dh_init(DH *dh)
+{
+ dh->flags |= DH_FLAG_CACHE_MONT_P;
+ return (1);
+}
+
+static int dh_finish(DH *dh)
+{
+ if (dh->method_mont_p)
+ BN_MONT_CTX_free(dh->method_mont_p);
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_lib.c b/Cryptlib/OpenSSL/crypto/dh/dh_lib.c
new file mode 100644
index 00000000..bebc160e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_lib.c
@@ -0,0 +1,263 @@
+/* crypto/dh/dh_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+const char DH_version[] = "Diffie-Hellman" OPENSSL_VERSION_PTEXT;
+
+static const DH_METHOD *default_DH_method = NULL;
+
+void DH_set_default_method(const DH_METHOD *meth)
+{
+ default_DH_method = meth;
+}
+
+const DH_METHOD *DH_get_default_method(void)
+{
+ if (!default_DH_method) {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dh_openssl();
+ else
+ return DH_OpenSSL();
+#else
+ default_DH_method = DH_OpenSSL();
+#endif
+ }
+ return default_DH_method;
+}
+
+int DH_set_method(DH *dh, const DH_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 DH_METHOD *mtmp;
+ mtmp = dh->meth;
+ if (mtmp->finish)
+ mtmp->finish(dh);
+#ifndef OPENSSL_NO_ENGINE
+ if (dh->engine) {
+ ENGINE_finish(dh->engine);
+ dh->engine = NULL;
+ }
+#endif
+ dh->meth = meth;
+ if (meth->init)
+ meth->init(dh);
+ return 1;
+}
+
+DH *DH_new(void)
+{
+ return DH_new_method(NULL);
+}
+
+DH *DH_new_method(ENGINE *engine)
+{
+ DH *ret;
+
+ ret = (DH *)OPENSSL_malloc(sizeof(DH));
+ if (ret == NULL) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ ret->meth = DH_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+ if (engine) {
+ if (!ENGINE_init(engine)) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ ret->engine = engine;
+ } else
+ ret->engine = ENGINE_get_default_DH();
+ if (ret->engine) {
+ ret->meth = ENGINE_get_DH(ret->engine);
+ if (!ret->meth) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+ ENGINE_finish(ret->engine);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+#endif
+
+ ret->pad = 0;
+ ret->version = 0;
+ ret->p = NULL;
+ ret->g = NULL;
+ ret->length = 0;
+ ret->pub_key = NULL;
+ ret->priv_key = NULL;
+ ret->q = NULL;
+ ret->j = NULL;
+ ret->seed = NULL;
+ ret->seedlen = 0;
+ ret->counter = NULL;
+ ret->method_mont_p = NULL;
+ ret->references = 1;
+ ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
+ 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_DH, ret, &ret->ex_data);
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+ return (ret);
+}
+
+void DH_free(DH *r)
+{
+ int i;
+ if (r == NULL)
+ return;
+ i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH);
+#ifdef REF_PRINT
+ REF_PRINT("DH", r);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "DH_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_DH, r, &r->ex_data);
+
+ if (r->p != NULL)
+ BN_clear_free(r->p);
+ if (r->g != NULL)
+ BN_clear_free(r->g);
+ if (r->q != NULL)
+ BN_clear_free(r->q);
+ if (r->j != NULL)
+ BN_clear_free(r->j);
+ if (r->seed)
+ OPENSSL_free(r->seed);
+ if (r->counter != NULL)
+ BN_clear_free(r->counter);
+ if (r->pub_key != NULL)
+ BN_clear_free(r->pub_key);
+ if (r->priv_key != NULL)
+ BN_clear_free(r->priv_key);
+ OPENSSL_free(r);
+}
+
+int DH_up_ref(DH *r)
+{
+ int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
+#ifdef REF_PRINT
+ REF_PRINT("DH", r);
+#endif
+#ifdef REF_CHECK
+ if (i < 2) {
+ fprintf(stderr, "DH_up, bad reference count\n");
+ abort();
+ }
+#endif
+ return ((i > 1) ? 1 : 0);
+}
+
+int DH_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_DH, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int DH_set_ex_data(DH *d, int idx, void *arg)
+{
+ return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
+}
+
+void *DH_get_ex_data(DH *d, int idx)
+{
+ return (CRYPTO_get_ex_data(&d->ex_data, idx));
+}
+
+int DH_size(const DH *dh)
+{
+ return (BN_num_bytes(dh->p));
+}
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c b/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c
new file mode 100644
index 00000000..926be98e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c
@@ -0,0 +1,558 @@
+/*
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#include <openssl/objects.h>
+#include "evp_locl.h"
+
+/* DH pkey context structure */
+
+typedef struct {
+ /* Parameter gen parameters */
+ int prime_len;
+ int generator;
+ int use_dsa;
+ int subprime_len;
+ /* message digest used for parameter generation */
+ const EVP_MD *md;
+ int rfc5114_param;
+ /* Keygen callback info */
+ int gentmp[2];
+ /* KDF (if any) to use for DH */
+ char kdf_type;
+ /* OID to use for KDF */
+ ASN1_OBJECT *kdf_oid;
+ /* Message digest to use for key derivation */
+ const EVP_MD *kdf_md;
+ /* User key material */
+ unsigned char *kdf_ukm;
+ size_t kdf_ukmlen;
+ /* KDF output length */
+ size_t kdf_outlen;
+} 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->subprime_len = -1;
+ dctx->generator = 2;
+ dctx->use_dsa = 0;
+ dctx->md = NULL;
+ dctx->rfc5114_param = 0;
+
+ dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
+ dctx->kdf_oid = NULL;
+ dctx->kdf_md = NULL;
+ dctx->kdf_ukm = NULL;
+ dctx->kdf_ukmlen = 0;
+ dctx->kdf_outlen = 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->subprime_len = sctx->subprime_len;
+ dctx->generator = sctx->generator;
+ dctx->use_dsa = sctx->use_dsa;
+ dctx->md = sctx->md;
+ dctx->rfc5114_param = sctx->rfc5114_param;
+
+ dctx->kdf_type = sctx->kdf_type;
+ dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
+ if (!dctx->kdf_oid)
+ return 0;
+ dctx->kdf_md = sctx->kdf_md;
+ if (dctx->kdf_ukm) {
+ dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
+ dctx->kdf_ukmlen = sctx->kdf_ukmlen;
+ }
+ dctx->kdf_outlen = sctx->kdf_outlen;
+ return 1;
+}
+
+static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
+{
+ DH_PKEY_CTX *dctx = ctx->data;
+ if (dctx) {
+ if (dctx->kdf_ukm)
+ OPENSSL_free(dctx->kdf_ukm);
+ if (dctx->kdf_oid)
+ ASN1_OBJECT_free(dctx->kdf_oid);
+ 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_SUBPRIME_LEN:
+ if (dctx->use_dsa == 0)
+ return -2;
+ dctx->subprime_len = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+ if (dctx->use_dsa)
+ return -2;
+ dctx->generator = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
+#ifdef OPENSSL_NO_DSA
+ if (p1 != 0)
+ return -2;
+#else
+ if (p1 < 0 || p1 > 2)
+ return -2;
+#endif
+ dctx->use_dsa = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_RFC5114:
+ if (p1 < 1 || p1 > 3)
+ return -2;
+ dctx->rfc5114_param = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_PEER_KEY:
+ /* Default behaviour is OK */
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_TYPE:
+ if (p1 == -2)
+ return dctx->kdf_type;
+#ifdef OPENSSL_NO_CMS
+ if (p1 != EVP_PKEY_DH_KDF_NONE)
+#else
+ if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
+#endif
+ return -2;
+ dctx->kdf_type = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_MD:
+ dctx->kdf_md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_MD:
+ *(const EVP_MD **)p2 = dctx->kdf_md;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
+ if (p1 <= 0)
+ return -2;
+ dctx->kdf_outlen = (size_t)p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
+ *(int *)p2 = dctx->kdf_outlen;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_UKM:
+ if (dctx->kdf_ukm)
+ OPENSSL_free(dctx->kdf_ukm);
+ dctx->kdf_ukm = p2;
+ if (p2)
+ dctx->kdf_ukmlen = p1;
+ else
+ dctx->kdf_ukmlen = 0;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
+ *(unsigned char **)p2 = dctx->kdf_ukm;
+ return dctx->kdf_ukmlen;
+
+ case EVP_PKEY_CTRL_DH_KDF_OID:
+ if (dctx->kdf_oid)
+ ASN1_OBJECT_free(dctx->kdf_oid);
+ dctx->kdf_oid = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_OID:
+ *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
+ 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_rfc5114")) {
+ DH_PKEY_CTX *dctx = ctx->data;
+ int len;
+ len = atoi(value);
+ if (len < 0 || len > 3)
+ return -2;
+ dctx->rfc5114_param = len;
+ return 1;
+ }
+ if (!strcmp(type, "dh_paramgen_generator")) {
+ int len;
+ len = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
+ }
+ if (!strcmp(type, "dh_paramgen_subprime_len")) {
+ int len;
+ len = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
+ }
+ if (!strcmp(type, "dh_paramgen_type")) {
+ int typ;
+ typ = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
+ }
+ return -2;
+}
+
+#ifndef OPENSSL_NO_DSA
+
+extern 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,
+ unsigned char *seed_out, int *counter_ret,
+ unsigned long *h_ret, BN_GENCB *cb);
+
+extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+ const EVP_MD *evpmd,
+ const unsigned char *seed_in,
+ size_t seed_len, int idx,
+ unsigned char *seed_out, int *counter_ret,
+ unsigned long *h_ret, BN_GENCB *cb);
+
+static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
+{
+ DSA *ret;
+ int rv = 0;
+ int prime_len = dctx->prime_len;
+ int subprime_len = dctx->subprime_len;
+ const EVP_MD *md = dctx->md;
+ if (dctx->use_dsa > 2)
+ return NULL;
+ ret = DSA_new();
+ if (!ret)
+ return NULL;
+ if (subprime_len == -1) {
+ if (prime_len >= 2048)
+ subprime_len = 256;
+ else
+ subprime_len = 160;
+ }
+ if (md == NULL) {
+ if (prime_len >= 2048)
+ md = EVP_sha256();
+ else
+ md = EVP_sha1();
+ }
+ if (dctx->use_dsa == 1)
+ rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
+ NULL, 0, NULL, NULL, NULL, pcb);
+ else if (dctx->use_dsa == 2)
+ rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
+ NULL, 0, -1, NULL, NULL, NULL, pcb);
+ if (rv <= 0) {
+ DSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+#endif
+
+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 (dctx->rfc5114_param) {
+ switch (dctx->rfc5114_param) {
+ case 1:
+ dh = DH_get_1024_160();
+ break;
+
+ case 2:
+ dh = DH_get_2048_224();
+ break;
+
+ case 3:
+ dh = DH_get_2048_256();
+ break;
+
+ default:
+ return -2;
+ }
+ EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+ return 1;
+ }
+
+ if (ctx->pkey_gencb) {
+ pcb = &cb;
+ evp_pkey_set_cb_translate(pcb, ctx);
+ } else
+ pcb = NULL;
+#ifndef OPENSSL_NO_DSA
+ if (dctx->use_dsa) {
+ DSA *dsa_dh;
+ dsa_dh = dsa_dh_generate(dctx, pcb);
+ if (!dsa_dh)
+ return 0;
+ dh = DSA_dup_DH(dsa_dh);
+ DSA_free(dsa_dh);
+ if (!dh)
+ return 0;
+ EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+ return 1;
+ }
+#endif
+ 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(pkey, ctx->pmeth->pkey_id, 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;
+ DH *dh;
+ DH_PKEY_CTX *dctx = ctx->data;
+ BIGNUM *dhpub;
+ if (!ctx->pkey || !ctx->peerkey) {
+ DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
+ return 0;
+ }
+ dh = ctx->pkey->pkey.dh;
+ dhpub = ctx->peerkey->pkey.dh->pub_key;
+ if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
+ if (key == NULL) {
+ *keylen = DH_size(dh);
+ return 1;
+ }
+ ret = DH_compute_key(key, dhpub, dh);
+ if (ret < 0)
+ return ret;
+ *keylen = ret;
+ return 1;
+ }
+#ifndef OPENSSL_NO_CMS
+ else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
+ unsigned char *Z = NULL;
+ size_t Zlen = 0;
+ if (!dctx->kdf_outlen || !dctx->kdf_oid)
+ return 0;
+ if (key == NULL) {
+ *keylen = dctx->kdf_outlen;
+ return 1;
+ }
+ if (*keylen != dctx->kdf_outlen)
+ return 0;
+ ret = 0;
+ Zlen = DH_size(dh);
+ Z = OPENSSL_malloc(Zlen);
+ if (!Z) {
+ goto err;
+ }
+ if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
+ goto err;
+ if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
+ dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
+ goto err;
+ *keylen = dctx->kdf_outlen;
+ ret = 1;
+ err:
+ if (Z) {
+ OPENSSL_cleanse(Z, Zlen);
+ OPENSSL_free(Z);
+ }
+ return ret;
+ }
+#endif
+ return 0;
+}
+
+const EVP_PKEY_METHOD dh_pkey_meth = {
+ EVP_PKEY_DH,
+ 0,
+ 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
+};
+
+const EVP_PKEY_METHOD dhx_pkey_meth = {
+ EVP_PKEY_DHX,
+ 0,
+ 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/Cryptlib/OpenSSL/crypto/dh/dh_prn.c b/Cryptlib/OpenSSL/crypto/dh/dh_prn.c
new file mode 100644
index 00000000..5d6c3a37
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_prn.c
@@ -0,0 +1,79 @@
+/* crypto/asn1/t_pkey.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+
+#ifndef OPENSSL_NO_FP_API
+int DHparams_print_fp(FILE *fp, const DH *x)
+{
+ 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/Cryptlib/OpenSSL/crypto/dh/dh_rfc5114.c b/Cryptlib/OpenSSL/crypto/dh/dh_rfc5114.c
new file mode 100644
index 00000000..e96e2aa3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_rfc5114.c
@@ -0,0 +1,285 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2011.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+
+/* DH parameters from RFC5114 */
+
+#if BN_BITS2 == 64
+static const BN_ULONG dh1024_160_p[] = {
+ 0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL,
+ 0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL,
+ 0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL,
+ 0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL,
+ 0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL,
+ 0xB10B8F96A080E01DULL
+};
+
+static const BN_ULONG dh1024_160_g[] = {
+ 0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL,
+ 0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL,
+ 0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL,
+ 0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL,
+ 0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL,
+ 0xA4D1CBD5C3FD3412ULL
+};
+
+static const BN_ULONG dh1024_160_q[] = {
+ 0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL
+};
+
+static const BN_ULONG dh2048_224_p[] = {
+ 0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL,
+ 0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL,
+ 0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL,
+ 0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL,
+ 0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL,
+ 0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL,
+ 0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL,
+ 0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL,
+ 0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL,
+ 0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL,
+ 0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL
+};
+
+static const BN_ULONG dh2048_224_g[] = {
+ 0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL,
+ 0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL,
+ 0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL,
+ 0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL,
+ 0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL,
+ 0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL,
+ 0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL,
+ 0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL,
+ 0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL,
+ 0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL,
+ 0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL
+};
+
+static const BN_ULONG dh2048_224_q[] = {
+ 0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL,
+ 0x00000000801C0D34ULL
+};
+
+static const BN_ULONG dh2048_256_p[] = {
+ 0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL,
+ 0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL,
+ 0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL,
+ 0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL,
+ 0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL,
+ 0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL,
+ 0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL,
+ 0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL,
+ 0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL,
+ 0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL,
+ 0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL
+};
+
+static const BN_ULONG dh2048_256_g[] = {
+ 0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL,
+ 0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL,
+ 0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL,
+ 0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL,
+ 0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL,
+ 0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL,
+ 0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL,
+ 0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL,
+ 0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL,
+ 0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL,
+ 0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL
+};
+
+static const BN_ULONG dh2048_256_q[] = {
+ 0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL,
+ 0x8CF83642A709A097ULL
+};
+
+#elif BN_BITS2 == 32
+
+static const BN_ULONG dh1024_160_p[] = {
+ 0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF,
+ 0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA,
+ 0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C,
+ 0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286,
+ 0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E,
+ 0xA080E01D, 0xB10B8F96
+};
+
+static const BN_ULONG dh1024_160_g[] = {
+ 0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59,
+ 0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08,
+ 0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F,
+ 0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E,
+ 0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442,
+ 0xC3FD3412, 0xA4D1CBD5
+};
+
+static const BN_ULONG dh1024_160_q[] = {
+ 0x49462353, 0x64B7CB9D, 0x8ABA4E7D, 0x81A8DF27, 0xF518AA87
+};
+
+static const BN_ULONG dh2048_224_p[] = {
+ 0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2,
+ 0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E,
+ 0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1,
+ 0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A,
+ 0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714,
+ 0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0,
+ 0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0,
+ 0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152,
+ 0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40,
+ 0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5,
+ 0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E
+};
+
+static const BN_ULONG dh2048_224_g[] = {
+ 0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1,
+ 0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE,
+ 0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F,
+ 0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137,
+ 0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3,
+ 0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2,
+ 0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0,
+ 0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001,
+ 0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01,
+ 0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B,
+ 0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF
+};
+
+static const BN_ULONG dh2048_224_q[] = {
+ 0xB36371EB, 0xBF389A99, 0x4738CEBC, 0x1F80535A, 0x99717710, 0xC58D93FE,
+ 0x801C0D34
+};
+
+static const BN_ULONG dh2048_256_p[] = {
+ 0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227,
+ 0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A,
+ 0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79,
+ 0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5,
+ 0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267,
+ 0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF,
+ 0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF,
+ 0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64,
+ 0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45,
+ 0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608,
+ 0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D
+};
+
+static const BN_ULONG dh2048_256_g[] = {
+ 0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148,
+ 0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428,
+ 0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15,
+ 0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73,
+ 0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1,
+ 0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982,
+ 0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5,
+ 0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8,
+ 0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A,
+ 0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F,
+ 0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B
+};
+
+static const BN_ULONG dh2048_256_q[] = {
+ 0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976,
+ 0xA709A097, 0x8CF83642
+};
+
+#else
+# error "unsupported BN_BITS2"
+#endif
+
+/* Macro to make a BIGNUM from static data */
+
+#define make_dh_bn(x) static const BIGNUM _bignum_##x = { (BN_ULONG *) x, \
+ sizeof(x)/sizeof(BN_ULONG),\
+ sizeof(x)/sizeof(BN_ULONG),\
+ 0, BN_FLG_STATIC_DATA }
+
+/*
+ * Macro to make a DH structure from BIGNUM data. NB: although just copying
+ * the BIGNUM static pointers would be more efficient we can't as they get
+ * wiped using BN_clear_free() when DH_free() is called.
+ */
+
+#define make_dh(x) \
+DH * DH_get_##x(void) \
+ { \
+ DH *dh; \
+ make_dh_bn(dh##x##_p); \
+ make_dh_bn(dh##x##_q); \
+ make_dh_bn(dh##x##_g); \
+ dh = DH_new(); \
+ if (!dh) \
+ return NULL; \
+ dh->p = BN_dup(&_bignum_dh##x##_p); \
+ dh->g = BN_dup(&_bignum_dh##x##_g); \
+ dh->q = BN_dup(&_bignum_dh##x##_q); \
+ if (!dh->p || !dh->q || !dh->g) \
+ { \
+ DH_free(dh); \
+ return NULL; \
+ } \
+ return dh; \
+ }
+
+make_dh(1024_160)
+make_dh(2048_224)
+make_dh(2048_256)
diff --git a/Cryptlib/OpenSSL/crypto/dso/dso_beos.c b/Cryptlib/OpenSSL/crypto/dso/dso_beos.c
new file mode 100644
index 00000000..68ebcd8a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_beos.c
@@ -0,0 +1,253 @@
+/* dso_beos.c */
+/*
+ * Written by Marcin Konicki (ahwayakchih@neoni.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#if !defined(OPENSSL_SYS_BEOS)
+DSO_METHOD *DSO_METHOD_beos(void)
+{
+ return NULL;
+}
+#else
+
+# include <kernel/image.h>
+
+static int beos_load(DSO *dso);
+static int beos_unload(DSO *dso);
+static void *beos_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname);
+# if 0
+static int beos_unbind_var(DSO *dso, char *symname, void *symptr);
+static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int beos_init(DSO *dso);
+static int beos_finish(DSO *dso);
+static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg);
+# endif
+static char *beos_name_converter(DSO *dso, const char *filename);
+
+static DSO_METHOD dso_meth_beos = {
+ "OpenSSL 'beos' shared library method",
+ beos_load,
+ beos_unload,
+ beos_bind_var,
+ beos_bind_func,
+/* For now, "unbind" doesn't exist */
+# if 0
+ NULL, /* unbind_var */
+ NULL, /* unbind_func */
+# endif
+ NULL, /* ctrl */
+ beos_name_converter,
+ NULL, /* init */
+ NULL /* finish */
+};
+
+DSO_METHOD *DSO_METHOD_beos(void)
+{
+ return (&dso_meth_beos);
+}
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to
+ * the handle (image_id) returned from load_add_on().
+ */
+
+static int beos_load(DSO *dso)
+{
+ image_id id;
+ /* See applicable comments from dso_dl.c */
+ char *filename = DSO_convert_filename(dso, NULL);
+
+ if (filename == NULL) {
+ DSOerr(DSO_F_BEOS_LOAD, DSO_R_NO_FILENAME);
+ goto err;
+ }
+ id = load_add_on(filename);
+ if (id < 1) {
+ DSOerr(DSO_F_BEOS_LOAD, DSO_R_LOAD_FAILED);
+ ERR_add_error_data(3, "filename(", filename, ")");
+ goto err;
+ }
+ if (!sk_push(dso->meth_data, (char *)id)) {
+ DSOerr(DSO_F_BEOS_LOAD, DSO_R_STACK_ERROR);
+ goto err;
+ }
+ /* Success */
+ dso->loaded_filename = filename;
+ return (1);
+ err:
+ /* Cleanup ! */
+ if (filename != NULL)
+ OPENSSL_free(filename);
+ if (id > 0)
+ unload_add_on(id);
+ return (0);
+}
+
+static int beos_unload(DSO *dso)
+{
+ image_id id;
+ if (dso == NULL) {
+ DSOerr(DSO_F_BEOS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (sk_num(dso->meth_data) < 1)
+ return (1);
+ id = (image_id) sk_pop(dso->meth_data);
+ if (id < 1) {
+ DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_NULL_HANDLE);
+ return (0);
+ }
+ if (unload_add_on(id) != B_OK) {
+ DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_UNLOAD_FAILED);
+ /*
+ * We should push the value back onto the stack in case of a retry.
+ */
+ sk_push(dso->meth_data, (char *)id);
+ return (0);
+ }
+ return (1);
+}
+
+static void *beos_bind_var(DSO *dso, const char *symname)
+{
+ image_id id;
+ void *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_BEOS_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+ if (id < 1) {
+ DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_NULL_HANDLE);
+ return (NULL);
+ }
+ if (get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK) {
+ DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(3, "symname(", symname, ")");
+ return (NULL);
+ }
+ return (sym);
+}
+
+static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname)
+{
+ image_id id;
+ void *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_BEOS_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+ if (id < 1) {
+ DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_NULL_HANDLE);
+ return (NULL);
+ }
+ if (get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK) {
+ DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(3, "symname(", symname, ")");
+ return (NULL);
+ }
+ return ((DSO_FUNC_TYPE)sym);
+}
+
+/* This one is the same as the one in dlfcn */
+static char *beos_name_converter(DSO *dso, const char *filename)
+{
+ char *translated;
+ int len, rsize, transform;
+
+ len = strlen(filename);
+ rsize = len + 1;
+ transform = (strstr(filename, "/") == NULL);
+ if (transform) {
+ /* We will convert this to "%s.so" or "lib%s.so" */
+ rsize += 3; /* The length of ".so" */
+ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+ rsize += 3; /* The length of "lib" */
+ }
+ translated = OPENSSL_malloc(rsize);
+ if (translated == NULL) {
+ DSOerr(DSO_F_BEOS_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+ return (NULL);
+ }
+ if (transform) {
+ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+ sprintf(translated, "lib%s.so", filename);
+ else
+ sprintf(translated, "%s.so", filename);
+ } else
+ sprintf(translated, "%s", filename);
+ return (translated);
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/dso/dso_dl.c b/Cryptlib/OpenSSL/crypto/dso/dso_dl.c
new file mode 100644
index 00000000..ceedf66e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_dl.c
@@ -0,0 +1,380 @@
+/* dso_dl.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#ifndef DSO_DL
+DSO_METHOD *DSO_METHOD_dl(void)
+{
+ return NULL;
+}
+#else
+
+# include <dl.h>
+
+/* Part of the hack in "dl_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dl_load(DSO *dso);
+static int dl_unload(DSO *dso);
+static void *dl_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
+# if 0
+static int dl_unbind_var(DSO *dso, char *symname, void *symptr);
+static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int dl_init(DSO *dso);
+static int dl_finish(DSO *dso);
+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",
+ dl_load,
+ dl_unload,
+ dl_bind_var,
+ dl_bind_func,
+/* For now, "unbind" doesn't exist */
+# if 0
+ NULL, /* unbind_var */
+ NULL, /* unbind_func */
+# endif
+ NULL, /* ctrl */
+ dl_name_converter,
+ dl_merger,
+ NULL, /* init */
+ NULL, /* finish */
+ dl_pathbyaddr,
+ dl_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_dl(void)
+{
+ return (&dso_meth_dl);
+}
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle
+ * (shl_t) returned from shl_load(). NB: I checked on HPUX11 and shl_t is
+ * itself a pointer type so the cast is safe.
+ */
+
+static int dl_load(DSO *dso)
+{
+ shl_t ptr = NULL;
+ /*
+ * We don't do any fancy retries or anything, just take the method's (or
+ * DSO's if it has the callback set) best translation of the
+ * platform-independant filename and try once with that.
+ */
+ char *filename = DSO_convert_filename(dso, NULL);
+
+ if (filename == NULL) {
+ DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME);
+ goto err;
+ }
+ ptr = shl_load(filename, BIND_IMMEDIATE |
+ (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 :
+ DYNAMIC_PATH), 0L);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED);
+ ERR_add_error_data(4, "filename(", filename, "): ", strerror(errno));
+ goto err;
+ }
+ if (!sk_push(dso->meth_data, (char *)ptr)) {
+ DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR);
+ goto err;
+ }
+ /*
+ * Success, stick the converted filename we've loaded under into the DSO
+ * (it also serves as the indicator that we are currently loaded).
+ */
+ dso->loaded_filename = filename;
+ return (1);
+ err:
+ /* Cleanup! */
+ if (filename != NULL)
+ OPENSSL_free(filename);
+ if (ptr != NULL)
+ shl_unload(ptr);
+ return (0);
+}
+
+static int dl_unload(DSO *dso)
+{
+ shl_t ptr;
+ if (dso == NULL) {
+ DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (sk_num(dso->meth_data) < 1)
+ return (1);
+ /* Is this statement legal? */
+ ptr = (shl_t) sk_pop(dso->meth_data);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_DL_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);
+ return (0);
+ }
+ shl_unload(ptr);
+ return (1);
+}
+
+static void *dl_bind_var(DSO *dso, const char *symname)
+{
+ shl_t ptr;
+ void *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_DL_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_DL_BIND_VAR, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_DL_BIND_VAR, DSO_R_NULL_HANDLE);
+ return (NULL);
+ }
+ if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) {
+ DSOerr(DSO_F_DL_BIND_VAR, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno));
+ return (NULL);
+ }
+ return (sym);
+}
+
+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
+{
+ shl_t ptr;
+ void *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE);
+ return (NULL);
+ }
+ if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) {
+ DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno));
+ return (NULL);
+ }
+ return ((DSO_FUNC_TYPE)sym);
+}
+
+static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
+{
+ char *merged;
+
+ if (!filespec1 && !filespec2) {
+ DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ /*
+ * If the first file specification is a rooted path, it rules. same goes
+ * if the second file specification is missing.
+ */
+ if (!filespec2 || filespec1[0] == '/') {
+ merged = OPENSSL_malloc(strlen(filespec1) + 1);
+ if (!merged) {
+ DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec1);
+ }
+ /*
+ * If the first file specification is missing, the second one rules.
+ */
+ else if (!filespec1) {
+ merged = OPENSSL_malloc(strlen(filespec2) + 1);
+ if (!merged) {
+ DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec2);
+ } else
+ /*
+ * This part isn't as trivial as it looks. It assumes that the
+ * second file specification really is a directory, and makes no
+ * checks whatsoever. Therefore, the result becomes the
+ * concatenation of filespec2 followed by a slash followed by
+ * filespec1.
+ */
+ {
+ int spec2len, len;
+
+ spec2len = (filespec2 ? strlen(filespec2) : 0);
+ len = spec2len + (filespec1 ? strlen(filespec1) : 0);
+
+ if (filespec2 && filespec2[spec2len - 1] == '/') {
+ spec2len--;
+ len--;
+ }
+ merged = OPENSSL_malloc(len + 2);
+ if (!merged) {
+ DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec2);
+ merged[spec2len] = '/';
+ strcpy(&merged[spec2len + 1], filespec1);
+ }
+ return (merged);
+}
+
+/*
+ * This function is identical to the one in dso_dlfcn.c, but as it is highly
+ * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at
+ * the same time, there's no great duplicating the code. Figuring out an
+ * elegant way to share one copy of the code would be more difficult and
+ * would not leave the implementations independant.
+ */
+# if defined(__hpux)
+static const char extension[] = ".sl";
+# else
+static const char extension[] = ".so";
+# endif
+static char *dl_name_converter(DSO *dso, const char *filename)
+{
+ char *translated;
+ int len, rsize, transform;
+
+ len = strlen(filename);
+ rsize = len + 1;
+ transform = (strstr(filename, "/") == NULL);
+ {
+ /* We will convert this to "%s.s?" or "lib%s.s?" */
+ rsize += strlen(extension); /* The length of ".s?" */
+ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+ rsize += 3; /* The length of "lib" */
+ }
+ translated = OPENSSL_malloc(rsize);
+ if (translated == NULL) {
+ DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+ return (NULL);
+ }
+ if (transform) {
+ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+ sprintf(translated, "lib%s%s", filename, extension);
+ else
+ sprintf(translated, "%s%s", filename, extension);
+ } else
+ sprintf(translated, "%s", 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/Cryptlib/OpenSSL/crypto/dso/dso_dlfcn.c b/Cryptlib/OpenSSL/crypto/dso/dso_dlfcn.c
new file mode 100644
index 00000000..78df723f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_dlfcn.c
@@ -0,0 +1,465 @@
+/* dso_dlfcn.c */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/*
+ * 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.
+ */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE /* make sure dladdr is declared */
+#endif
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#ifndef DSO_DLFCN
+DSO_METHOD *DSO_METHOD_dlfcn(void)
+{
+ return NULL;
+}
+#else
+
+# ifdef HAVE_DLFCN_H
+# ifdef __osf__
+# define __EXTENSIONS__
+# endif
+# include <dlfcn.h>
+# define HAVE_DLINFO 1
+# if defined(_AIX) || defined(__CYGWIN__) || \
+ defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+ (defined(__osf__) && !defined(RTLD_NEXT)) || \
+ (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
+ defined(__ANDROID__)
+# undef HAVE_DLINFO
+# endif
+# endif
+
+/* Part of the hack in "dlfcn_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dlfcn_load(DSO *dso);
+static int dlfcn_unload(DSO *dso);
+static void *dlfcn_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
+# if 0
+static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
+static int dlfcn_init(DSO *dso);
+static int dlfcn_finish(DSO *dso);
+static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
+# endif
+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",
+ dlfcn_load,
+ dlfcn_unload,
+ dlfcn_bind_var,
+ dlfcn_bind_func,
+/* For now, "unbind" doesn't exist */
+# if 0
+ NULL, /* unbind_var */
+ NULL, /* unbind_func */
+# endif
+ NULL, /* ctrl */
+ dlfcn_name_converter,
+ dlfcn_merger,
+ NULL, /* init */
+ NULL, /* finish */
+ dlfcn_pathbyaddr,
+ dlfcn_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_dlfcn(void)
+{
+ return (&dso_meth_dlfcn);
+}
+
+/*
+ * Prior to using the dlopen() function, we should decide on the flag we
+ * send. There's a few different ways of doing this and it's a messy
+ * venn-diagram to match up which platforms support what. So as we don't have
+ * autoconf yet, I'm implementing a hack that could be hacked further
+ * relatively easily to deal with cases as we find them. Initially this is to
+ * cope with OpenBSD.
+ */
+# if defined(__OpenBSD__) || defined(__NetBSD__)
+# ifdef DL_LAZY
+# define DLOPEN_FLAG DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define DLOPEN_FLAG RTLD_NOW
+# else
+# define DLOPEN_FLAG 0
+# endif
+# endif
+# else
+# ifdef OPENSSL_SYS_SUNOS
+# define DLOPEN_FLAG 1
+# else
+# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
+# endif
+# endif
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle
+ * (void*) returned from dlopen().
+ */
+
+static int dlfcn_load(DSO *dso)
+{
+ void *ptr = NULL;
+ /* See applicable comments in dso_dl.c */
+ char *filename = DSO_convert_filename(dso, NULL);
+ int flags = DLOPEN_FLAG;
+
+ if (filename == NULL) {
+ DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
+ goto err;
+ }
+# ifdef RTLD_GLOBAL
+ if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
+ flags |= RTLD_GLOBAL;
+# endif
+ ptr = dlopen(filename, flags);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED);
+ ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
+ goto err;
+ }
+ if (!sk_void_push(dso->meth_data, (char *)ptr)) {
+ DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
+ goto err;
+ }
+ /* Success */
+ dso->loaded_filename = filename;
+ return (1);
+ err:
+ /* Cleanup! */
+ if (filename != NULL)
+ OPENSSL_free(filename);
+ if (ptr != NULL)
+ dlclose(ptr);
+ return (0);
+}
+
+static int dlfcn_unload(DSO *dso)
+{
+ void *ptr;
+ if (dso == NULL) {
+ DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (sk_void_num(dso->meth_data) < 1)
+ return (1);
+ 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_void_push(dso->meth_data, ptr);
+ return (0);
+ }
+ /* For now I'm not aware of any errors associated with dlclose() */
+ dlclose(ptr);
+ return (1);
+}
+
+static void *dlfcn_bind_var(DSO *dso, const char *symname)
+{
+ void *ptr, *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_DLFCN_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_void_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ 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);
+ return (NULL);
+ }
+ sym = dlsym(ptr, symname);
+ if (sym == NULL) {
+ DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
+ return (NULL);
+ }
+ return (sym);
+}
+
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
+{
+ void *ptr;
+ union {
+ DSO_FUNC_TYPE sym;
+ void *dlret;
+ } u;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_void_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ 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);
+ return (NULL);
+ }
+ u.dlret = dlsym(ptr, symname);
+ if (u.dlret == NULL) {
+ DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
+ return (NULL);
+ }
+ return u.sym;
+}
+
+static char *dlfcn_merger(DSO *dso, const char *filespec1,
+ const char *filespec2)
+{
+ char *merged;
+
+ if (!filespec1 && !filespec2) {
+ DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ /*
+ * If the first file specification is a rooted path, it rules. same goes
+ * if the second file specification is missing.
+ */
+ if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) {
+ merged = OPENSSL_malloc(strlen(filespec1) + 1);
+ if (!merged) {
+ DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec1);
+ }
+ /*
+ * If the first file specification is missing, the second one rules.
+ */
+ else if (!filespec1) {
+ merged = OPENSSL_malloc(strlen(filespec2) + 1);
+ if (!merged) {
+ DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec2);
+ } else {
+ /*
+ * This part isn't as trivial as it looks. It assumes that the
+ * second file specification really is a directory, and makes no
+ * checks whatsoever. Therefore, the result becomes the
+ * concatenation of filespec2 followed by a slash followed by
+ * filespec1.
+ */
+ int spec2len, len;
+
+ spec2len = strlen(filespec2);
+ len = spec2len + strlen(filespec1);
+
+ if (spec2len && filespec2[spec2len - 1] == '/') {
+ spec2len--;
+ len--;
+ }
+ merged = OPENSSL_malloc(len + 2);
+ if (!merged) {
+ DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec2);
+ merged[spec2len] = '/';
+ strcpy(&merged[spec2len + 1], filespec1);
+ }
+ return (merged);
+}
+
+# ifdef OPENSSL_SYS_MACOSX
+# define DSO_ext ".dylib"
+# define DSO_extlen 6
+# else
+# define DSO_ext ".so"
+# define DSO_extlen 3
+# endif
+
+static char *dlfcn_name_converter(DSO *dso, const char *filename)
+{
+ char *translated;
+ int len, rsize, transform;
+
+ len = strlen(filename);
+ rsize = len + 1;
+ transform = (strstr(filename, "/") == NULL);
+ if (transform) {
+ /* We will convert this to "%s.so" or "lib%s.so" etc */
+ rsize += DSO_extlen; /* The length of ".so" */
+ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+ rsize += 3; /* The length of "lib" */
+ }
+ translated = OPENSSL_malloc(rsize);
+ if (translated == NULL) {
+ DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+ return (NULL);
+ }
+ if (transform) {
+ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+ sprintf(translated, "lib%s" DSO_ext, filename);
+ else
+ sprintf(translated, "%s" DSO_ext, filename);
+ } else
+ sprintf(translated, "%s", filename);
+ return (translated);
+}
+
+# ifdef __sgi
+/*-
+This is a quote from IRIX manual for dladdr(3c):
+
+ <dlfcn.h> does not contain a prototype for dladdr or definition of
+ Dl_info. The #include <dlfcn.h> 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 <rld_interface.h>
+# 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(2, "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/Cryptlib/OpenSSL/crypto/dso/dso_err.c b/Cryptlib/OpenSSL/crypto/dso/dso_err.c
new file mode 100644
index 00000000..e143cc01
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_err.c
@@ -0,0 +1,158 @@
+/* crypto/dso/dso_err.c */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dso.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
+
+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"},
+ {ERR_FUNC(DSO_F_DLFCN_MERGER), "DLFCN_MERGER"},
+ {ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"},
+ {ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"},
+ {ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"},
+ {ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"},
+ {ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"},
+ {ERR_FUNC(DSO_F_DL_MERGER), "DL_MERGER"},
+ {ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"},
+ {ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"},
+ {ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"},
+ {ERR_FUNC(DSO_F_DSO_BIND_VAR), "DSO_bind_var"},
+ {ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"},
+ {ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"},
+ {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}
+};
+
+static ERR_STRING_DATA DSO_str_reasons[] = {
+ {ERR_REASON(DSO_R_CTRL_FAILED), "control command failed"},
+ {ERR_REASON(DSO_R_DSO_ALREADY_LOADED), "dso already loaded"},
+ {ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE), "empty file structure"},
+ {ERR_REASON(DSO_R_FAILURE), "failure"},
+ {ERR_REASON(DSO_R_FILENAME_TOO_BIG), "filename too big"},
+ {ERR_REASON(DSO_R_FINISH_FAILED), "cleanup method function failed"},
+ {ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX), "incorrect file syntax"},
+ {ERR_REASON(DSO_R_LOAD_FAILED), "could not load the shared library"},
+ {ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"},
+ {ERR_REASON(DSO_R_NO_FILENAME), "no filename"},
+ {ERR_REASON(DSO_R_NO_FILE_SPECIFICATION), "no file specification"},
+ {ERR_REASON(DSO_R_NULL_HANDLE), "a null shared library handle was used"},
+ {ERR_REASON(DSO_R_SET_FILENAME_FAILED), "set filename failed"},
+ {ERR_REASON(DSO_R_STACK_ERROR), "the meth_data stack is corrupt"},
+ {ERR_REASON(DSO_R_SYM_FAILURE),
+ "could not bind to the requested symbol name"},
+ {ERR_REASON(DSO_R_UNLOAD_FAILED), "could not unload the shared library"},
+ {ERR_REASON(DSO_R_UNSUPPORTED), "functionality not supported"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_DSO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, DSO_str_functs);
+ ERR_load_strings(0, DSO_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/dso/dso_lib.c b/Cryptlib/OpenSSL/crypto/dso/dso_lib.c
new file mode 100644
index 00000000..2beb7c1b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_lib.c
@@ -0,0 +1,448 @@
+/* dso_lib.c */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+static DSO_METHOD *default_DSO_meth = NULL;
+
+DSO *DSO_new(void)
+{
+ return (DSO_new_method(NULL));
+}
+
+void DSO_set_default_method(DSO_METHOD *meth)
+{
+ default_DSO_meth = meth;
+}
+
+DSO_METHOD *DSO_get_default_method(void)
+{
+ return (default_DSO_meth);
+}
+
+DSO_METHOD *DSO_get_method(DSO *dso)
+{
+ return (dso->meth);
+}
+
+DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth)
+{
+ DSO_METHOD *mtmp;
+ mtmp = dso->meth;
+ dso->meth = meth;
+ return (mtmp);
+}
+
+DSO *DSO_new_method(DSO_METHOD *meth)
+{
+ DSO *ret;
+
+ if (default_DSO_meth == NULL)
+ /*
+ * We default to DSO_METH_openssl() which in turn defaults to
+ * stealing the "best available" method. Will fallback to
+ * DSO_METH_null() in the worst case.
+ */
+ default_DSO_meth = DSO_METHOD_openssl();
+ ret = (DSO *)OPENSSL_malloc(sizeof(DSO));
+ if (ret == NULL) {
+ DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(DSO));
+ ret->meth_data = sk_void_new_null();
+ if (ret->meth_data == NULL) {
+ /* sk_new doesn't generate any errors so we do */
+ DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return (NULL);
+ }
+ if (meth == NULL)
+ ret->meth = default_DSO_meth;
+ else
+ ret->meth = meth;
+ ret->references = 1;
+ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+ sk_void_free(ret->meth_data);
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+ return (ret);
+}
+
+int DSO_free(DSO *dso)
+{
+ int i;
+
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_FREE, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+
+ i = CRYPTO_add(&dso->references, -1, CRYPTO_LOCK_DSO);
+#ifdef REF_PRINT
+ REF_PRINT("DSO", dso);
+#endif
+ if (i > 0)
+ return (1);
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "DSO_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) {
+ DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED);
+ return (0);
+ }
+
+ if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) {
+ DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED);
+ return (0);
+ }
+
+ sk_void_free(dso->meth_data);
+ if (dso->filename != NULL)
+ OPENSSL_free(dso->filename);
+ if (dso->loaded_filename != NULL)
+ OPENSSL_free(dso->loaded_filename);
+
+ OPENSSL_free(dso);
+ return (1);
+}
+
+int DSO_flags(DSO *dso)
+{
+ return ((dso == NULL) ? 0 : dso->flags);
+}
+
+int DSO_up_ref(DSO *dso)
+{
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+
+ CRYPTO_add(&dso->references, 1, CRYPTO_LOCK_DSO);
+ return (1);
+}
+
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
+{
+ DSO *ret;
+ int allocated = 0;
+
+ if (dso == NULL) {
+ ret = DSO_new_method(meth);
+ if (ret == NULL) {
+ DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ allocated = 1;
+ /* Pass the provided flags to the new DSO object */
+ if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) {
+ DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED);
+ goto err;
+ }
+ } else
+ ret = dso;
+ /* Don't load if we're currently already loaded */
+ if (ret->filename != NULL) {
+ DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED);
+ goto err;
+ }
+ /*
+ * filename can only be NULL if we were passed a dso that already has one
+ * set.
+ */
+ if (filename != NULL)
+ if (!DSO_set_filename(ret, filename)) {
+ DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED);
+ goto err;
+ }
+ filename = ret->filename;
+ if (filename == NULL) {
+ DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME);
+ goto err;
+ }
+ if (ret->meth->dso_load == NULL) {
+ DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED);
+ goto err;
+ }
+ if (!ret->meth->dso_load(ret)) {
+ DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED);
+ goto err;
+ }
+ /* Load succeeded */
+ return (ret);
+ err:
+ if (allocated)
+ DSO_free(ret);
+ return (NULL);
+}
+
+void *DSO_bind_var(DSO *dso, const char *symname)
+{
+ void *ret = NULL;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_DSO_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (dso->meth->dso_bind_var == NULL) {
+ DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_UNSUPPORTED);
+ return (NULL);
+ }
+ if ((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) {
+ DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_SYM_FAILURE);
+ return (NULL);
+ }
+ /* Success */
+ return (ret);
+}
+
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
+{
+ DSO_FUNC_TYPE ret = NULL;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (dso->meth->dso_bind_func == NULL) {
+ DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED);
+ return (NULL);
+ }
+ if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) {
+ DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE);
+ return (NULL);
+ }
+ /* Success */
+ return (ret);
+}
+
+/*
+ * I don't really like these *_ctrl functions very much to be perfectly
+ * honest. For one thing, I think I have to return a negative value for any
+ * error because possible DSO_ctrl() commands may return values such as
+ * "size"s that can legitimately be zero (making the standard
+ * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd
+ * times. I'd prefer "output" values to be passed by reference and the return
+ * value as success/failure like usual ... but we conform when we must... :-)
+ */
+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
+{
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+ return (-1);
+ }
+ /*
+ * We should intercept certain generic commands and only pass control to
+ * the method-specific ctrl() function if it's something we don't handle.
+ */
+ switch (cmd) {
+ case DSO_CTRL_GET_FLAGS:
+ return dso->flags;
+ case DSO_CTRL_SET_FLAGS:
+ dso->flags = (int)larg;
+ return (0);
+ case DSO_CTRL_OR_FLAGS:
+ dso->flags |= (int)larg;
+ return (0);
+ default:
+ break;
+ }
+ if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) {
+ DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED);
+ return (-1);
+ }
+ return (dso->meth->dso_ctrl(dso, cmd, larg, parg));
+}
+
+int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+ DSO_NAME_CONVERTER_FUNC *oldcb)
+{
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_SET_NAME_CONVERTER, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (oldcb)
+ *oldcb = dso->name_converter;
+ dso->name_converter = cb;
+ return (1);
+}
+
+const char *DSO_get_filename(DSO *dso)
+{
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ return (dso->filename);
+}
+
+int DSO_set_filename(DSO *dso, const char *filename)
+{
+ char *copied;
+
+ if ((dso == NULL) || (filename == NULL)) {
+ DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (dso->loaded_filename) {
+ DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED);
+ return (0);
+ }
+ /* We'll duplicate filename */
+ copied = OPENSSL_malloc(strlen(filename) + 1);
+ if (copied == NULL) {
+ DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ BUF_strlcpy(copied, filename, strlen(filename) + 1);
+ if (dso->filename)
+ OPENSSL_free(dso->filename);
+ dso->filename = copied;
+ return (1);
+}
+
+char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
+{
+ char *result = NULL;
+
+ if (dso == NULL || filespec1 == NULL) {
+ DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+ if (dso->merger != NULL)
+ result = dso->merger(dso, filespec1, filespec2);
+ else if (dso->meth->dso_merger != NULL)
+ result = dso->meth->dso_merger(dso, filespec1, filespec2);
+ }
+ return (result);
+}
+
+char *DSO_convert_filename(DSO *dso, const char *filename)
+{
+ char *result = NULL;
+
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (filename == NULL)
+ filename = dso->filename;
+ if (filename == NULL) {
+ DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
+ return (NULL);
+ }
+ if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+ if (dso->name_converter != NULL)
+ result = dso->name_converter(dso, filename);
+ else if (dso->meth->dso_name_converter != NULL)
+ result = dso->meth->dso_name_converter(dso, filename);
+ }
+ if (result == NULL) {
+ result = OPENSSL_malloc(strlen(filename) + 1);
+ if (result == NULL) {
+ DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ BUF_strlcpy(result, filename, strlen(filename) + 1);
+ }
+ return (result);
+}
+
+const char *DSO_get_loaded_filename(DSO *dso)
+{
+ if (dso == NULL) {
+ DSOerr(DSO_F_DSO_GET_LOADED_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ 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/Cryptlib/OpenSSL/crypto/dso/dso_null.c b/Cryptlib/OpenSSL/crypto/dso/dso_null.c
new file mode 100644
index 00000000..20122d1c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_null.c
@@ -0,0 +1,92 @@
+/* dso_null.c */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/*
+ * This "NULL" method is provided as the fallback for systems that have no
+ * appropriate support for "shared-libraries".
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+static DSO_METHOD dso_meth_null = {
+ "NULL shared library method",
+ NULL, /* load */
+ NULL, /* unload */
+ NULL, /* bind_var */
+ NULL, /* bind_func */
+/* For now, "unbind" doesn't exist */
+#if 0
+ NULL, /* unbind_var */
+ NULL, /* unbind_func */
+#endif
+ NULL, /* ctrl */
+ NULL, /* dso_name_converter */
+ NULL, /* dso_merger */
+ NULL, /* init */
+ NULL, /* finish */
+ NULL, /* pathbyaddr */
+ NULL /* globallookup */
+};
+
+DSO_METHOD *DSO_METHOD_null(void)
+{
+ return (&dso_meth_null);
+}
diff --git a/Cryptlib/OpenSSL/crypto/dso/dso_openssl.c b/Cryptlib/OpenSSL/crypto/dso/dso_openssl.c
new file mode 100644
index 00000000..087e989e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_openssl.c
@@ -0,0 +1,83 @@
+/* dso_openssl.c */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+/* We just pinch the method from an appropriate "default" method. */
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+#ifdef DEF_DSO_METHOD
+ return (DEF_DSO_METHOD());
+#elif defined(DSO_DLFCN)
+ return (DSO_METHOD_dlfcn());
+#elif defined(DSO_DL)
+ return (DSO_METHOD_dl());
+#elif defined(DSO_WIN32)
+ 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/Cryptlib/OpenSSL/crypto/dso/dso_vms.c b/Cryptlib/OpenSSL/crypto/dso/dso_vms.c
new file mode 100644
index 00000000..1efd84b9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_vms.c
@@ -0,0 +1,547 @@
+/* dso_vms.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#ifndef OPENSSL_SYS_VMS
+DSO_METHOD *DSO_METHOD_vms(void)
+{
+ return NULL;
+}
+#else
+
+# pragma message disable DOLLARID
+# include <rms.h>
+# include <lib$routines.h>
+# include <stsdef.h>
+# include <descrip.h>
+# include <starlet.h>
+# include "vms_rms.h"
+
+/* Some compiler options may mask the declaration of "_malloc32". */
+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+void *_malloc32(__size_t);
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+# endif /* __INITIAL_POINTER_SIZE && defined
+ * _ANSI_C_SOURCE */
+
+# pragma message disable DOLLARID
+
+static int vms_load(DSO *dso);
+static int vms_unload(DSO *dso);
+static void *vms_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
+# if 0
+static int vms_unbind_var(DSO *dso, char *symname, void *symptr);
+static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int vms_init(DSO *dso);
+static int vms_finish(DSO *dso);
+static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
+# endif
+static char *vms_name_converter(DSO *dso, const char *filename);
+static char *vms_merger(DSO *dso, const char *filespec1,
+ const char *filespec2);
+
+static DSO_METHOD dso_meth_vms = {
+ "OpenSSL 'VMS' shared library method",
+ vms_load,
+ NULL, /* unload */
+ vms_bind_var,
+ vms_bind_func,
+/* For now, "unbind" doesn't exist */
+# if 0
+ NULL, /* unbind_var */
+ NULL, /* unbind_func */
+# endif
+ NULL, /* ctrl */
+ vms_name_converter,
+ vms_merger,
+ NULL, /* init */
+ NULL /* finish */
+};
+
+/*
+ * On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends
+ * on the reference to the file name being the same for all calls regarding
+ * one shared image, so we'll just store it in an instance of the following
+ * structure and put a pointer to that instance in the meth_data stack.
+ */
+typedef struct dso_internal_st {
+ /*
+ * This should contain the name only, no directory, no extension, nothing
+ * but a name.
+ */
+ struct dsc$descriptor_s filename_dsc;
+ char filename[NAMX_MAXRSS + 1];
+ /*
+ * This contains whatever is not in filename, if needed. Normally not
+ * defined.
+ */
+ struct dsc$descriptor_s imagename_dsc;
+ char imagename[NAMX_MAXRSS + 1];
+} DSO_VMS_INTERNAL;
+
+DSO_METHOD *DSO_METHOD_vms(void)
+{
+ return (&dso_meth_vms);
+}
+
+static int vms_load(DSO *dso)
+{
+ void *ptr = NULL;
+ /* See applicable comments in dso_dl.c */
+ char *filename = DSO_convert_filename(dso, NULL);
+
+/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
+# if __INITIAL_POINTER_SIZE == 64
+# define DSO_MALLOC _malloc32
+# pragma pointer_size save
+# pragma pointer_size 32
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define DSO_MALLOC OPENSSL_malloc
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ DSO_VMS_INTERNAL *p = NULL;
+
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+
+ const char *sp1, *sp2; /* Search result */
+ const char *ext = NULL; /* possible extension to add */
+
+ if (filename == NULL) {
+ DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME);
+ goto err;
+ }
+
+ /*-
+ * A file specification may look like this:
+ *
+ * node::dev:[dir-spec]name.type;ver
+ *
+ * or (for compatibility with TOPS-20):
+ *
+ * node::dev:<dir-spec>name.type;ver
+ *
+ * and the dir-spec uses '.' as separator. Also, a dir-spec
+ * may consist of several parts, with mixed use of [] and <>:
+ *
+ * [dir1.]<dir2>
+ *
+ * We need to split the file specification into the name and
+ * the rest (both before and after the name itself).
+ */
+ /*
+ * Start with trying to find the end of a dir-spec, and save the position
+ * of the byte after in sp1
+ */
+ sp1 = strrchr(filename, ']');
+ sp2 = strrchr(filename, '>');
+ if (sp1 == NULL)
+ sp1 = sp2;
+ if (sp2 != NULL && sp2 > sp1)
+ sp1 = sp2;
+ if (sp1 == NULL)
+ sp1 = strrchr(filename, ':');
+ if (sp1 == NULL)
+ sp1 = filename;
+ else
+ sp1++; /* The byte after the found character */
+ /* Now, let's see if there's a type, and save the position in sp2 */
+ sp2 = strchr(sp1, '.');
+ /*
+ * If there is a period and the next character is a semi-colon,
+ * we need to add an extension
+ */
+ if (sp2 != NULL && sp2[1] == ';')
+ ext = ".EXE";
+ /*
+ * If we found it, that's where we'll cut. Otherwise, look for a version
+ * number and save the position in sp2
+ */
+ if (sp2 == NULL) {
+ sp2 = strchr(sp1, ';');
+ ext = ".EXE";
+ }
+ /*
+ * If there was still nothing to find, set sp2 to point at the end of the
+ * string
+ */
+ if (sp2 == NULL)
+ sp2 = sp1 + strlen(sp1);
+
+ /* Check that we won't get buffer overflows */
+ if (sp2 - sp1 > FILENAME_MAX
+ || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) {
+ DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG);
+ goto err;
+ }
+
+ p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL));
+ if (p == NULL) {
+ DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ strncpy(p->filename, sp1, sp2 - sp1);
+ p->filename[sp2 - sp1] = '\0';
+
+ strncpy(p->imagename, filename, sp1 - filename);
+ p->imagename[sp1 - filename] = '\0';
+ if (ext) {
+ strcat(p->imagename, ext);
+ if (*sp2 == '.')
+ sp2++;
+ }
+ strcat(p->imagename, sp2);
+
+ p->filename_dsc.dsc$w_length = strlen(p->filename);
+ p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
+ p->filename_dsc.dsc$a_pointer = p->filename;
+ p->imagename_dsc.dsc$w_length = strlen(p->imagename);
+ p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
+ p->imagename_dsc.dsc$a_pointer = p->imagename;
+
+ if (!sk_void_push(dso->meth_data, (char *)p)) {
+ DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR);
+ goto err;
+ }
+
+ /* Success (for now, we lie. We actually do not know...) */
+ dso->loaded_filename = filename;
+ return (1);
+ err:
+ /* Cleanup! */
+ if (p != NULL)
+ OPENSSL_free(p);
+ if (filename != NULL)
+ OPENSSL_free(filename);
+ return (0);
+}
+
+/*
+ * Note that this doesn't actually unload the shared image, as there is no
+ * such thing in VMS. Next time it get loaded again, a new copy will
+ * actually be loaded.
+ */
+static int vms_unload(DSO *dso)
+{
+ DSO_VMS_INTERNAL *p;
+ if (dso == NULL) {
+ DSOerr(DSO_F_VMS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (sk_void_num(dso->meth_data) < 1)
+ return (1);
+ p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
+ if (p == NULL) {
+ DSOerr(DSO_F_VMS_UNLOAD, DSO_R_NULL_HANDLE);
+ return (0);
+ }
+ /* Cleanup */
+ OPENSSL_free(p);
+ return (1);
+}
+
+/*
+ * We must do this in a separate function because of the way the exception
+ * handler works (it makes this function return
+ */
+static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
+ struct dsc$descriptor_s *symname_dsc, void **sym,
+ unsigned long flags)
+{
+ /*
+ * Make sure that signals are caught and returned instead of aborting the
+ * program. The exception handler gets unestablished automatically on
+ * return from this function.
+ */
+ lib$establish(lib$sig_to_ret);
+
+ if (ptr->imagename_dsc.dsc$w_length)
+ return lib$find_image_symbol(&ptr->filename_dsc,
+ symname_dsc, sym,
+ &ptr->imagename_dsc, flags);
+ else
+ return lib$find_image_symbol(&ptr->filename_dsc,
+ symname_dsc, sym, 0, flags);
+}
+
+void vms_bind_sym(DSO *dso, const char *symname, void **sym)
+{
+ DSO_VMS_INTERNAL *ptr;
+ int status;
+# if 0
+ int flags = (1 << 4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't
+ * defined in VMS older than 7.0 or so */
+# else
+ int flags = 0;
+# endif
+ struct dsc$descriptor_s symname_dsc;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+# define SYMNAME symname_32p
+# pragma pointer_size save
+# pragma pointer_size 32
+ char *symname_32p;
+# pragma pointer_size restore
+ char symname_32[NAMX_MAXRSS + 1];
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define SYMNAME ((char *) symname)
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ *sym = NULL;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_VMS_BIND_SYM, ERR_R_PASSED_NULL_PARAMETER);
+ return;
+ }
+# if __INITIAL_POINTER_SIZE == 64
+ /* Copy the symbol name to storage with a 32-bit pointer. */
+ symname_32p = symname_32;
+ strcpy(symname_32p, symname);
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ symname_dsc.dsc$w_length = strlen(SYMNAME);
+ symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ symname_dsc.dsc$b_class = DSC$K_CLASS_S;
+ symname_dsc.dsc$a_pointer = SYMNAME;
+
+ if (sk_void_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_STACK_ERROR);
+ return;
+ }
+ ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
+ sk_void_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_NULL_HANDLE);
+ return;
+ }
+
+ if (dso->flags & DSO_FLAG_UPCASE_SYMBOL)
+ flags = 0;
+
+ status = do_find_symbol(ptr, &symname_dsc, sym, flags);
+
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ unsigned short length;
+ char errstring[257];
+ struct dsc$descriptor_s errstring_dsc;
+
+ errstring_dsc.dsc$w_length = sizeof(errstring);
+ errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+ errstring_dsc.dsc$a_pointer = errstring;
+
+ *sym = NULL;
+
+ status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status))
+ lib$signal(status); /* This is really bad. Abort! */
+ else {
+ errstring[length] = '\0';
+
+ DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_SYM_FAILURE);
+ if (ptr->imagename_dsc.dsc$w_length)
+ ERR_add_error_data(9,
+ "Symbol ", symname,
+ " in ", ptr->filename,
+ " (", ptr->imagename, ")",
+ ": ", errstring);
+ else
+ ERR_add_error_data(6,
+ "Symbol ", symname,
+ " in ", ptr->filename, ": ", errstring);
+ }
+ return;
+ }
+ return;
+}
+
+static void *vms_bind_var(DSO *dso, const char *symname)
+{
+ void *sym = 0;
+ vms_bind_sym(dso, symname, &sym);
+ return sym;
+}
+
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
+{
+ DSO_FUNC_TYPE sym = 0;
+ vms_bind_sym(dso, symname, (void **)&sym);
+ return sym;
+}
+
+static char *vms_merger(DSO *dso, const char *filespec1,
+ const char *filespec2)
+{
+ int status;
+ int filespec1len, filespec2len;
+ struct FAB fab;
+ struct NAMX_STRUCT nam;
+ char esa[NAMX_MAXRSS + 1];
+ char *merged;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+# define FILESPEC1 filespec1_32p;
+# define FILESPEC2 filespec2_32p;
+# pragma pointer_size save
+# pragma pointer_size 32
+ char *filespec1_32p;
+ char *filespec2_32p;
+# pragma pointer_size restore
+ char filespec1_32[NAMX_MAXRSS + 1];
+ char filespec2_32[NAMX_MAXRSS + 1];
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define FILESPEC1 ((char *) filespec1)
+# define FILESPEC2 ((char *) filespec2)
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ if (!filespec1)
+ filespec1 = "";
+ if (!filespec2)
+ filespec2 = "";
+ filespec1len = strlen(filespec1);
+ filespec2len = strlen(filespec2);
+
+# if __INITIAL_POINTER_SIZE == 64
+ /* Copy the file names to storage with a 32-bit pointer. */
+ filespec1_32p = filespec1_32;
+ filespec2_32p = filespec2_32;
+ strcpy(filespec1_32p, filespec1);
+ strcpy(filespec2_32p, filespec2);
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ fab = cc$rms_fab;
+ nam = CC_RMS_NAMX;
+
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len;
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len;
+ NAMX_DNA_FNA_SET(fab)
+
+ nam.NAMX_ESA = esa;
+ nam.NAMX_ESS = NAMX_MAXRSS;
+ nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
+ SET_NAMX_NO_SHORT_UPCASE(nam);
+
+ fab.FAB_NAMX = &nam;
+
+ status = sys$parse(&fab, 0, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ unsigned short length;
+ char errstring[257];
+ struct dsc$descriptor_s errstring_dsc;
+
+ errstring_dsc.dsc$w_length = sizeof(errstring);
+ errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+ errstring_dsc.dsc$a_pointer = errstring;
+
+ status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status))
+ lib$signal(status); /* This is really bad. Abort! */
+ else {
+ errstring[length] = '\0';
+
+ DSOerr(DSO_F_VMS_MERGER, DSO_R_FAILURE);
+ ERR_add_error_data(7,
+ "filespec \"", filespec1, "\", ",
+ "defaults \"", filespec2, "\": ", errstring);
+ }
+ return (NULL);
+ }
+
+ merged = OPENSSL_malloc(nam.NAMX_ESL + 1);
+ if (!merged)
+ goto malloc_err;
+ strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL);
+ merged[nam.NAMX_ESL] = '\0';
+ return (merged);
+ malloc_err:
+ DSOerr(DSO_F_VMS_MERGER, ERR_R_MALLOC_FAILURE);
+}
+
+static char *vms_name_converter(DSO *dso, const char *filename)
+{
+ int len = strlen(filename);
+ char *not_translated = OPENSSL_malloc(len + 1);
+ if (not_translated)
+ strcpy(not_translated, filename);
+ return (not_translated);
+}
+
+#endif /* OPENSSL_SYS_VMS */
diff --git a/Cryptlib/OpenSSL/crypto/dso/dso_win32.c b/Cryptlib/OpenSSL/crypto/dso/dso_win32.c
new file mode 100644
index 00000000..706e754a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/dso/dso_win32.c
@@ -0,0 +1,788 @@
+/* dso_win32.c */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#if !defined(DSO_WIN32)
+DSO_METHOD *DSO_METHOD_win32(void)
+{
+ return NULL;
+}
+#else
+
+# ifdef _WIN32_WCE
+# if _WIN32_WCE < 300
+static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName)
+{
+ WCHAR lpProcNameW[64];
+ int i;
+
+ for (i = 0; lpProcName[i] && i < 64; i++)
+ lpProcNameW[i] = (WCHAR)lpProcName[i];
+ if (i == 64)
+ return NULL;
+ lpProcNameW[i] = 0;
+
+ return GetProcAddressW(hModule, lpProcNameW);
+}
+# endif
+# undef GetProcAddress
+# define GetProcAddress GetProcAddressA
+
+static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
+{
+ WCHAR *fnamw;
+ size_t len_0 = strlen(lpLibFileName) + 1, i;
+
+# ifdef _MSC_VER
+ fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR));
+# else
+ fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
+# endif
+ if (fnamw == NULL) {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+# if defined(_WIN32_WCE) && _WIN32_WCE>=101
+ if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0))
+# endif
+ for (i = 0; i < len_0; i++)
+ fnamw[i] = (WCHAR)lpLibFileName[i];
+
+ return LoadLibraryW(fnamw);
+}
+# endif
+
+/* Part of the hack in "win32_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int win32_load(DSO *dso);
+static int win32_unload(DSO *dso);
+static void *win32_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
+# if 0
+static int win32_unbind_var(DSO *dso, char *symname, void *symptr);
+static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int win32_init(DSO *dso);
+static int win32_finish(DSO *dso);
+static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
+# endif
+static char *win32_name_converter(DSO *dso, const char *filename);
+static char *win32_merger(DSO *dso, const char *filespec1,
+ const char *filespec2);
+static int win32_pathbyaddr(void *addr, char *path, int sz);
+static void *win32_globallookup(const char *name);
+
+static const char *openssl_strnchr(const char *string, int c, size_t len);
+
+static DSO_METHOD dso_meth_win32 = {
+ "OpenSSL 'win32' shared library method",
+ win32_load,
+ win32_unload,
+ win32_bind_var,
+ win32_bind_func,
+/* For now, "unbind" doesn't exist */
+# if 0
+ NULL, /* unbind_var */
+ NULL, /* unbind_func */
+# endif
+ NULL, /* ctrl */
+ win32_name_converter,
+ win32_merger,
+ NULL, /* init */
+ NULL, /* finish */
+ win32_pathbyaddr,
+ win32_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_win32(void)
+{
+ return (&dso_meth_win32);
+}
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to
+ * the handle (HINSTANCE) returned from LoadLibrary(), and copied.
+ */
+
+static int win32_load(DSO *dso)
+{
+ HINSTANCE h = NULL, *p = NULL;
+ /* See applicable comments from dso_dl.c */
+ char *filename = DSO_convert_filename(dso, NULL);
+
+ if (filename == NULL) {
+ DSOerr(DSO_F_WIN32_LOAD, DSO_R_NO_FILENAME);
+ goto err;
+ }
+ h = LoadLibraryA(filename);
+ if (h == NULL) {
+ DSOerr(DSO_F_WIN32_LOAD, DSO_R_LOAD_FAILED);
+ ERR_add_error_data(3, "filename(", filename, ")");
+ goto err;
+ }
+ p = (HINSTANCE *) OPENSSL_malloc(sizeof(HINSTANCE));
+ if (p == NULL) {
+ DSOerr(DSO_F_WIN32_LOAD, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *p = h;
+ if (!sk_void_push(dso->meth_data, p)) {
+ DSOerr(DSO_F_WIN32_LOAD, DSO_R_STACK_ERROR);
+ goto err;
+ }
+ /* Success */
+ dso->loaded_filename = filename;
+ return (1);
+ err:
+ /* Cleanup ! */
+ if (filename != NULL)
+ OPENSSL_free(filename);
+ if (p != NULL)
+ OPENSSL_free(p);
+ if (h != NULL)
+ FreeLibrary(h);
+ return (0);
+}
+
+static int win32_unload(DSO *dso)
+{
+ HINSTANCE *p;
+ if (dso == NULL) {
+ DSOerr(DSO_F_WIN32_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (sk_void_num(dso->meth_data) < 1)
+ return (1);
+ p = sk_void_pop(dso->meth_data);
+ if (p == NULL) {
+ DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_NULL_HANDLE);
+ return (0);
+ }
+ if (!FreeLibrary(*p)) {
+ DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_UNLOAD_FAILED);
+ /*
+ * We should push the value back onto the stack in case of a retry.
+ */
+ sk_void_push(dso->meth_data, p);
+ return (0);
+ }
+ /* Cleanup */
+ OPENSSL_free(p);
+ return (1);
+}
+
+/*
+ * Using GetProcAddress for variables? TODO: Check this out in the Win32 API
+ * docs, there's probably a variant for variables.
+ */
+static void *win32_bind_var(DSO *dso, const char *symname)
+{
+ HINSTANCE *ptr;
+ void *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_WIN32_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_void_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_NULL_HANDLE);
+ return (NULL);
+ }
+ sym = GetProcAddress(*ptr, symname);
+ if (sym == NULL) {
+ DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(3, "symname(", symname, ")");
+ return (NULL);
+ }
+ return (sym);
+}
+
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
+{
+ HINSTANCE *ptr;
+ void *sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ DSOerr(DSO_F_WIN32_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (sk_void_num(dso->meth_data) < 1) {
+ DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_STACK_ERROR);
+ return (NULL);
+ }
+ ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_NULL_HANDLE);
+ return (NULL);
+ }
+ sym = GetProcAddress(*ptr, symname);
+ if (sym == NULL) {
+ DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_SYM_FAILURE);
+ ERR_add_error_data(3, "symname(", symname, ")");
+ return (NULL);
+ }
+ return ((DSO_FUNC_TYPE)sym);
+}
+
+struct file_st {
+ const char *node;
+ int nodelen;
+ const char *device;
+ int devicelen;
+ const char *predir;
+ int predirlen;
+ const char *dir;
+ int dirlen;
+ const char *file;
+ int filelen;
+};
+
+static struct file_st *win32_splitter(DSO *dso, const char *filename,
+ int assume_last_is_dir)
+{
+ struct file_st *result = NULL;
+ enum { IN_NODE, IN_DEVICE, IN_FILE } position;
+ const char *start = filename;
+ char last;
+
+ if (!filename) {
+ DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_NO_FILENAME);
+ /*
+ * goto err;
+ */
+ return (NULL);
+ }
+
+ result = OPENSSL_malloc(sizeof(struct file_st));
+ if (result == NULL) {
+ DSOerr(DSO_F_WIN32_SPLITTER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ memset(result, 0, sizeof(struct file_st));
+ position = IN_DEVICE;
+
+ if ((filename[0] == '\\' && filename[1] == '\\')
+ || (filename[0] == '/' && filename[1] == '/')) {
+ position = IN_NODE;
+ filename += 2;
+ start = filename;
+ result->node = start;
+ }
+
+ do {
+ last = filename[0];
+ switch (last) {
+ case ':':
+ if (position != IN_DEVICE) {
+ DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_INCORRECT_FILE_SYNTAX);
+ /*
+ * goto err;
+ */
+ OPENSSL_free(result);
+ return (NULL);
+ }
+ result->device = start;
+ result->devicelen = (int)(filename - start);
+ position = IN_FILE;
+ start = ++filename;
+ result->dir = start;
+ break;
+ case '\\':
+ case '/':
+ if (position == IN_NODE) {
+ result->nodelen = (int)(filename - start);
+ position = IN_FILE;
+ start = ++filename;
+ result->dir = start;
+ } else if (position == IN_DEVICE) {
+ position = IN_FILE;
+ filename++;
+ result->dir = start;
+ result->dirlen = (int)(filename - start);
+ start = filename;
+ } else {
+ filename++;
+ result->dirlen += (int)(filename - start);
+ start = filename;
+ }
+ break;
+ case '\0':
+ if (position == IN_NODE) {
+ result->nodelen = (int)(filename - start);
+ } else {
+ if (filename - start > 0) {
+ if (assume_last_is_dir) {
+ if (position == IN_DEVICE) {
+ result->dir = start;
+ result->dirlen = 0;
+ }
+ result->dirlen += (int)(filename - start);
+ } else {
+ result->file = start;
+ result->filelen = (int)(filename - start);
+ }
+ }
+ }
+ break;
+ default:
+ filename++;
+ break;
+ }
+ }
+ while (last);
+
+ if (!result->nodelen)
+ result->node = NULL;
+ if (!result->devicelen)
+ result->device = NULL;
+ if (!result->dirlen)
+ result->dir = NULL;
+ if (!result->filelen)
+ result->file = NULL;
+
+ return (result);
+}
+
+static char *win32_joiner(DSO *dso, const struct file_st *file_split)
+{
+ int len = 0, offset = 0;
+ char *result = NULL;
+ const char *start;
+
+ if (!file_split) {
+ DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (file_split->node) {
+ len += 2 + file_split->nodelen; /* 2 for starting \\ */
+ if (file_split->predir || file_split->dir || file_split->file)
+ len++; /* 1 for ending \ */
+ } else if (file_split->device) {
+ len += file_split->devicelen + 1; /* 1 for ending : */
+ }
+ len += file_split->predirlen;
+ if (file_split->predir && (file_split->dir || file_split->file)) {
+ len++; /* 1 for ending \ */
+ }
+ len += file_split->dirlen;
+ if (file_split->dir && file_split->file) {
+ len++; /* 1 for ending \ */
+ }
+ len += file_split->filelen;
+
+ if (!len) {
+ DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
+ return (NULL);
+ }
+
+ result = OPENSSL_malloc(len + 1);
+ if (!result) {
+ DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ if (file_split->node) {
+ strcpy(&result[offset], "\\\\");
+ offset += 2;
+ strncpy(&result[offset], file_split->node, file_split->nodelen);
+ offset += file_split->nodelen;
+ if (file_split->predir || file_split->dir || file_split->file) {
+ result[offset] = '\\';
+ offset++;
+ }
+ } else if (file_split->device) {
+ strncpy(&result[offset], file_split->device, file_split->devicelen);
+ offset += file_split->devicelen;
+ result[offset] = ':';
+ offset++;
+ }
+ start = file_split->predir;
+ while (file_split->predirlen > (start - file_split->predir)) {
+ const char *end = openssl_strnchr(start, '/',
+ file_split->predirlen - (start -
+ file_split->predir));
+ if (!end)
+ end = start
+ + file_split->predirlen - (start - file_split->predir);
+ strncpy(&result[offset], start, end - start);
+ offset += (int)(end - start);
+ result[offset] = '\\';
+ offset++;
+ start = end + 1;
+ }
+# if 0 /* Not needed, since the directory converter
+ * above already appeneded a backslash */
+ if (file_split->predir && (file_split->dir || file_split->file)) {
+ result[offset] = '\\';
+ offset++;
+ }
+# endif
+ start = file_split->dir;
+ while (file_split->dirlen > (start - file_split->dir)) {
+ const char *end = openssl_strnchr(start, '/',
+ file_split->dirlen - (start -
+ file_split->dir));
+ if (!end)
+ end = start + file_split->dirlen - (start - file_split->dir);
+ strncpy(&result[offset], start, end - start);
+ offset += (int)(end - start);
+ result[offset] = '\\';
+ offset++;
+ start = end + 1;
+ }
+# if 0 /* Not needed, since the directory converter
+ * above already appeneded a backslash */
+ if (file_split->dir && file_split->file) {
+ result[offset] = '\\';
+ offset++;
+ }
+# endif
+ strncpy(&result[offset], file_split->file, file_split->filelen);
+ offset += file_split->filelen;
+ result[offset] = '\0';
+ return (result);
+}
+
+static char *win32_merger(DSO *dso, const char *filespec1,
+ const char *filespec2)
+{
+ char *merged = NULL;
+ struct file_st *filespec1_split = NULL;
+ struct file_st *filespec2_split = NULL;
+
+ if (!filespec1 && !filespec2) {
+ DSOerr(DSO_F_WIN32_MERGER, ERR_R_PASSED_NULL_PARAMETER);
+ return (NULL);
+ }
+ if (!filespec2) {
+ merged = OPENSSL_malloc(strlen(filespec1) + 1);
+ if (!merged) {
+ DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec1);
+ } else if (!filespec1) {
+ merged = OPENSSL_malloc(strlen(filespec2) + 1);
+ if (!merged) {
+ DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ strcpy(merged, filespec2);
+ } else {
+ filespec1_split = win32_splitter(dso, filespec1, 0);
+ if (!filespec1_split) {
+ DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ filespec2_split = win32_splitter(dso, filespec2, 1);
+ if (!filespec2_split) {
+ DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(filespec1_split);
+ return (NULL);
+ }
+
+ /* Fill in into filespec1_split */
+ if (!filespec1_split->node && !filespec1_split->device) {
+ filespec1_split->node = filespec2_split->node;
+ filespec1_split->nodelen = filespec2_split->nodelen;
+ filespec1_split->device = filespec2_split->device;
+ filespec1_split->devicelen = filespec2_split->devicelen;
+ }
+ if (!filespec1_split->dir) {
+ filespec1_split->dir = filespec2_split->dir;
+ filespec1_split->dirlen = filespec2_split->dirlen;
+ } else if (filespec1_split->dir[0] != '\\'
+ && filespec1_split->dir[0] != '/') {
+ filespec1_split->predir = filespec2_split->dir;
+ filespec1_split->predirlen = filespec2_split->dirlen;
+ }
+ if (!filespec1_split->file) {
+ filespec1_split->file = filespec2_split->file;
+ filespec1_split->filelen = filespec2_split->filelen;
+ }
+
+ merged = win32_joiner(dso, filespec1_split);
+ }
+ OPENSSL_free(filespec1_split);
+ OPENSSL_free(filespec2_split);
+ return (merged);
+}
+
+static char *win32_name_converter(DSO *dso, const char *filename)
+{
+ char *translated;
+ int len, transform;
+
+ len = strlen(filename);
+ transform = ((strstr(filename, "/") == NULL) &&
+ (strstr(filename, "\\") == NULL) &&
+ (strstr(filename, ":") == NULL));
+ if (transform)
+ /* We will convert this to "%s.dll" */
+ translated = OPENSSL_malloc(len + 5);
+ else
+ /* We will simply duplicate filename */
+ translated = OPENSSL_malloc(len + 1);
+ if (translated == NULL) {
+ DSOerr(DSO_F_WIN32_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+ return (NULL);
+ }
+ if (transform)
+ sprintf(translated, "%s.dll", filename);
+ else
+ sprintf(translated, "%s", filename);
+ return (translated);
+}
+
+static const char *openssl_strnchr(const char *string, int c, size_t len)
+{
+ size_t i;
+ const char *p;
+ for (i = 0, p = string; i < len && *p; i++, p++) {
+ if (*p == c)
+ return p;
+ }
+ return NULL;
+}
+
+# include <tlhelp32.h>
+# ifdef _WIN32_WCE
+# define DLLNAME "TOOLHELP.DLL"
+# else
+# ifdef MODULEENTRY32
+# undef MODULEENTRY32 /* unmask the ASCII version! */
+# endif
+# define DLLNAME "KERNEL32.DLL"
+# endif
+
+typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD);
+typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE);
+typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *);
+
+static int win32_pathbyaddr(void *addr, char *path, int sz)
+{
+ HMODULE dll;
+ HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+ MODULEENTRY32 me32;
+ CREATETOOLHELP32SNAPSHOT create_snap;
+ CLOSETOOLHELP32SNAPSHOT close_snap;
+ MODULE32 module_first, module_next;
+
+ if (addr == NULL) {
+ union {
+ int (*f) (void *, char *, int);
+ void *p;
+ } t = {
+ win32_pathbyaddr
+ };
+ addr = t.p;
+ }
+
+ dll = LoadLibrary(TEXT(DLLNAME));
+ if (dll == NULL) {
+ DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+
+ create_snap = (CREATETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CreateToolhelp32Snapshot");
+ if (create_snap == NULL) {
+ FreeLibrary(dll);
+ DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+ /* We take the rest for granted... */
+# ifdef _WIN32_WCE
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CloseToolhelp32Snapshot");
+# else
+ close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
+# endif
+ module_first = (MODULE32) GetProcAddress(dll, "Module32First");
+ module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
+
+ hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
+ if (hModuleSnap == INVALID_HANDLE_VALUE) {
+ FreeLibrary(dll);
+ DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+
+ me32.dwSize = sizeof(me32);
+
+ if (!(*module_first) (hModuleSnap, &me32)) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_FAILURE);
+ return -1;
+ }
+
+ do {
+ if ((BYTE *) addr >= me32.modBaseAddr &&
+ (BYTE *) addr < me32.modBaseAddr + me32.modBaseSize) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+# ifdef _WIN32_WCE
+# if _WIN32_WCE >= 101
+ return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1,
+ path, sz, NULL, NULL);
+# else
+ {
+ int i, len = (int)wcslen(me32.szExePath);
+ if (sz <= 0)
+ return len + 1;
+ if (len >= sz)
+ len = sz - 1;
+ for (i = 0; i < len; i++)
+ path[i] = (char)me32.szExePath[i];
+ path[len++] = 0;
+ return len;
+ }
+# endif
+# else
+ {
+ int len = (int)strlen(me32.szExePath);
+ if (sz <= 0)
+ return len + 1;
+ if (len >= sz)
+ len = sz - 1;
+ memcpy(path, me32.szExePath, len);
+ path[len++] = 0;
+ return len;
+ }
+# endif
+ }
+ } while ((*module_next) (hModuleSnap, &me32));
+
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return 0;
+}
+
+static void *win32_globallookup(const char *name)
+{
+ HMODULE dll;
+ HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+ MODULEENTRY32 me32;
+ CREATETOOLHELP32SNAPSHOT create_snap;
+ CLOSETOOLHELP32SNAPSHOT close_snap;
+ MODULE32 module_first, module_next;
+ FARPROC ret = NULL;
+
+ dll = LoadLibrary(TEXT(DLLNAME));
+ if (dll == NULL) {
+ DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+
+ create_snap = (CREATETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CreateToolhelp32Snapshot");
+ if (create_snap == NULL) {
+ FreeLibrary(dll);
+ DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+ /* We take the rest for granted... */
+# ifdef _WIN32_WCE
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CloseToolhelp32Snapshot");
+# else
+ close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
+# endif
+ module_first = (MODULE32) GetProcAddress(dll, "Module32First");
+ module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
+
+ hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
+ if (hModuleSnap == INVALID_HANDLE_VALUE) {
+ FreeLibrary(dll);
+ DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+
+ me32.dwSize = sizeof(me32);
+
+ if (!(*module_first) (hModuleSnap, &me32)) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return NULL;
+ }
+
+ do {
+ if ((ret = GetProcAddress(me32.hModule, name))) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return ret;
+ }
+ } while ((*module_next) (hModuleSnap, &me32));
+
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return NULL;
+}
+#endif /* DSO_WIN32 */
diff --git a/Cryptlib/OpenSSL/crypto/ebcdic.c b/Cryptlib/OpenSSL/crypto/ebcdic.c
new file mode 100644
index 00000000..fd6df92b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ebcdic.c
@@ -0,0 +1,284 @@
+/* crypto/ebcdic.c */
+
+#ifndef CHARSET_EBCDIC
+
+# include <openssl/e_os2.h>
+# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) || defined(__clang__)
+static void *dummy = &dummy;
+# endif
+
+#else /* CHARSET_EBCDIC */
+
+# include "ebcdic.h"
+/*-
+ * Initial Port for Apache-1.3 by <Martin.Kraemer@Mch.SNI.De>
+ * Adapted for OpenSSL-0.9.4 by <Martin.Kraemer@Mch.SNI.De>
+ */
+
+# ifdef _OSD_POSIX
+/*
+ * "BS2000 OSD" is a POSIX subsystem on a main frame. It is made by Siemens
+ * AG, Germany, for their BS2000 mainframe machines. Within the POSIX
+ * subsystem, the same character set was chosen as in "native BS2000", namely
+ * EBCDIC. (EDF04)
+ *
+ * The name "ASCII" in these routines is misleading: actually, conversion is
+ * not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1; that means
+ * that (western european) national characters are preserved.
+ *
+ * This table is identical to the one used by rsh/rcp/ftp and other POSIX
+ * tools.
+ */
+
+/* Here's the bijective ebcdic-to-ascii table: */
+const unsigned char os_toascii[256] = {
+ /*
+ * 00
+ */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
+ 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+ /*
+ * 10
+ */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
+ 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+ /*
+ * 20
+ */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
+ /*
+ * 30
+ */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
+ /*
+ * 40
+ */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+ 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */
+ /*
+ * 50
+ */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+ 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /* &.........!$*);. */
+ /*
+ * 60
+ */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+ 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/
+ /*
+ * 70
+ */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+ 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* ..........:#@'=" */
+ /*
+ * 80
+ */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
+ /*
+ * 90
+ */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
+ /*
+ * a0
+ */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /* ..stuvwxyz...... */
+ /*
+ * b0
+ */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+ 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /* ...........[\].. */
+ /*
+ * c0
+ */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* .ABCDEFGHI...... */
+ /*
+ * d0
+ */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /* .JKLMNOPQR...... */
+ /*
+ * e0
+ */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* ..STUVWXYZ...... */
+ /*
+ * f0
+ */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /* 0123456789.{.}.~ */
+};
+
+/* The ascii-to-ebcdic table: */
+const unsigned char os_toebcdic[256] = {
+ /*
+ * 00
+ */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+ /*
+ * 10
+ */ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+ /*
+ * 20
+ */ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
+ /*
+ * 30
+ */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
+ /*
+ * 40
+ */ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
+ /*
+ * 50
+ */ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /* PQRSTUVWXYZ[\]^_ */
+ /*
+ * 60
+ */ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
+ /*
+ * 70
+ */ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /* pqrstuvwxyz{|}~. */
+ /*
+ * 80
+ */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
+ /*
+ * 90
+ */ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
+ 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /* ................ */
+ /*
+ * a0
+ */ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
+ 0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /* ................ */
+ /*
+ * b0
+ */ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+ 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
+ /*
+ * c0
+ */ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
+ /*
+ * d0
+ */ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+ 0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /* ................ */
+ /*
+ * e0
+ */ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
+ /*
+ * f0
+ */ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+ 0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
+};
+
+# else /*_OSD_POSIX*/
+
+/*
+ * This code does basic character mapping for IBM's TPF and OS/390 operating
+ * systems. It is a modified version of the BS2000 table.
+ *
+ * Bijective EBCDIC (character set IBM-1047) to US-ASCII table: This table is
+ * bijective - there are no ambigous or duplicate characters.
+ */
+const unsigned char os_toascii[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */
+ 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */
+ 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
+ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */
+ 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */
+ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */
+ 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
+ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */
+ 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
+ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */
+ 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
+ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */
+ 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
+ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */
+ 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
+ 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */
+ 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
+ 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */
+ 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */
+ 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */
+ 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
+ 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */
+ 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */
+ 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */
+};
+
+/*
+ * The US-ASCII to EBCDIC (character set IBM-1047) table: This table is
+ * bijective (no ambiguous or duplicate characters)
+ */
+const unsigned char os_toebcdic[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */
+ 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */
+ 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
+ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */
+ 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */
+ 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */
+ 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */
+ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */
+ 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
+ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */
+ 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
+ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */
+ 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
+};
+# endif/*_OSD_POSIX*/
+
+/*
+ * Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
+ * dest and srce may be identical, or separate memory blocks, but should not
+ * overlap. These functions intentionally have an interface compatible to
+ * memcpy(3).
+ */
+
+void *ebcdic2ascii(void *dest, const void *srce, size_t count)
+{
+ unsigned char *udest = dest;
+ const unsigned char *usrce = srce;
+
+ while (count-- != 0) {
+ *udest++ = os_toascii[*usrce++];
+ }
+
+ return dest;
+}
+
+void *ascii2ebcdic(void *dest, const void *srce, size_t count)
+{
+ unsigned char *udest = dest;
+ const unsigned char *usrce = srce;
+
+ while (count-- != 0) {
+ *udest++ = os_toebcdic[*usrce++];
+ }
+
+ return dest;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/err/err.c b/Cryptlib/OpenSSL/crypto/err/err.c
new file mode 100644
index 00000000..e77d963b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/err/err.c
@@ -0,0 +1,1145 @@
+/* crypto/err/err.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-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 <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+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 { \
+ 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_STATE_free(ERR_STATE *s)
+{
+ int i;
+
+ if (s == NULL)
+ return;
+
+ for (i = 0; i < ERR_NUM_ERRORS; i++) {
+ err_clear_data(s, i);
+ }
+ OPENSSL_free(s);
+}
+
+void ERR_load_ERR_strings(void)
+{
+ err_fns_check();
+#ifndef OPENSSL_NO_ERR
+ 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
+}
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str)
+{
+ while (str->error) {
+ 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)
+{
+ ERR_STATE *es;
+
+#ifdef _OSD_POSIX
+ /*
+ * In the BS2000-OSD POSIX subsystem, the compiler generates path names
+ * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to
+ * something sensible. @@@ We shouldn't modify a const string, though.
+ */
+ if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) {
+ char *end;
+
+ /* Skip the "*POSIX(" prefix */
+ file += sizeof("*POSIX(") - 1;
+ end = &file[strlen(file) - 1];
+ if (*end == ')')
+ *end = '\0';
+ /* Optional: use the basename of the path only. */
+ if ((end = strrchr(file, '/')) != NULL)
+ file = &end[1];
+ }
+#endif
+ es = ERR_get_state();
+
+ es->top = (es->top + 1) % ERR_NUM_ERRORS;
+ if (es->top == es->bottom)
+ es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
+ es->err_flags[es->top] = 0;
+ es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
+ es->err_file[es->top] = file;
+ es->err_line[es->top] = line;
+ err_clear_data(es, es->top);
+}
+
+void ERR_clear_error(void)
+{
+ int i;
+ ERR_STATE *es;
+
+ es = ERR_get_state();
+
+ for (i = 0; i < ERR_NUM_ERRORS; i++) {
+ err_clear(es, i);
+ }
+ es->top = es->bottom = 0;
+}
+
+unsigned long ERR_get_error(void)
+{
+ return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
+}
+
+unsigned long ERR_get_error_line(const char **file, int *line)
+{
+ return (get_error_values(1, 0, file, line, NULL, NULL));
+}
+
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+ const char **data, int *flags)
+{
+ return (get_error_values(1, 0, file, line, data, flags));
+}
+
+unsigned long ERR_peek_error(void)
+{
+ return (get_error_values(0, 0, NULL, NULL, NULL, NULL));
+}
+
+unsigned long ERR_peek_error_line(const char **file, int *line)
+{
+ return (get_error_values(0, 0, file, line, NULL, NULL));
+}
+
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+ const char **data, int *flags)
+{
+ return (get_error_values(0, 0, file, line, data, flags));
+}
+
+unsigned long ERR_peek_last_error(void)
+{
+ return (get_error_values(0, 1, NULL, NULL, NULL, NULL));
+}
+
+unsigned long ERR_peek_last_error_line(const char **file, int *line)
+{
+ return (get_error_values(0, 1, file, line, NULL, NULL));
+}
+
+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+ const char **data, int *flags)
+{
+ return (get_error_values(0, 1, file, line, data, flags));
+}
+
+static unsigned long get_error_values(int inc, int top, const char **file,
+ int *line, const char **data,
+ int *flags)
+{
+ int i = 0;
+ ERR_STATE *es;
+ unsigned long ret;
+
+ es = ERR_get_state();
+
+ if (inc && top) {
+ if (file)
+ *file = "";
+ if (line)
+ *line = 0;
+ if (data)
+ *data = "";
+ if (flags)
+ *flags = 0;
+
+ return ERR_R_INTERNAL_ERROR;
+ }
+
+ if (es->bottom == es->top)
+ return 0;
+ if (top)
+ i = es->top; /* last error */
+ else
+ i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
+
+ ret = es->err_buffer[i];
+ if (inc) {
+ es->bottom = i;
+ es->err_buffer[i] = 0;
+ }
+
+ if ((file != NULL) && (line != NULL)) {
+ if (es->err_file[i] == NULL) {
+ *file = "NA";
+ if (line != NULL)
+ *line = 0;
+ } else {
+ *file = es->err_file[i];
+ if (line != NULL)
+ *line = es->err_line[i];
+ }
+ }
+
+ if (data == NULL) {
+ if (inc) {
+ err_clear_data(es, i);
+ }
+ } else {
+ if (es->err_data[i] == NULL) {
+ *data = "";
+ if (flags != NULL)
+ *flags = 0;
+ } else {
+ *data = es->err_data[i];
+ if (flags != NULL)
+ *flags = es->err_data_flags[i];
+ }
+ }
+ 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; i < ERR_NUM_ERRORS; i++) {
+ ret->err_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;
+ int i;
+
+ es = ERR_get_state();
+
+ i = es->top;
+ if (i == 0)
+ i = ERR_NUM_ERRORS - 1;
+
+ err_clear_data(es, i);
+ es->err_data[i] = data;
+ es->err_data_flags[i] = flags;
+}
+
+void ERR_add_error_data(int num, ...)
+{
+ va_list args;
+ va_start(args, num);
+ ERR_add_error_vdata(num, args);
+ va_end(args);
+}
+
+void ERR_add_error_vdata(int num, va_list args)
+{
+ int i, n, s;
+ char *str, *p, *a;
+
+ s = 80;
+ str = OPENSSL_malloc(s + 1);
+ if (str == NULL)
+ return;
+ str[0] = '\0';
+
+ n = 0;
+ for (i = 0; i < num; i++) {
+ a = va_arg(args, char *);
+ /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
+ if (a != NULL) {
+ n += strlen(a);
+ if (n > s) {
+ s = n + 20;
+ p = OPENSSL_realloc(str, s + 1);
+ if (p == NULL) {
+ OPENSSL_free(str);
+ return;
+ } else
+ str = p;
+ }
+ BUF_strlcat(str, a, (size_t)s + 1);
+ }
+ }
+ ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING);
+}
+
+int ERR_set_mark(void)
+{
+ ERR_STATE *es;
+
+ es = ERR_get_state();
+
+ if (es->bottom == es->top)
+ return 0;
+ es->err_flags[es->top] |= ERR_FLAG_MARK;
+ return 1;
+}
+
+int ERR_pop_to_mark(void)
+{
+ ERR_STATE *es;
+
+ es = ERR_get_state();
+
+ while (es->bottom != es->top
+ && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
+ err_clear(es, es->top);
+ es->top -= 1;
+ if (es->top == -1)
+ es->top = ERR_NUM_ERRORS - 1;
+ }
+
+ if (es->bottom == es->top)
+ return 0;
+ es->err_flags[es->top] &= ~ERR_FLAG_MARK;
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/err/err_all.c b/Cryptlib/OpenSSL/crypto/err/err_all.c
new file mode 100644
index 00000000..d7575a7e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/err/err_all.c
@@ -0,0 +1,168 @@
+/* crypto/err/err_all.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 <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_EC
+# include <openssl/ec.h>
+#endif
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
+# include <openssl/comp.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_ECDSA
+# include <openssl/ecdsa.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+# include <openssl/ecdh.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/pem2.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/conf.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include <openssl/dso.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include <openssl/ui.h>
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/ts.h>
+#ifndef OPENSSL_NO_CMS
+# include <openssl/cms.h>
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# include <openssl/jpake.h>
+#endif
+
+void ERR_load_crypto_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ ERR_load_ERR_strings(); /* include error strings for SYSerr */
+ ERR_load_BN_strings();
+# ifndef OPENSSL_NO_RSA
+ ERR_load_RSA_strings();
+# endif
+# ifndef OPENSSL_NO_DH
+ ERR_load_DH_strings();
+# endif
+ ERR_load_EVP_strings();
+ ERR_load_BUF_strings();
+ ERR_load_OBJ_strings();
+ ERR_load_PEM_strings();
+# ifndef OPENSSL_NO_DSA
+ ERR_load_DSA_strings();
+# endif
+ ERR_load_X509_strings();
+ ERR_load_ASN1_strings();
+ ERR_load_CONF_strings();
+ ERR_load_CRYPTO_strings();
+# ifndef OPENSSL_NO_COMP
+ ERR_load_COMP_strings();
+# endif
+# ifndef OPENSSL_NO_EC
+ ERR_load_EC_strings();
+# endif
+# ifndef OPENSSL_NO_ECDSA
+ ERR_load_ECDSA_strings();
+# endif
+# ifndef OPENSSL_NO_ECDH
+ ERR_load_ECDH_strings();
+# endif
+ /* skip ERR_load_SSL_strings() because it is not in this library */
+ ERR_load_BIO_strings();
+ ERR_load_PKCS7_strings();
+ ERR_load_X509V3_strings();
+ 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
+# ifndef OPENSSL_NO_JPAKE
+ ERR_load_JPAKE_strings();
+# endif
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/err/err_prn.c b/Cryptlib/OpenSSL/crypto/err/err_prn.c
new file mode 100644
index 00000000..6e352eff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/err/err_prn.c
@@ -0,0 +1,113 @@
+/* crypto/err/err_prn.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
+ void *u)
+{
+ unsigned long l;
+ char buf[256];
+ char buf2[4096];
+ const char *file, *data;
+ int line, flags;
+ unsigned long es;
+ CRYPTO_THREADID cur;
+
+ 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 : "");
+ 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)
+{
+ 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)
+{
+ ERR_print_errors_cb(print_fp, fp);
+}
+#endif
+
+static int print_bio(const char *str, size_t len, void *bp)
+{
+ return BIO_write((BIO *)bp, str, len);
+}
+
+void ERR_print_errors(BIO *bp)
+{
+ ERR_print_errors_cb(print_bio, bp);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_b64.c b/Cryptlib/OpenSSL/crypto/evp/bio_b64.c
new file mode 100644
index 00000000..538b5202
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_b64.c
@@ -0,0 +1,573 @@
+/* crypto/evp/bio_b64.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+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_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);
+static int b64_free(BIO *data);
+static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define B64_BLOCK_SIZE 1024
+#define B64_BLOCK_SIZE2 768
+#define B64_NONE 0
+#define B64_ENCODE 1
+#define B64_DECODE 2
+
+typedef struct b64_struct {
+ /*
+ * BIO *bio; moved to the BIO structure
+ */
+ int buf_len;
+ int buf_off;
+ int tmp_len; /* used to find the start when decoding */
+ int tmp_nl; /* If true, scan until '\n' */
+ int encode;
+ int start; /* have we started decoding yet? */
+ int cont; /* <= 0 when finished */
+ EVP_ENCODE_CTX base64;
+ char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
+ char tmp[B64_BLOCK_SIZE];
+} BIO_B64_CTX;
+
+static BIO_METHOD methods_b64 = {
+ BIO_TYPE_BASE64, "base64 encoding",
+ b64_write,
+ b64_read,
+ b64_puts,
+ NULL, /* b64_gets, */
+ b64_ctrl,
+ b64_new,
+ b64_free,
+ b64_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_base64(void)
+{
+ return (&methods_b64);
+}
+
+static int b64_new(BIO *bi)
+{
+ BIO_B64_CTX *ctx;
+
+ ctx = (BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX));
+ if (ctx == NULL)
+ return (0);
+
+ ctx->buf_len = 0;
+ ctx->tmp_len = 0;
+ ctx->tmp_nl = 0;
+ ctx->buf_off = 0;
+ ctx->cont = 1;
+ ctx->start = 1;
+ ctx->encode = 0;
+
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ bi->num = 0;
+ return (1);
+}
+
+static int b64_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int b64_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+ BIO_B64_CTX *ctx;
+ unsigned char *p, *q;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_B64_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_DECODE) {
+ ctx->encode = B64_DECODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_DecodeInit(&(ctx->base64));
+ }
+
+ /* First check if there are bytes decoded/encoded */
+ if (ctx->buf_len > 0) {
+ 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));
+ memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+ ret = i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ }
+
+ /*
+ * At this point, we have room of outl bytes and an empty buffer, so we
+ * should read in some more.
+ */
+
+ ret_code = 0;
+ while (outl > 0) {
+ if (ctx->cont <= 0)
+ break;
+
+ i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
+ B64_BLOCK_SIZE - ctx->tmp_len);
+
+ if (i <= 0) {
+ ret_code = i;
+
+ /* Should we continue next time we are called? */
+ if (!BIO_should_retry(b->next_bio)) {
+ ctx->cont = i;
+ /* If buffer empty break */
+ if (ctx->tmp_len == 0)
+ break;
+ /* Fall through and process what we have */
+ else
+ i = 0;
+ }
+ /* else we retry and add more data to buffer */
+ else
+ break;
+ }
+ i += ctx->tmp_len;
+ ctx->tmp_len = i;
+
+ /*
+ * We need to scan, a line at a time until we have a valid line if we
+ * are starting.
+ */
+ if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
+ /* ctx->start=1; */
+ ctx->tmp_len = 0;
+ } else if (ctx->start) {
+ q = p = (unsigned char *)ctx->tmp;
+ num = 0;
+ for (j = 0; j < i; j++) {
+ if (*(q++) != '\n')
+ continue;
+
+ /*
+ * due to a previous very long line, we need to keep on
+ * scanning for a '\n' before we even start looking for
+ * base64 encoded stuff.
+ */
+ if (ctx->tmp_nl) {
+ p = q;
+ ctx->tmp_nl = 0;
+ continue;
+ }
+
+ k = EVP_DecodeUpdate(&(ctx->base64),
+ (unsigned char *)ctx->buf,
+ &num, p, q - p);
+ if ((k <= 0) && (num == 0) && (ctx->start))
+ EVP_DecodeInit(&ctx->base64);
+ else {
+ if (p != (unsigned char *)
+ &(ctx->tmp[0])) {
+ i -= (p - (unsigned char *)
+ &(ctx->tmp[0]));
+ for (x = 0; x < i; x++)
+ ctx->tmp[x] = p[x];
+ }
+ EVP_DecodeInit(&ctx->base64);
+ ctx->start = 0;
+ break;
+ }
+ p = q;
+ }
+
+ /* we fell off the end without starting */
+ if ((j == i) && (num == 0)) {
+ /*
+ * Is this is one long chunk?, if so, keep on reading until a
+ * new line.
+ */
+ if (p == (unsigned char *)&(ctx->tmp[0])) {
+ /* Check buffer full */
+ if (i == B64_BLOCK_SIZE) {
+ ctx->tmp_nl = 1;
+ ctx->tmp_len = 0;
+ }
+ } else if (p != q) { /* finished on a '\n' */
+ n = q - p;
+ for (ii = 0; ii < n; ii++)
+ ctx->tmp[ii] = p[ii];
+ ctx->tmp_len = n;
+ }
+ /* else finished on a '\n' */
+ continue;
+ } else {
+ ctx->tmp_len = 0;
+ }
+ } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
+ /*
+ * If buffer isn't full and we can retry then restart to read in
+ * more data.
+ */
+ continue;
+ }
+
+ if (BIO_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) {
+ if (ctx->tmp[jj - 1] == '=') {
+ z--;
+ if (ctx->tmp[jj - 2] == '=')
+ z--;
+ }
+ }
+ /*
+ * z is now number of output bytes and jj is the number consumed
+ */
+ if (jj != i) {
+ memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
+ ctx->tmp_len = i - jj;
+ }
+ ctx->buf_len = 0;
+ if (z > 0) {
+ ctx->buf_len = z;
+ }
+ i = z;
+ } else {
+ i = EVP_DecodeUpdate(&(ctx->base64),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)ctx->tmp, i);
+ ctx->tmp_len = 0;
+ }
+ ctx->buf_off = 0;
+ if (i < 0) {
+ ret_code = 0;
+ ctx->buf_len = 0;
+ break;
+ }
+
+ if (ctx->buf_len <= outl)
+ i = ctx->buf_len;
+ else
+ i = outl;
+
+ memcpy(out, ctx->buf, i);
+ ret += i;
+ ctx->buf_off = i;
+ if (ctx->buf_off == ctx->buf_len) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ outl -= i;
+ out += i;
+ }
+ /* BIO_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 = 0;
+ int n;
+ int i;
+ BIO_B64_CTX *ctx;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_ENCODE) {
+ ctx->encode = B64_ENCODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_EncodeInit(&(ctx->base64));
+ }
+
+ 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) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ 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 */
+ ctx->buf_off = 0;
+ ctx->buf_len = 0;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+
+ while (inl > 0) {
+ n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
+
+ if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+ if (ctx->tmp_len > 0) {
+ OPENSSL_assert(ctx->tmp_len <= 3);
+ n = 3 - ctx->tmp_len;
+ /*
+ * 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);
+ 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;
+ } else {
+ if (n < 3) {
+ memcpy(ctx->tmp, in, n);
+ ctx->tmp_len = n;
+ ret += n;
+ break;
+ }
+ n -= n % 3;
+ 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 {
+ 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;
+
+ ctx->buf_off = 0;
+ n = ctx->buf_len;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return ((ret == 0) ? i : ret);
+ }
+ 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;
+ }
+ return (ret);
+}
+
+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_B64_CTX *ctx;
+ long ret = 1;
+ int i;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->cont = 1;
+ ctx->start = 1;
+ ctx->encode = B64_NONE;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0)
+ ret = 1;
+ else
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_WPENDING: /* More to write in buffer */
+ 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))
+ ret = 1;
+ else if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ 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);
+ break;
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ again:
+ while (ctx->buf_len != ctx->buf_off) {
+ i = b64_write(b, NULL, 0);
+ if (i < 0)
+ return i;
+ }
+ if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+ if (ctx->tmp_len != 0) {
+ ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
+ (unsigned char *)ctx->tmp,
+ ctx->tmp_len);
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ goto again;
+ }
+ } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
+ ctx->buf_off = 0;
+ EVP_EncodeFinal(&(ctx->base64),
+ (unsigned char *)ctx->buf, &(ctx->buf_len));
+ /* push out the bytes */
+ goto again;
+ }
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_DUP:
+ break;
+ case BIO_CTRL_INFO:
+ case BIO_CTRL_GET:
+ case BIO_CTRL_SET:
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int b64_puts(BIO *b, const char *str)
+{
+ return b64_write(b, str, strlen(str));
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_enc.c b/Cryptlib/OpenSSL/crypto/evp/bio_enc.c
new file mode 100644
index 00000000..363e0246
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_enc.c
@@ -0,0 +1,428 @@
+/* crypto/evp/bio_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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+static int enc_write(BIO *h, const char *buf, int num);
+static int enc_read(BIO *h, char *buf, int size);
+/*
+ * static int enc_puts(BIO *h, const char *str);
+ */
+/*
+ * static int enc_gets(BIO *h, char *str, int size);
+ */
+static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int enc_new(BIO *h);
+static int enc_free(BIO *data);
+static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
+#define ENC_BLOCK_SIZE (1024*4)
+#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2)
+
+typedef struct enc_struct {
+ int buf_len;
+ int buf_off;
+ int cont; /* <= 0 when finished */
+ int finished;
+ int ok; /* bad decrypt */
+ EVP_CIPHER_CTX cipher;
+ /*
+ * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
+ * up to a block more data than is presented to it
+ */
+ char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
+} BIO_ENC_CTX;
+
+static BIO_METHOD methods_enc = {
+ BIO_TYPE_CIPHER, "cipher",
+ enc_write,
+ enc_read,
+ NULL, /* enc_puts, */
+ NULL, /* enc_gets, */
+ enc_ctrl,
+ enc_new,
+ enc_free,
+ enc_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_cipher(void)
+{
+ return (&methods_enc);
+}
+
+static int enc_new(BIO *bi)
+{
+ BIO_ENC_CTX *ctx;
+
+ ctx = (BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX));
+ if (ctx == NULL)
+ return (0);
+ EVP_CIPHER_CTX_init(&ctx->cipher);
+
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->cont = 1;
+ ctx->finished = 0;
+ ctx->ok = 1;
+
+ bi->init = 0;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int enc_free(BIO *a)
+{
+ BIO_ENC_CTX *b;
+
+ if (a == NULL)
+ return (0);
+ b = (BIO_ENC_CTX *)a->ptr;
+ EVP_CIPHER_CTX_cleanup(&(b->cipher));
+ OPENSSL_cleanse(a->ptr, sizeof(BIO_ENC_CTX));
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int enc_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, i;
+ BIO_ENC_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_ENC_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ /* First check if there are bytes decoded/encoded */
+ if (ctx->buf_len > 0) {
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+ ret = i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ }
+
+ /*
+ * At this point, we have room of outl bytes and an empty buffer, so we
+ * should read in some more.
+ */
+
+ while (outl > 0) {
+ if (ctx->cont <= 0)
+ break;
+
+ /*
+ * read in at IV offset, read the EVP_Cipher documentation about why
+ */
+ i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
+
+ if (i <= 0) {
+ /* Should be continue next time we are called? */
+ if (!BIO_should_retry(b->next_bio)) {
+ ctx->cont = i;
+ i = EVP_CipherFinal_ex(&(ctx->cipher),
+ (unsigned char *)ctx->buf,
+ &(ctx->buf_len));
+ ctx->ok = i;
+ ctx->buf_off = 0;
+ } else {
+ ret = (ret == 0) ? i : ret;
+ break;
+ }
+ } else {
+ EVP_CipherUpdate(&(ctx->cipher),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)&(ctx->buf[BUF_OFFSET]), i);
+ ctx->cont = 1;
+ /*
+ * Note: it is possible for EVP_CipherUpdate to decrypt zero
+ * bytes because this is or looks like the final block: if this
+ * happens we should retry and either read more data or decrypt
+ * the final block
+ */
+ if (ctx->buf_len == 0)
+ continue;
+ }
+
+ if (ctx->buf_len <= outl)
+ i = ctx->buf_len;
+ else
+ i = outl;
+ if (i <= 0)
+ break;
+ memcpy(out, ctx->buf, i);
+ ret += i;
+ ctx->buf_off = i;
+ outl -= i;
+ out += i;
+ }
+
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return ((ret == 0) ? ctx->cont : ret);
+}
+
+static int enc_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0, n, i;
+ BIO_ENC_CTX *ctx;
+
+ ctx = (BIO_ENC_CTX *)b->ptr;
+ ret = inl;
+
+ BIO_clear_retry_flags(b);
+ n = ctx->buf_len - ctx->buf_off;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return (i);
+ }
+ ctx->buf_off += i;
+ n -= i;
+ }
+ /* at this point all pending data has been written */
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+
+ ctx->buf_off = 0;
+ while (inl > 0) {
+ n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
+ EVP_CipherUpdate(&(ctx->cipher),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)in, n);
+ inl -= n;
+ in += n;
+
+ ctx->buf_off = 0;
+ n = ctx->buf_len;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return (ret == inl) ? i : ret - inl;
+ }
+ n -= i;
+ ctx->buf_off += i;
+ }
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ BIO_ENC_CTX *ctx, *dctx;
+ long ret = 1;
+ int i;
+ EVP_CIPHER_CTX **c_ctx;
+
+ ctx = (BIO_ENC_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->ok = 1;
+ ctx->finished = 0;
+ EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL,
+ ctx->cipher.encrypt);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0)
+ ret = 1;
+ else
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ again:
+ while (ctx->buf_len != ctx->buf_off) {
+ i = enc_write(b, NULL, 0);
+ if (i < 0)
+ return i;
+ }
+
+ if (!ctx->finished) {
+ ctx->finished = 1;
+ ctx->buf_off = 0;
+ ret = EVP_CipherFinal_ex(&(ctx->cipher),
+ (unsigned char *)ctx->buf,
+ &(ctx->buf_len));
+ ctx->ok = (int)ret;
+ if (ret <= 0)
+ break;
+
+ /* push out the bytes */
+ goto again;
+ }
+
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_C_GET_CIPHER_STATUS:
+ ret = (long)ctx->ok;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_C_GET_CIPHER_CTX:
+ c_ctx = (EVP_CIPHER_CTX **)ptr;
+ (*c_ctx) = &(ctx->cipher);
+ b->init = 1;
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ dctx = (BIO_ENC_CTX *)dbio->ptr;
+ 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);
+ break;
+ }
+ return (ret);
+}
+
+static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+/*-
+void BIO_set_cipher_ctx(b,c)
+BIO *b;
+EVP_CIPHER_ctx *c;
+ {
+ if (b == NULL) return;
+
+ if ((b->callback != NULL) &&
+ (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+ return;
+
+ b->init=1;
+ ctx=(BIO_ENC_CTX *)b->ptr;
+ memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
+
+ if (b->callback != NULL)
+ b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+ }
+*/
+
+void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+ const unsigned char *i, int e)
+{
+ BIO_ENC_CTX *ctx;
+
+ if (b == NULL)
+ return;
+
+ if ((b->callback != NULL) &&
+ (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <=
+ 0))
+ return;
+
+ b->init = 1;
+ ctx = (BIO_ENC_CTX *)b->ptr;
+ EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e);
+
+ if (b->callback != NULL)
+ b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_md.c b/Cryptlib/OpenSSL/crypto/evp/bio_md.c
new file mode 100644
index 00000000..f0b0c0c0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_md.c
@@ -0,0 +1,272 @@
+/* crypto/evp/bio_md.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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int md_write(BIO *h, char const *buf, int num);
+static int md_read(BIO *h, char *buf, int size);
+/*
+ * static int md_puts(BIO *h, const char *str);
+ */
+static int md_gets(BIO *h, char *str, int size);
+static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int md_new(BIO *h);
+static int md_free(BIO *data);
+static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD methods_md = {
+ BIO_TYPE_MD, "message digest",
+ md_write,
+ md_read,
+ NULL, /* md_puts, */
+ md_gets,
+ md_ctrl,
+ md_new,
+ md_free,
+ md_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_md(void)
+{
+ return (&methods_md);
+}
+
+static int md_new(BIO *bi)
+{
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+ if (ctx == NULL)
+ return (0);
+
+ bi->init = 0;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int md_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ EVP_MD_CTX_destroy(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int md_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ EVP_MD_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ ret = BIO_read(b->next_bio, out, outl);
+ if (b->init) {
+ if (ret > 0) {
+ if (EVP_DigestUpdate(ctx, (unsigned char *)out,
+ (unsigned int)ret) <= 0)
+ return (-1);
+ }
+ }
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static int md_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+ EVP_MD_CTX *ctx;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+ ctx = b->ptr;
+
+ if ((ctx != NULL) && (b->next_bio != NULL))
+ ret = BIO_write(b->next_bio, in, inl);
+ if (b->init) {
+ if (ret > 0) {
+ if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
+ (unsigned int)ret)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+ }
+ if (b->next_bio != NULL) {
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ }
+ return (ret);
+}
+
+static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ EVP_MD_CTX *ctx, *dctx, **pctx;
+ const EVP_MD **ppmd;
+ EVP_MD *md;
+ long ret = 1;
+ BIO *dbio;
+
+ ctx = b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ if (b->init)
+ ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
+ else
+ ret = 0;
+ if (ret > 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_C_GET_MD:
+ if (b->init) {
+ ppmd = ptr;
+ *ppmd = ctx->digest;
+ } else
+ ret = 0;
+ break;
+ case BIO_C_GET_MD_CTX:
+ pctx = ptr;
+ *pctx = ctx;
+ b->init = 1;
+ break;
+ case BIO_C_SET_MD_CTX:
+ if (b->init)
+ b->ptr = ptr;
+ else
+ ret = 0;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_C_SET_MD:
+ md = ptr;
+ ret = EVP_DigestInit_ex(ctx, md, NULL);
+ if (ret > 0)
+ b->init = 1;
+ break;
+ case BIO_CTRL_DUP:
+ dbio = ptr;
+ dctx = dbio->ptr;
+ if (!EVP_MD_CTX_copy_ex(dctx, ctx))
+ return 0;
+ b->init = 1;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int md_gets(BIO *bp, char *buf, int size)
+{
+ EVP_MD_CTX *ctx;
+ unsigned int ret;
+
+ ctx = bp->ptr;
+ if (size < ctx->digest->md_size)
+ return (0);
+ if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
+ return -1;
+
+ return ((int)ret);
+}
+
+/*-
+static int md_puts(bp,str)
+BIO *bp;
+char *str;
+ {
+ return(-1);
+ }
+*/
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_ok.c b/Cryptlib/OpenSSL/crypto/evp/bio_ok.c
new file mode 100644
index 00000000..5c32e35e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_ok.c
@@ -0,0 +1,624 @@
+/* crypto/evp/bio_ok.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.]
+ */
+
+/*-
+ From: Arne Ansper <arne@cyber.ee>
+
+ Why BIO_f_reliable?
+
+ I wrote function which took BIO* as argument, read data from it
+ and processed it. Then I wanted to store the input file in
+ encrypted form. OK I pushed BIO_f_cipher to the BIO stack
+ and everything was OK. BUT if user types wrong password
+ BIO_f_cipher outputs only garbage and my function crashes. Yes
+ I can and I should fix my function, but BIO_f_cipher is
+ easy way to add encryption support to many existing applications
+ and it's hard to debug and fix them all.
+
+ So I wanted another BIO which would catch the incorrect passwords and
+ file damages which cause garbage on BIO_f_cipher's output.
+
+ The easy way is to push the BIO_f_md and save the checksum at
+ the end of the file. However there are several problems with this
+ approach:
+
+ 1) you must somehow separate checksum from actual data.
+ 2) you need lot's of memory when reading the file, because you
+ must read to the end of the file and verify the checksum before
+ letting the application to read the data.
+
+ BIO_f_reliable tries to solve both problems, so that you can
+ read and write arbitrary long streams using only fixed amount
+ of memory.
+
+ BIO_f_reliable splits data stream into blocks. Each block is prefixed
+ with it's length and suffixed with it's digest. So you need only
+ several Kbytes of memory to buffer single block before verifying
+ it's digest.
+
+ BIO_f_reliable goes further and adds several important capabilities:
+
+ 1) the digest of the block is computed over the whole stream
+ -- so nobody can rearrange the blocks or remove or replace them.
+
+ 2) to detect invalid passwords right at the start BIO_f_reliable
+ adds special prefix to the stream. In order to avoid known plain-text
+ attacks this prefix is generated as follows:
+
+ *) digest is initialized with random seed instead of
+ standardized one.
+ *) same seed is written to output
+ *) well-known text is then hashed and the output
+ of the digest is also written to output.
+
+ reader can now read the seed from stream, hash the same string
+ and then compare the digest output.
+
+ Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
+ initially wrote and tested this code on x86 machine and wrote the
+ digests out in machine-dependent order :( There are people using
+ this code and I cannot change this easily without making existing
+ data files unreadable.
+
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+static int ok_write(BIO *h, const char *buf, int num);
+static int ok_read(BIO *h, char *buf, int size);
+static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ok_new(BIO *h);
+static int ok_free(BIO *data);
+static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int sig_out(BIO *b);
+static int sig_in(BIO *b);
+static int block_out(BIO *b);
+static int block_in(BIO *b);
+#define OK_BLOCK_SIZE (1024*4)
+#define OK_BLOCK_BLOCK 4
+#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
+#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
+
+typedef struct ok_struct {
+ size_t buf_len;
+ size_t buf_off;
+ size_t buf_len_save;
+ size_t buf_off_save;
+ int cont; /* <= 0 when finished */
+ int finished;
+ EVP_MD_CTX md;
+ int blockout; /* output block is ready */
+ int sigio; /* must process signature */
+ unsigned char buf[IOBS];
+} BIO_OK_CTX;
+
+static BIO_METHOD methods_ok = {
+ BIO_TYPE_CIPHER, "reliable",
+ ok_write,
+ ok_read,
+ NULL, /* ok_puts, */
+ NULL, /* ok_gets, */
+ ok_ctrl,
+ ok_new,
+ ok_free,
+ ok_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_reliable(void)
+{
+ return (&methods_ok);
+}
+
+static int ok_new(BIO *bi)
+{
+ BIO_OK_CTX *ctx;
+
+ ctx = (BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
+ if (ctx == NULL)
+ return (0);
+
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->buf_len_save = 0;
+ ctx->buf_off_save = 0;
+ ctx->cont = 1;
+ ctx->finished = 0;
+ ctx->blockout = 0;
+ ctx->sigio = 1;
+
+ EVP_MD_CTX_init(&ctx->md);
+
+ bi->init = 0;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int ok_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
+ OPENSSL_cleanse(a->ptr, sizeof(BIO_OK_CTX));
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int ok_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, i, n;
+ BIO_OK_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_OK_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
+ return (0);
+
+ while (outl > 0) {
+
+ /* copy clean bytes to output buffer */
+ if (ctx->blockout) {
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+ ret += i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+
+ /* all clean bytes are out */
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_off = 0;
+
+ /*
+ * copy start of the next block into proper place
+ */
+ if (ctx->buf_len_save - ctx->buf_off_save > 0) {
+ ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
+ memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
+ ctx->buf_len);
+ } else {
+ ctx->buf_len = 0;
+ }
+ ctx->blockout = 0;
+ }
+ }
+
+ /* output buffer full -- cancel */
+ if (outl == 0)
+ break;
+
+ /* no clean bytes in buffer -- fill it */
+ n = IOBS - ctx->buf_len;
+ i = BIO_read(b->next_bio, &(ctx->buf[ctx->buf_len]), n);
+
+ if (i <= 0)
+ break; /* nothing new */
+
+ ctx->buf_len += i;
+
+ /* no signature yet -- check if we got one */
+ if (ctx->sigio == 1) {
+ if (!sig_in(b)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+
+ /* signature ok -- check if we got block */
+ if (ctx->sigio == 0) {
+ if (!block_in(b)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+
+ /* invalid block -- cancel */
+ if (ctx->cont <= 0)
+ break;
+
+ }
+
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static int ok_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0, n, i;
+ BIO_OK_CTX *ctx;
+
+ if (inl <= 0)
+ return inl;
+
+ ctx = (BIO_OK_CTX *)b->ptr;
+ ret = inl;
+
+ if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
+ return (0);
+
+ if (ctx->sigio && !sig_out(b))
+ return 0;
+
+ do {
+ BIO_clear_retry_flags(b);
+ n = ctx->buf_len - ctx->buf_off;
+ while (ctx->blockout && n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (!BIO_should_retry(b))
+ ctx->cont = 0;
+ return (i);
+ }
+ ctx->buf_off += i;
+ n -= i;
+ }
+
+ /* at this point all pending data has been written */
+ ctx->blockout = 0;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = OK_BLOCK_BLOCK;
+ ctx->buf_off = 0;
+ }
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+
+ n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
+ (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
+
+ memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),
+ (unsigned char *)in, n);
+ ctx->buf_len += n;
+ inl -= n;
+ in += n;
+
+ if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
+ if (!block_out(b)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+ } while (inl > 0);
+
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD *md;
+ const EVP_MD **ppmd;
+ long ret = 1;
+ int i;
+
+ ctx = b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->buf_len_save = 0;
+ ctx->buf_off_save = 0;
+ ctx->cont = 1;
+ ctx->finished = 0;
+ ctx->blockout = 0;
+ ctx->sigio = 1;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0)
+ ret = 1;
+ else
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ case BIO_CTRL_WPENDING: /* More to read in buffer */
+ ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ if (ctx->blockout == 0)
+ if (!block_out(b))
+ return 0;
+
+ while (ctx->blockout) {
+ i = ok_write(b, NULL, 0);
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+ }
+
+ ctx->finished = 1;
+ ctx->buf_off = ctx->buf_len = 0;
+ ctx->cont = (int)ret;
+
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->cont;
+ break;
+ case BIO_C_SET_MD:
+ md = ptr;
+ if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
+ return 0;
+ b->init = 1;
+ break;
+ case BIO_C_GET_MD:
+ if (b->init) {
+ ppmd = ptr;
+ *ppmd = ctx->md.digest;
+ } else
+ ret = 0;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static void longswap(void *_ptr, size_t len)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ if (is_endian.little) {
+ size_t i;
+ unsigned char *p = _ptr, c;
+
+ for (i = 0; i < len; i += 4) {
+ c = p[0], p[0] = p[3], p[3] = c;
+ c = p[1], p[1] = p[2], p[2] = c;
+ }
+ }
+}
+
+static int sig_out(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE)
+ return 1;
+
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
+ /*
+ * FIXME: there's absolutely no guarantee this makes any sense at all,
+ * particularly now EVP_MD_CTX has been restructured.
+ */
+ if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0)
+ goto berr;
+ memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
+ longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
+ ctx->buf_len += md->digest->md_size;
+
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
+ ctx->buf_len += md->digest->md_size;
+ ctx->blockout = 1;
+ ctx->sigio = 0;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
+
+static int sig_in(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+ unsigned char tmp[EVP_MAX_MD_SIZE];
+ int ret = 0;
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size)
+ return 1;
+
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
+ memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
+ longswap(md->md_data, md->digest->md_size);
+ ctx->buf_off += md->digest->md_size;
+
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
+ ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
+ ctx->buf_off += md->digest->md_size;
+ if (ret == 1) {
+ ctx->sigio = 0;
+ if (ctx->buf_len != ctx->buf_off) {
+ memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
+ ctx->buf_len - ctx->buf_off);
+ }
+ ctx->buf_len -= ctx->buf_off;
+ ctx->buf_off = 0;
+ } else {
+ ctx->cont = 0;
+ }
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
+
+static int block_out(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+ unsigned long tl;
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ tl = ctx->buf_len - OK_BLOCK_BLOCK;
+ ctx->buf[0] = (unsigned char)(tl >> 24);
+ ctx->buf[1] = (unsigned char)(tl >> 16);
+ ctx->buf[2] = (unsigned char)(tl >> 8);
+ ctx->buf[3] = (unsigned char)(tl);
+ if (!EVP_DigestUpdate(md,
+ (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
+ ctx->buf_len += md->digest->md_size;
+ ctx->blockout = 1;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
+
+static int block_in(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+ unsigned long tl = 0;
+ unsigned char tmp[EVP_MAX_MD_SIZE];
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
+ tl = ctx->buf[0];
+ tl <<= 8;
+ tl |= ctx->buf[1];
+ tl <<= 8;
+ tl |= ctx->buf[2];
+ tl <<= 8;
+ tl |= ctx->buf[3];
+
+ if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size)
+ return 1;
+
+ if (!EVP_DigestUpdate(md,
+ (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
+ if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) ==
+ 0) {
+ /* there might be parts from next block lurking around ! */
+ ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size;
+ ctx->buf_len_save = ctx->buf_len;
+ ctx->buf_off = OK_BLOCK_BLOCK;
+ ctx->buf_len = tl + OK_BLOCK_BLOCK;
+ ctx->blockout = 1;
+ } else {
+ ctx->cont = 0;
+ }
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/c_all.c b/Cryptlib/OpenSSL/crypto/evp/c_all.c
new file mode 100644
index 00000000..a3ed00d4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/c_all.c
@@ -0,0 +1,90 @@
+/* crypto/evp/c_all.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#if 0
+# undef OpenSSL_add_all_algorithms
+
+void OpenSSL_add_all_algorithms(void)
+{
+ OPENSSL_add_all_algorithms_noconf();
+}
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void)
+{
+ /*
+ * For the moment OPENSSL_cpuid_setup does something
+ * only on IA-32, but we reserve the option for all
+ * platforms...
+ */
+ OPENSSL_cpuid_setup();
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
+#ifndef OPENSSL_NO_ENGINE
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+ ENGINE_setup_bsd_cryptodev();
+# endif
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/c_allc.c b/Cryptlib/OpenSSL/crypto/evp/c_allc.c
new file mode 100644
index 00000000..280e5840
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/c_allc.c
@@ -0,0 +1,241 @@
+/* crypto/evp/c_allc.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void OpenSSL_add_all_ciphers(void)
+{
+
+#ifndef OPENSSL_NO_DES
+ EVP_add_cipher(EVP_des_cfb());
+ EVP_add_cipher(EVP_des_cfb1());
+ EVP_add_cipher(EVP_des_cfb8());
+ EVP_add_cipher(EVP_des_ede_cfb());
+ EVP_add_cipher(EVP_des_ede3_cfb());
+ EVP_add_cipher(EVP_des_ede3_cfb1());
+ EVP_add_cipher(EVP_des_ede3_cfb8());
+
+ EVP_add_cipher(EVP_des_ofb());
+ EVP_add_cipher(EVP_des_ede_ofb());
+ EVP_add_cipher(EVP_des_ede3_ofb());
+
+ EVP_add_cipher(EVP_desx_cbc());
+ EVP_add_cipher_alias(SN_desx_cbc, "DESX");
+ EVP_add_cipher_alias(SN_desx_cbc, "desx");
+
+ EVP_add_cipher(EVP_des_cbc());
+ EVP_add_cipher_alias(SN_des_cbc, "DES");
+ EVP_add_cipher_alias(SN_des_cbc, "des");
+ EVP_add_cipher(EVP_des_ede_cbc());
+ EVP_add_cipher(EVP_des_ede3_cbc());
+ EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
+ EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
+
+ EVP_add_cipher(EVP_des_ecb());
+ EVP_add_cipher(EVP_des_ede());
+ EVP_add_cipher(EVP_des_ede3());
+ EVP_add_cipher(EVP_des_ede3_wrap());
+#endif
+
+#ifndef OPENSSL_NO_RC4
+ EVP_add_cipher(EVP_rc4());
+ EVP_add_cipher(EVP_rc4_40());
+# ifndef OPENSSL_NO_MD5
+ EVP_add_cipher(EVP_rc4_hmac_md5());
+# endif
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+ EVP_add_cipher(EVP_idea_ecb());
+ EVP_add_cipher(EVP_idea_cfb());
+ EVP_add_cipher(EVP_idea_ofb());
+ EVP_add_cipher(EVP_idea_cbc());
+ EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
+ EVP_add_cipher_alias(SN_idea_cbc, "idea");
+#endif
+
+#ifndef OPENSSL_NO_SEED
+ EVP_add_cipher(EVP_seed_ecb());
+ EVP_add_cipher(EVP_seed_cfb());
+ EVP_add_cipher(EVP_seed_ofb());
+ EVP_add_cipher(EVP_seed_cbc());
+ EVP_add_cipher_alias(SN_seed_cbc, "SEED");
+ EVP_add_cipher_alias(SN_seed_cbc, "seed");
+#endif
+
+#ifndef OPENSSL_NO_RC2
+ EVP_add_cipher(EVP_rc2_ecb());
+ EVP_add_cipher(EVP_rc2_cfb());
+ EVP_add_cipher(EVP_rc2_ofb());
+ EVP_add_cipher(EVP_rc2_cbc());
+ EVP_add_cipher(EVP_rc2_40_cbc());
+ EVP_add_cipher(EVP_rc2_64_cbc());
+ EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
+ EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
+#endif
+
+#ifndef OPENSSL_NO_BF
+ EVP_add_cipher(EVP_bf_ecb());
+ EVP_add_cipher(EVP_bf_cfb());
+ EVP_add_cipher(EVP_bf_ofb());
+ EVP_add_cipher(EVP_bf_cbc());
+ EVP_add_cipher_alias(SN_bf_cbc, "BF");
+ EVP_add_cipher_alias(SN_bf_cbc, "bf");
+ EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
+#endif
+
+#ifndef OPENSSL_NO_CAST
+ EVP_add_cipher(EVP_cast5_ecb());
+ EVP_add_cipher(EVP_cast5_cfb());
+ EVP_add_cipher(EVP_cast5_ofb());
+ EVP_add_cipher(EVP_cast5_cbc());
+ EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
+ EVP_add_cipher_alias(SN_cast5_cbc, "cast");
+ EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
+ EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
+#endif
+
+#ifndef OPENSSL_NO_RC5
+ EVP_add_cipher(EVP_rc5_32_12_16_ecb());
+ EVP_add_cipher(EVP_rc5_32_12_16_cfb());
+ EVP_add_cipher(EVP_rc5_32_12_16_ofb());
+ EVP_add_cipher(EVP_rc5_32_12_16_cbc());
+ EVP_add_cipher_alias(SN_rc5_cbc, "rc5");
+ EVP_add_cipher_alias(SN_rc5_cbc, "RC5");
+#endif
+
+#ifndef OPENSSL_NO_AES
+ EVP_add_cipher(EVP_aes_128_ecb());
+ EVP_add_cipher(EVP_aes_128_cbc());
+ EVP_add_cipher(EVP_aes_128_cfb());
+ EVP_add_cipher(EVP_aes_128_cfb1());
+ EVP_add_cipher(EVP_aes_128_cfb8());
+ EVP_add_cipher(EVP_aes_128_ofb());
+ EVP_add_cipher(EVP_aes_128_ctr());
+ EVP_add_cipher(EVP_aes_128_gcm());
+ EVP_add_cipher(EVP_aes_128_xts());
+ EVP_add_cipher(EVP_aes_128_ccm());
+ EVP_add_cipher(EVP_aes_128_wrap());
+ EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
+ EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
+ EVP_add_cipher(EVP_aes_192_ecb());
+ EVP_add_cipher(EVP_aes_192_cbc());
+ EVP_add_cipher(EVP_aes_192_cfb());
+ EVP_add_cipher(EVP_aes_192_cfb1());
+ EVP_add_cipher(EVP_aes_192_cfb8());
+ EVP_add_cipher(EVP_aes_192_ofb());
+ EVP_add_cipher(EVP_aes_192_ctr());
+ EVP_add_cipher(EVP_aes_192_gcm());
+ EVP_add_cipher(EVP_aes_192_ccm());
+ EVP_add_cipher(EVP_aes_192_wrap());
+ EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
+ EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
+ EVP_add_cipher(EVP_aes_256_ecb());
+ EVP_add_cipher(EVP_aes_256_cbc());
+ EVP_add_cipher(EVP_aes_256_cfb());
+ EVP_add_cipher(EVP_aes_256_cfb1());
+ EVP_add_cipher(EVP_aes_256_cfb8());
+ EVP_add_cipher(EVP_aes_256_ofb());
+ EVP_add_cipher(EVP_aes_256_ctr());
+ EVP_add_cipher(EVP_aes_256_gcm());
+ EVP_add_cipher(EVP_aes_256_xts());
+ EVP_add_cipher(EVP_aes_256_ccm());
+ EVP_add_cipher(EVP_aes_256_wrap());
+ EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
+ EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+# endif
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
+# endif
+#endif
+
+#ifndef OPENSSL_NO_CAMELLIA
+ EVP_add_cipher(EVP_camellia_128_ecb());
+ EVP_add_cipher(EVP_camellia_128_cbc());
+ EVP_add_cipher(EVP_camellia_128_cfb());
+ EVP_add_cipher(EVP_camellia_128_cfb1());
+ EVP_add_cipher(EVP_camellia_128_cfb8());
+ EVP_add_cipher(EVP_camellia_128_ofb());
+ EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
+ EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
+ EVP_add_cipher(EVP_camellia_192_ecb());
+ EVP_add_cipher(EVP_camellia_192_cbc());
+ EVP_add_cipher(EVP_camellia_192_cfb());
+ EVP_add_cipher(EVP_camellia_192_cfb1());
+ EVP_add_cipher(EVP_camellia_192_cfb8());
+ EVP_add_cipher(EVP_camellia_192_ofb());
+ EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
+ EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
+ EVP_add_cipher(EVP_camellia_256_ecb());
+ EVP_add_cipher(EVP_camellia_256_cbc());
+ EVP_add_cipher(EVP_camellia_256_cfb());
+ EVP_add_cipher(EVP_camellia_256_cfb1());
+ EVP_add_cipher(EVP_camellia_256_cfb8());
+ EVP_add_cipher(EVP_camellia_256_ofb());
+ EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
+ EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/c_alld.c b/Cryptlib/OpenSSL/crypto/evp/c_alld.c
new file mode 100644
index 00000000..fdbe3ee0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/c_alld.c
@@ -0,0 +1,114 @@
+/* crypto/evp/c_alld.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void OpenSSL_add_all_digests(void)
+{
+#ifndef OPENSSL_NO_MD4
+ EVP_add_digest(EVP_md4());
+#endif
+#ifndef OPENSSL_NO_MD5
+ EVP_add_digest(EVP_md5());
+ EVP_add_digest_alias(SN_md5, "ssl2-md5");
+ EVP_add_digest_alias(SN_md5, "ssl3-md5");
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
+ EVP_add_digest(EVP_sha());
+# ifndef OPENSSL_NO_DSA
+ EVP_add_digest(EVP_dss());
+# endif
+#endif
+#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);
+# ifndef OPENSSL_NO_DSA
+ EVP_add_digest(EVP_dss1());
+ EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
+ EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
+ EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
+# endif
+# ifndef OPENSSL_NO_ECDSA
+ EVP_add_digest(EVP_ecdsa());
+# endif
+#endif
+#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
+ EVP_add_digest(EVP_mdc2());
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+ EVP_add_digest(EVP_ripemd160());
+ EVP_add_digest_alias(SN_ripemd160, "ripemd");
+ EVP_add_digest_alias(SN_ripemd160, "rmd160");
+#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
+#ifndef OPENSSL_NO_WHIRLPOOL
+ EVP_add_digest(EVP_whirlpool());
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/digest.c b/Cryptlib/OpenSSL/crypto/evp/digest.c
new file mode 100644
index 00000000..5b642b23
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/digest.c
@@ -0,0 +1,408 @@
+/* crypto/evp/digest.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include "evp_locl.h"
+#endif
+
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+{
+ memset(ctx, '\0', sizeof *ctx);
+}
+
+EVP_MD_CTX *EVP_MD_CTX_create(void)
+{
+ EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+
+ if (ctx)
+ EVP_MD_CTX_init(ctx);
+
+ return ctx;
+}
+
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
+{
+ EVP_MD_CTX_init(ctx);
+ return EVP_DigestInit_ex(ctx, type, NULL);
+}
+
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+{
+ EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+#ifdef OPENSSL_FIPS
+ /* If FIPS mode switch to approved implementation if possible */
+ if (FIPS_mode()) {
+ const EVP_MD *fipsmd;
+ if (type) {
+ fipsmd = evp_get_fips_md(type);
+ if (fipsmd)
+ type = fipsmd;
+ }
+ }
+#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 (type) {
+ /*
+ * 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_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ } else
+ /* Ask if an ENGINE is reserved for this job */
+ 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, type->type);
+ if (!d) {
+ /* Same comment from evp_enc.c */
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ ENGINE_finish(impl);
+ return 0;
+ }
+ /* We'll use the ENGINE's private digest definition */
+ type = 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_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
+ return 0;
+ }
+ type = ctx->digest;
+ }
+#endif
+ if (ctx->digest != type) {
+ if (ctx->digest && ctx->digest->ctx_size) {
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ }
+ ctx->digest = type;
+ 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 == NULL) {
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ }
+#ifndef OPENSSL_NO_ENGINE
+ 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;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode()) {
+ if (FIPS_digestinit(ctx, type))
+ return 1;
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ return 0;
+ }
+#endif
+ return ctx->digest->init(ctx);
+}
+
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestupdate(ctx, data, count);
+#else
+ return ctx->update(ctx, data, count);
+#endif
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+ int ret;
+ ret = EVP_DigestFinal_ex(ctx, md, size);
+ EVP_MD_CTX_cleanup(ctx);
+ return ret;
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestfinal(ctx, md, size);
+#else
+ int ret;
+
+ OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+ ret = ctx->digest->final(ctx, md);
+ if (size != NULL)
+ *size = ctx->digest->md_size;
+ if (ctx->digest->cleanup) {
+ ctx->digest->cleanup(ctx);
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+ }
+ memset(ctx->md_data, 0, ctx->digest->ctx_size);
+ return ret;
+#endif
+}
+
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+ EVP_MD_CTX_init(out);
+ return EVP_MD_CTX_copy_ex(out, in);
+}
+
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+ unsigned char *tmp_buf;
+ if ((in == NULL) || (in->digest == NULL)) {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
+ return 0;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ /* Make sure it's safe to copy a digest context using an ENGINE */
+ if (in->engine && !ENGINE_init(in->engine)) {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+#endif
+
+ if (out->digest == in->digest) {
+ tmp_buf = out->md_data;
+ 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 (in->md_data && out->digest->ctx_size) {
+ if (tmp_buf)
+ out->md_data = tmp_buf;
+ else {
+ out->md_data = OPENSSL_malloc(out->digest->ctx_size);
+ if (!out->md_data) {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ 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);
+
+ return 1;
+}
+
+int EVP_Digest(const void *data, size_t count,
+ unsigned char *md, unsigned int *size, const EVP_MD *type,
+ ENGINE *impl)
+{
+ EVP_MD_CTX ctx;
+ int ret;
+
+ EVP_MD_CTX_init(&ctx);
+ 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);
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return ret;
+}
+
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
+{
+ if (ctx) {
+ EVP_MD_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
+{
+#ifndef OPENSSL_FIPS
+ /*
+ * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
+ * sometimes only copies of the context are ever finalised.
+ */
+ if (ctx->digest && ctx->digest->cleanup
+ && !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
+ && !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);
+ }
+#endif
+ 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.
+ */
+ ENGINE_finish(ctx->engine);
+#endif
+#ifdef OPENSSL_FIPS
+ FIPS_md_ctx_cleanup(ctx);
+#endif
+ memset(ctx, '\0', sizeof *ctx);
+
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes.c b/Cryptlib/OpenSSL/crypto/evp/e_aes.c
new file mode 100644
index 00000000..1734a823
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes.c
@@ -0,0 +1,2024 @@
+/* ====================================================================
+ * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_AES
+#include <openssl/crypto.h>
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/aes.h>
+# include "evp_locl.h"
+# include "modes_lcl.h"
+# include <openssl/rand.h>
+
+# undef EVP_CIPH_FLAG_FIPS
+# define EVP_CIPH_FLAG_FIPS 0
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks;
+ block128_f block;
+ union {
+ cbc128_f cbc;
+ ctr128_f ctr;
+ } stream;
+} EVP_AES_KEY;
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ GCM128_CONTEXT gcm;
+ unsigned char *iv; /* Temporary IV store */
+ int ivlen; /* IV length */
+ int taglen;
+ int iv_gen; /* It is OK to generate IVs */
+ int tls_aad_len; /* TLS AAD length */
+ ctr128_f ctr;
+} EVP_AES_GCM_CTX;
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks1, ks2; /* AES key schedules to use */
+ XTS128_CONTEXT xts;
+ void (*stream) (const unsigned char *in,
+ unsigned char *out, size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+} EVP_AES_XTS_CTX;
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_set; /* Set if tag is valid */
+ int len_set; /* Set if message length set */
+ int L, M; /* L and M parameters from RFC3610 */
+ CCM128_CONTEXT ccm;
+ ccm128_f str;
+} EVP_AES_CCM_CTX;
+
+# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
+
+# ifdef VPAES_ASM
+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void vpaes_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+# endif
+# ifdef BSAES_ASM
+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char ivec[16], int enc);
+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ const unsigned char ivec[16]);
+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+# endif
+# ifdef AES_CTR_ASM
+void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ const unsigned char ivec[AES_BLOCK_SIZE]);
+# endif
+# ifdef AES_XTS_ASM
+void AES_xts_encrypt(const char *inp, char *out, size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+void AES_xts_decrypt(const char *inp, char *out, size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+# endif
+
+# if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+# include "ppc_arch.h"
+# ifdef VPAES_ASM
+# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
+# endif
+# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207)
+# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
+# define HWAES_encrypt aes_p8_encrypt
+# define HWAES_decrypt aes_p8_decrypt
+# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
+# endif
+
+# if defined(AES_ASM) && !defined(I386_ONLY) && ( \
+ ((defined(__i386) || defined(__i386__) || \
+ defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+
+# ifdef VPAES_ASM
+# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+# endif
+# ifdef BSAES_ASM
+# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+# endif
+/*
+ * AES-NI section
+ */
+# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length, const AES_KEY *key, int enc);
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_ctr32_encrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key, const unsigned char *ivec);
+
+void aesni_xts_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_xts_decrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_ccm64_encrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+void aesni_ccm64_decrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+size_t aesni_gcm_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t len,
+ const void *key, unsigned char ivec[16], u64 *Xi);
+# define AES_gcm_encrypt aesni_gcm_encrypt
+size_t aesni_gcm_decrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t len,
+ const void *key, unsigned char ivec[16], u64 *Xi);
+# define AES_gcm_decrypt aesni_gcm_decrypt
+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in,
+ size_t len);
+# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \
+ gctx->gcm.ghash==gcm_ghash_avx)
+# define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \
+ gctx->gcm.ghash==gcm_ghash_avx)
+# undef AES_GCM_ASM2 /* minor size optimization */
+# endif
+
+static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+ dat->block = (block128_f) aesni_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aesni_cbc_encrypt : NULL;
+ } else {
+ ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+ dat->block = (block128_f) aesni_encrypt;
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+ else
+ dat->stream.cbc = NULL;
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt);
+
+ return 1;
+}
+
+static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+
+ if (len < bl)
+ return 1;
+
+ aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt);
+
+ return 1;
+}
+
+# define aesni_ofb_cipher aes_ofb_cipher
+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_cfb_cipher aes_cfb_cipher
+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_cfb8_cipher aes_cfb8_cipher
+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_cfb1_cipher aes_cfb1_cipher
+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_ctr_cipher aes_ctr_cipher
+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt);
+ gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+ /*
+ * If we have an iv can set it directly, otherwise use saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv) {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+}
+
+# define aesni_gcm_cipher aes_gcm_cipher
+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key) {
+ /* key_len is two AES keys */
+ if (enc) {
+ aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aesni_encrypt;
+ xctx->stream = aesni_xts_encrypt;
+ } else {
+ aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aesni_decrypt;
+ xctx->stream = aesni_xts_decrypt;
+ }
+
+ aesni_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) aesni_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+# define aesni_xts_cipher aes_xts_cipher
+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) aesni_encrypt);
+ cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks :
+ (ccm128_f) aesni_ccm64_decrypt_blocks;
+ cctx->key_set = 1;
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+}
+
+# define aesni_ccm_cipher aes_ccm_cipher
+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_init_key, \
+ aesni_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_##mode##_init_key, \
+ aesni_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
+
+void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
+void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
+void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+/*
+ * Key-length specific subroutines were chosen for following reason.
+ * Each SPARC T4 core can execute up to 8 threads which share core's
+ * resources. Loading as much key material to registers allows to
+ * minimize references to shared memory interface, as well as amount
+ * of instructions in inner loops [much needed on T4]. But then having
+ * non-key-length specific routines would require conditional branches
+ * either in inner loops or on subroutines' entries. Former is hardly
+ * acceptable, while latter means code size increase to size occupied
+ * by multiple key-length specfic subroutines, so why fight?
+ */
+void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ unsigned char *ivec);
+void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ unsigned char *ivec);
+void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ unsigned char *ivec);
+void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+
+static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode, bits;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ bits = ctx->key_len * 8;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ ret = 0;
+ aes_t4_set_decrypt_key(key, bits, ctx->cipher_data);
+ dat->block = (block128_f) aes_t4_decrypt;
+ switch (bits) {
+ case 128:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aes128_t4_cbc_decrypt : NULL;
+ break;
+ case 192:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aes192_t4_cbc_decrypt : NULL;
+ break;
+ case 256:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aes256_t4_cbc_decrypt : NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ } else {
+ ret = 0;
+ aes_t4_set_encrypt_key(key, bits, ctx->cipher_data);
+ dat->block = (block128_f) aes_t4_encrypt;
+ switch (bits) {
+ case 128:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aes128_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ case 192:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aes192_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ case 256:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aes256_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+# define aes_t4_cbc_cipher aes_cbc_cipher
+static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_ecb_cipher aes_ecb_cipher
+static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_ofb_cipher aes_ofb_cipher
+static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_cfb_cipher aes_cfb_cipher
+static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_cfb8_cipher aes_cfb8_cipher
+static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_cfb1_cipher aes_cfb1_cipher
+static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_ctr_cipher aes_ctr_cipher
+static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ int bits = ctx->key_len * 8;
+ aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) aes_t4_encrypt);
+ switch (bits) {
+ case 128:
+ gctx->ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
+ break;
+ case 192:
+ gctx->ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
+ break;
+ case 256:
+ gctx->ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
+ break;
+ default:
+ return 0;
+ }
+ /*
+ * If we have an iv can set it directly, otherwise use saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv) {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+}
+
+# define aes_t4_gcm_cipher aes_gcm_cipher
+static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key) {
+ int bits = ctx->key_len * 4;
+ xctx->stream = NULL;
+ /* key_len is two AES keys */
+ if (enc) {
+ aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aes_t4_encrypt;
+ switch (bits) {
+ case 128:
+ xctx->stream = aes128_t4_xts_encrypt;
+ break;
+# if 0 /* not yet */
+ case 192:
+ xctx->stream = aes192_t4_xts_encrypt;
+ break;
+# endif
+ case 256:
+ xctx->stream = aes256_t4_xts_encrypt;
+ break;
+ default:
+ return 0;
+ }
+ } else {
+ aes_t4_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aes_t4_decrypt;
+ switch (bits) {
+ case 128:
+ xctx->stream = aes128_t4_xts_decrypt;
+ break;
+# if 0 /* not yet */
+ case 192:
+ xctx->stream = aes192_t4_xts_decrypt;
+ break;
+# endif
+ case 256:
+ xctx->stream = aes256_t4_xts_decrypt;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ aes_t4_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) aes_t4_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+# define aes_t4_xts_cipher aes_xts_cipher
+static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ int bits = ctx->key_len * 8;
+ aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) aes_t4_encrypt);
+# if 0 /* not yet */
+ switch (bits) {
+ case 128:
+ cctx->str = enc ? (ccm128_f) aes128_t4_ccm64_encrypt :
+ (ccm128_f) ae128_t4_ccm64_decrypt;
+ break;
+ case 192:
+ cctx->str = enc ? (ccm128_f) aes192_t4_ccm64_encrypt :
+ (ccm128_f) ae192_t4_ccm64_decrypt;
+ break;
+ case 256:
+ cctx->str = enc ? (ccm128_f) aes256_t4_ccm64_encrypt :
+ (ccm128_f) ae256_t4_ccm64_decrypt;
+ break;
+ default:
+ return 0;
+ }
+# else
+ cctx->str = NULL;
+# endif
+ cctx->key_set = 1;
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+}
+
+# define aes_t4_ccm_cipher aes_ccm_cipher
+static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_t4_init_key, \
+ aes_t4_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_t4_##mode##_init_key, \
+ aes_t4_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# else
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+# endif
+
+# if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
+# include "arm_arch.h"
+# if __ARM_MAX_ARCH__>=7
+# if defined(BSAES_ASM)
+# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
+# endif
+# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
+# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
+# define HWAES_encrypt aes_v8_encrypt
+# define HWAES_decrypt aes_v8_decrypt
+# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
+# endif
+# endif
+
+# if defined(HWAES_CAPABLE)
+int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+void HWAES_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void HWAES_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, const int enc);
+void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ const unsigned char ivec[16]);
+# endif
+
+# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc)
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ ret = HWAES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) HWAES_decrypt;
+ dat->stream.cbc = NULL;
+# ifdef HWAES_cbc_encrypt
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
+# endif
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
+ ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_decrypt;
+ dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) vpaes_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) vpaes_cbc_encrypt : NULL;
+ } else
+# endif
+ {
+ ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) AES_cbc_encrypt : NULL;
+ } else
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ ret = HWAES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) HWAES_encrypt;
+ dat->stream.cbc = NULL;
+# ifdef HWAES_cbc_encrypt
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
+ else
+# endif
+# ifdef HWAES_ctr32_encrypt_blocks
+ if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
+ else
+# endif
+ (void)0; /* terminate potentially open 'else' */
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
+ ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_encrypt;
+ dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) vpaes_encrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) vpaes_cbc_encrypt : NULL;
+ } else
+# endif
+ {
+ ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_encrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) AES_cbc_encrypt : NULL;
+# ifdef AES_CTR_ASM
+ if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt;
+# endif
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (dat->stream.cbc)
+ (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
+ else if (ctx->encrypt)
+ CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+ else
+ CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+
+ return 1;
+}
+
+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+ size_t i;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (len < bl)
+ return 1;
+
+ for (i = 0, len -= bl; i <= len; i += bl)
+ (*dat->block) (in + i, out + i, &dat->ks);
+
+ return 1;
+}
+
+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, dat->block);
+ return 1;
+}
+
+static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) {
+ CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+ }
+
+ while (len >= MAXBITCHUNK) {
+ CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ len -= MAXBITCHUNK;
+ }
+ if (len)
+ CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+
+ return 1;
+}
+
+static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ unsigned int num = ctx->num;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (dat->stream.ctr)
+ CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->stream.ctr);
+ else
+ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->block);
+ ctx->num = (size_t)num;
+ return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS)
+ BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS)
+ BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS)
+
+static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
+{
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ return 1;
+}
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter)
+{
+ int n = 8;
+ unsigned char c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c)
+ return;
+ } while (n);
+}
+
+static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ switch (type) {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->ivlen = c->cipher->iv_len;
+ gctx->iv = c->iv;
+ gctx->taglen = -1;
+ gctx->iv_gen = 0;
+ gctx->tls_aad_len = -1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IVLEN:
+ if (arg <= 0)
+ return 0;
+ /* Allocate memory for IV if needed */
+ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ gctx->iv = OPENSSL_malloc(arg);
+ if (!gctx->iv)
+ return 0;
+ }
+ gctx->ivlen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_TAG:
+ if (arg <= 0 || arg > 16 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->taglen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_GET_TAG:
+ if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_FIXED:
+ /* Special case: -1 length restores whole IV */
+ if (arg == -1) {
+ memcpy(gctx->iv, ptr, gctx->ivlen);
+ gctx->iv_gen = 1;
+ return 1;
+ }
+ /*
+ * Fixed field must be at least 4 bytes and invocation field at least
+ * 8.
+ */
+ if ((arg < 4) || (gctx->ivlen - arg) < 8)
+ return 0;
+ if (arg)
+ memcpy(gctx->iv, ptr, arg);
+ if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
+ return 0;
+ gctx->iv_gen = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_IV_GEN:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0)
+ return 0;
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ if (arg <= 0 || arg > gctx->ivlen)
+ arg = gctx->ivlen;
+ memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
+ /*
+ * Invocation field will be at least 8 bytes in size and so no need
+ * to check wrap around or increment more than last 8 bytes.
+ */
+ ctr64_inc(gctx->iv + gctx->ivlen - 8);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_INV:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
+ return 0;
+ memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ /* Save the AAD for later use */
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tls_aad_len = arg;
+ {
+ unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1];
+ /* Correct length for explicit IV */
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ /* If decrypting correct for tag too */
+ if (!c->encrypt)
+ len -= EVP_GCM_TLS_TAG_LEN;
+ c->buf[arg - 2] = len >> 8;
+ c->buf[arg - 1] = len & 0xff;
+ }
+ /* Extra padding: tag appended to record */
+ return EVP_GCM_TLS_TAG_LEN;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
+ if (gctx->gcm.key) {
+ if (gctx->gcm.key != &gctx->ks)
+ return 0;
+ gctx_out->gcm.key = &gctx_out->ks;
+ }
+ if (gctx->iv == c->iv)
+ gctx_out->iv = out->iv;
+ else {
+ gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
+ if (!gctx_out->iv)
+ return 0;
+ memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
+ }
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ do {
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ HWAES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) HWAES_encrypt);
+# ifdef HWAES_ctr32_encrypt_blocks
+ gctx->ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
+# else
+ gctx->ctr = NULL;
+# endif
+ break;
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE) {
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) AES_encrypt);
+ gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
+ break;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) vpaes_encrypt);
+ gctx->ctr = NULL;
+ break;
+ } else
+# endif
+ (void)0; /* terminate potentially open 'else' */
+
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) AES_encrypt);
+# ifdef AES_CTR_ASM
+ gctx->ctr = (ctr128_f) AES_ctr32_encrypt;
+# else
+ gctx->ctr = NULL;
+# endif
+ } while (0);
+
+ /*
+ * If we have an iv can set it directly, otherwise use saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv) {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+}
+
+/*
+ * Handle TLS GCM packet format. This consists of the last portion of the IV
+ * followed by the payload and finally the tag. On encrypt generate IV,
+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
+ * and verify tag.
+ */
+
+static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ int rv = -1;
+ /* Encrypt/decrypt must be performed in place */
+ if (out != in
+ || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
+ return -1;
+ /*
+ * Set IV from start of buffer or generate IV and write to start of
+ * buffer.
+ */
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
+ EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
+ EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
+ goto err;
+ /* Use saved AAD */
+ if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
+ goto err;
+ /* Fix buffer and length to point to payload */
+ in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ if (ctx->encrypt) {
+ /* Encrypt payload */
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 32 && AES_GCM_ASM(gctx)) {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ goto err;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 32 && AES_GCM_ASM2(gctx)) {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ goto err;
+ }
+ out += len;
+ /* Finally write tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
+ rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ } else {
+ /* Decrypt */
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 16 && AES_GCM_ASM(gctx)) {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ goto err;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 16 && AES_GCM_ASM2(gctx)) {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ goto err;
+ }
+ /* Retrieve tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN);
+ /* If tag mismatch wipe buffer */
+ if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) {
+ OPENSSL_cleanse(out, len);
+ goto err;
+ }
+ rv = len;
+ }
+
+ err:
+ gctx->iv_set = 0;
+ gctx->tls_aad_len = -1;
+ return rv;
+}
+
+static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (gctx->tls_aad_len >= 0)
+ return aes_gcm_tls_cipher(ctx, out, in, len);
+
+ if (!gctx->iv_set)
+ return -1;
+ if (in) {
+ if (out == NULL) {
+ if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
+ return -1;
+ } else if (ctx->encrypt) {
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 32 && AES_GCM_ASM(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key, gctx->gcm.Yi.c,
+ gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ return -1;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 32 && AES_GCM_ASM2(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key, gctx->gcm.Yi.c,
+ gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ return -1;
+ }
+ } else {
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 16 && AES_GCM_ASM(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ return -1;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 16 && AES_GCM_ASM2(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ return -1;
+ }
+ }
+ return len;
+ } else {
+ if (!ctx->encrypt) {
+ if (gctx->taglen < 0)
+ return -1;
+ if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
+ gctx->taglen = 16;
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+}
+
+# define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+ | EVP_CIPH_CUSTOM_COPY)
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
+ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER |
+ CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM,
+ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER |
+ CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM,
+ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER |
+ CUSTOM_FLAGS)
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_XTS_CTX *xctx = c->cipher_data;
+ if (type == EVP_CTRL_COPY) {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
+ if (xctx->xts.key1) {
+ if (xctx->xts.key1 != &xctx->ks1)
+ return 0;
+ xctx_out->xts.key1 = &xctx_out->ks1;
+ }
+ if (xctx->xts.key2) {
+ if (xctx->xts.key2 != &xctx->ks2)
+ return 0;
+ xctx_out->xts.key2 = &xctx_out->ks2;
+ }
+ return 1;
+ } else if (type != EVP_CTRL_INIT)
+ return -1;
+ /* key1 and key2 are used as an indicator both key and IV are set */
+ xctx->xts.key1 = NULL;
+ xctx->xts.key2 = NULL;
+ return 1;
+}
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key)
+ do {
+# ifdef AES_XTS_ASM
+ xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
+# else
+ xctx->stream = NULL;
+# endif
+ /* key_len is two AES keys */
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ if (enc) {
+ HWAES_set_encrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) HWAES_encrypt;
+ } else {
+ HWAES_set_decrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) HWAES_decrypt;
+ }
+
+ HWAES_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) HWAES_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE)
+ xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
+ else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ if (enc) {
+ vpaes_set_encrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) vpaes_encrypt;
+ } else {
+ vpaes_set_decrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) vpaes_decrypt;
+ }
+
+ vpaes_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) vpaes_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ } else
+# endif
+ (void)0; /* terminate potentially open 'else' */
+
+ if (enc) {
+ AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_encrypt;
+ } else {
+ AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_decrypt;
+ }
+
+ AES_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) AES_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ } while (0);
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!xctx->xts.key1 || !xctx->xts.key2)
+ return 0;
+ if (!out || !in || len < AES_BLOCK_SIZE)
+ return 0;
+ if (xctx->stream)
+ (*xctx->stream) (in, out, len,
+ xctx->xts.key1, xctx->xts.key2, ctx->iv);
+ else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
+ ctx->encrypt))
+ return 0;
+ return 1;
+}
+
+# define aes_xts_cleanup NULL
+
+# define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+ | EVP_CIPH_CUSTOM_COPY)
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS,
+ EVP_CIPH_FLAG_FIPS | XTS_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS,
+ EVP_CIPH_FLAG_FIPS | XTS_FLAGS)
+
+static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_CCM_CTX *cctx = c->cipher_data;
+ switch (type) {
+ case EVP_CTRL_INIT:
+ cctx->key_set = 0;
+ cctx->iv_set = 0;
+ cctx->L = 8;
+ cctx->M = 12;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_IVLEN:
+ arg = 15 - arg;
+ case EVP_CTRL_CCM_SET_L:
+ if (arg < 2 || arg > 8)
+ return 0;
+ cctx->L = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_TAG:
+ if ((arg & 1) || arg < 4 || arg > 16)
+ return 0;
+ if (c->encrypt && ptr)
+ return 0;
+ if (ptr) {
+ cctx->tag_set = 1;
+ memcpy(c->buf, ptr, arg);
+ }
+ cctx->M = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_GET_TAG:
+ if (!c->encrypt || !cctx->tag_set)
+ return 0;
+ if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+ return 0;
+ cctx->tag_set = 0;
+ cctx->iv_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_CCM_CTX *cctx_out = out->cipher_data;
+ if (cctx->ccm.key) {
+ if (cctx->ccm.key != &cctx->ks)
+ return 0;
+ cctx_out->ccm.key = &cctx_out->ks;
+ }
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ do {
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ HWAES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) HWAES_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ break;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) vpaes_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ break;
+ }
+# endif
+ AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) AES_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ } while (0);
+ if (iv) {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+}
+
+static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ CCM128_CONTEXT *ccm = &cctx->ccm;
+ /* If not set up, return error */
+ if (!cctx->iv_set && !cctx->key_set)
+ return -1;
+ if (!ctx->encrypt && !cctx->tag_set)
+ return -1;
+ if (!out) {
+ if (!in) {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+ return -1;
+ cctx->len_set = 1;
+ return len;
+ }
+ /* If have AAD need message length */
+ if (!cctx->len_set && len)
+ return -1;
+ CRYPTO_ccm128_aad(ccm, in, len);
+ return len;
+ }
+ /* EVP_*Final() doesn't return any data */
+ if (!in)
+ return 0;
+ /* If not set length yet do it */
+ if (!cctx->len_set) {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+ return -1;
+ cctx->len_set = 1;
+ }
+ if (ctx->encrypt) {
+ if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ CRYPTO_ccm128_encrypt(ccm, in, out, len))
+ return -1;
+ cctx->tag_set = 1;
+ return len;
+ } else {
+ int rv = -1;
+ if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
+ unsigned char tag[16];
+ if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
+ if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M))
+ rv = len;
+ }
+ }
+ if (rv == -1)
+ OPENSSL_cleanse(out, len);
+ cctx->iv_set = 0;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return rv;
+ }
+
+}
+
+# define aes_ccm_cleanup NULL
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
+ EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM,
+ EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM,
+ EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
+#endif
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks;
+ /* Indicates if IV has been set */
+ unsigned char *iv;
+} EVP_AES_WRAP_CTX;
+
+static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_WRAP_CTX *wctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ if (ctx->encrypt)
+ AES_set_encrypt_key(key, ctx->key_len * 8, &wctx->ks.ks);
+ else
+ AES_set_decrypt_key(key, ctx->key_len * 8, &wctx->ks.ks);
+ if (!iv)
+ wctx->iv = NULL;
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 8);
+ wctx->iv = ctx->iv;
+ }
+ return 1;
+}
+
+static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inlen)
+{
+ EVP_AES_WRAP_CTX *wctx = ctx->cipher_data;
+ size_t rv;
+ if (!in)
+ return 0;
+ if (inlen % 8)
+ return -1;
+ if (ctx->encrypt && inlen < 8)
+ return -1;
+ if (!ctx->encrypt && inlen < 16)
+ return -1;
+ if (!out) {
+ if (ctx->encrypt)
+ return inlen + 8;
+ else
+ return inlen - 8;
+ }
+ if (ctx->encrypt)
+ rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
+ (block128_f) AES_encrypt);
+ else
+ rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
+ (block128_f) AES_decrypt);
+ return rv ? (int)rv : -1;
+}
+
+#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
+
+static const EVP_CIPHER aes_128_wrap = {
+ NID_id_aes128_wrap,
+ 8, 16, 8, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_wrap(void)
+{
+ return &aes_128_wrap;
+}
+
+static const EVP_CIPHER aes_192_wrap = {
+ NID_id_aes192_wrap,
+ 8, 24, 8, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_192_wrap(void)
+{
+ return &aes_192_wrap;
+}
+
+static const EVP_CIPHER aes_256_wrap = {
+ NID_id_aes256_wrap,
+ 8, 32, 8, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_256_wrap(void)
+{
+ return &aes_256_wrap;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
new file mode 100644
index 00000000..6dfd590a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -0,0 +1,1008 @@
+/* ====================================================================
+ * Copyright (c) 2011-2013 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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/aes.h>
+# include <openssl/sha.h>
+# include <openssl/rand.h>
+# include "modes_lcl.h"
+# include "constant_time_locl.h"
+
+# ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+# endif
+
+# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
+# define EVP_CIPH_FLAG_DEFAULT_ASN1 0
+# endif
+
+# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+# endif
+
+# define TLS1_1_VERSION 0x0302
+
+typedef struct {
+ AES_KEY ks;
+ SHA_CTX head, tail, md;
+ size_t payload_length; /* AAD length in decrypt case */
+ union {
+ unsigned int tls_ver;
+ unsigned char tls_aad[16]; /* 13 used */
+ } aux;
+} EVP_AES_HMAC_SHA1;
+
+# define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+# if defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+# define AESNI_CAPABLE (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA_CTX *ctx, const void *in0);
+
+void aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA_CTX *ctx, const void *in0);
+
+# define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
+
+static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ int ret;
+
+ if (enc)
+ ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks);
+ else
+ ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks);
+
+ SHA1_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return ret < 0 ? 0 : 1;
+}
+
+# define STITCHED_CALL
+# undef STITCHED_DECRYPT_CALL
+
+# if !defined(STITCHED_CALL)
+# define aes_off 0
+# endif
+
+void sha1_block_data_order(void *c, const void *p, size_t len);
+
+static void sha1_update(SHA_CTX *c, const void *data, size_t len)
+{
+ const unsigned char *ptr = data;
+ size_t res;
+
+ if ((res = c->num)) {
+ res = SHA_CBLOCK - res;
+ if (len < res)
+ res = len;
+ SHA1_Update(c, ptr, res);
+ ptr += res;
+ len -= res;
+ }
+
+ res = len % SHA_CBLOCK;
+ len -= res;
+
+ if (len) {
+ sha1_block_data_order(c, ptr, len / SHA_CBLOCK);
+
+ ptr += len;
+ c->Nh += len >> 29;
+ c->Nl += len <<= 3;
+ if (c->Nl < (unsigned int)len)
+ c->Nh++;
+ }
+
+ if (res)
+ SHA1_Update(c, ptr, res);
+}
+
+# ifdef SHA1_Update
+# undef SHA1_Update
+# endif
+# define SHA1_Update sha1_update
+
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+
+typedef struct {
+ unsigned int A[8], B[8], C[8], D[8], E[8];
+} SHA1_MB_CTX;
+typedef struct {
+ const unsigned char *ptr;
+ int blocks;
+} HASH_DESC;
+
+void sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int);
+
+typedef struct {
+ const unsigned char *inp;
+ unsigned char *out;
+ int blocks;
+ u64 iv[2];
+} CIPH_DESC;
+
+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
+
+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key,
+ unsigned char *out,
+ const unsigned char *inp,
+ size_t inp_len, int n4x)
+{ /* n4x is 1 or 2 */
+ HASH_DESC hash_d[8], edges[8];
+ CIPH_DESC ciph_d[8];
+ unsigned char storage[sizeof(SHA1_MB_CTX) + 32];
+ union {
+ u64 q[16];
+ u32 d[32];
+ u8 c[128];
+ } blocks[8];
+ SHA1_MB_CTX *ctx;
+ unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
+ 0;
+ size_t ret = 0;
+ u8 *IVs;
+# if defined(BSWAP8)
+ u64 seqnum;
+# endif
+
+ /* ask for IVs in bulk */
+ if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
+ return 0;
+
+ ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */
+
+ frag = (unsigned int)inp_len >> (1 + n4x);
+ last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
+ if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 20 + 16) & -16);
+
+ /* populate descriptors with pointers and IVs */
+ hash_d[0].ptr = inp;
+ ciph_d[0].inp = inp;
+ /* 5+16 is place for header and explicit IV */
+ ciph_d[0].out = out + 5 + 16;
+ memcpy(ciph_d[0].out - 16, IVs, 16);
+ memcpy(ciph_d[0].iv, IVs, 16);
+ IVs += 16;
+
+ for (i = 1; i < x4; i++) {
+ ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
+ ciph_d[i].out = ciph_d[i - 1].out + packlen;
+ memcpy(ciph_d[i].out - 16, IVs, 16);
+ memcpy(ciph_d[i].iv, IVs, 16);
+ IVs += 16;
+ }
+
+# if defined(BSWAP8)
+ memcpy(blocks[0].c, key->md.data, 8);
+ seqnum = BSWAP8(blocks[0].q[0]);
+# endif
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag);
+# if !defined(BSWAP8)
+ unsigned int carry, j;
+# endif
+
+ ctx->A[i] = key->md.h0;
+ ctx->B[i] = key->md.h1;
+ ctx->C[i] = key->md.h2;
+ ctx->D[i] = key->md.h3;
+ ctx->E[i] = key->md.h4;
+
+ /* fix seqnum */
+# if defined(BSWAP8)
+ blocks[i].q[0] = BSWAP8(seqnum + i);
+# else
+ for (carry = i, j = 8; j--;) {
+ blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
+ carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
+ }
+# endif
+ blocks[i].c[8] = ((u8 *)key->md.data)[8];
+ blocks[i].c[9] = ((u8 *)key->md.data)[9];
+ blocks[i].c[10] = ((u8 *)key->md.data)[10];
+ /* fix length */
+ blocks[i].c[11] = (u8)(len >> 8);
+ blocks[i].c[12] = (u8)(len);
+
+ memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
+ hash_d[i].ptr += 64 - 13;
+ hash_d[i].blocks = (len - (64 - 13)) / 64;
+
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* hash 13-byte headers and first 64-13 bytes of inputs */
+ sha1_multi_block(ctx, edges, n4x);
+ /* hash bulk inputs */
+# define MAXCHUNKSIZE 2048
+# if MAXCHUNKSIZE%64
+# error "MAXCHUNKSIZE is not divisible by 64"
+# elif MAXCHUNKSIZE
+ /*
+ * goal is to minimize pressure on L1 cache by moving in shorter steps,
+ * so that hashed data is still in the cache by the time we encrypt it
+ */
+ minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
+ if (minblocks > MAXCHUNKSIZE / 64) {
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ }
+ do {
+ sha1_multi_block(ctx, edges, n4x);
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
+ hash_d[i].blocks -= MAXCHUNKSIZE / 64;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].inp += MAXCHUNKSIZE;
+ ciph_d[i].out += MAXCHUNKSIZE;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
+ }
+ processed += MAXCHUNKSIZE;
+ minblocks -= MAXCHUNKSIZE / 64;
+ } while (minblocks > MAXCHUNKSIZE / 64);
+ }
+# endif
+# undef MAXCHUNKSIZE
+ sha1_multi_block(ctx, hash_d, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag),
+ off = hash_d[i].blocks * 64;
+ const unsigned char *ptr = hash_d[i].ptr + off;
+
+ off = (len - processed) - (64 - 13) - off; /* remainder actually */
+ memcpy(blocks[i].c, ptr, off);
+ blocks[i].c[off] = 0x80;
+ len += 64 + 13; /* 64 is HMAC header */
+ len *= 8; /* convert to bits */
+ if (off < (64 - 8)) {
+# ifdef BSWAP4
+ blocks[i].d[15] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 60, len);
+# endif
+ edges[i].blocks = 1;
+ } else {
+# ifdef BSWAP4
+ blocks[i].d[31] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 124, len);
+# endif
+ edges[i].blocks = 2;
+ }
+ edges[i].ptr = blocks[i].c;
+ }
+
+ /* hash input tails and finalize */
+ sha1_multi_block(ctx, edges, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+# ifdef BSWAP4
+ blocks[i].d[0] = BSWAP4(ctx->A[i]);
+ ctx->A[i] = key->tail.h0;
+ blocks[i].d[1] = BSWAP4(ctx->B[i]);
+ ctx->B[i] = key->tail.h1;
+ blocks[i].d[2] = BSWAP4(ctx->C[i]);
+ ctx->C[i] = key->tail.h2;
+ blocks[i].d[3] = BSWAP4(ctx->D[i]);
+ ctx->D[i] = key->tail.h3;
+ blocks[i].d[4] = BSWAP4(ctx->E[i]);
+ ctx->E[i] = key->tail.h4;
+ blocks[i].c[20] = 0x80;
+ blocks[i].d[15] = BSWAP4((64 + 20) * 8);
+# else
+ PUTU32(blocks[i].c + 0, ctx->A[i]);
+ ctx->A[i] = key->tail.h0;
+ PUTU32(blocks[i].c + 4, ctx->B[i]);
+ ctx->B[i] = key->tail.h1;
+ PUTU32(blocks[i].c + 8, ctx->C[i]);
+ ctx->C[i] = key->tail.h2;
+ PUTU32(blocks[i].c + 12, ctx->D[i]);
+ ctx->D[i] = key->tail.h3;
+ PUTU32(blocks[i].c + 16, ctx->E[i]);
+ ctx->E[i] = key->tail.h4;
+ blocks[i].c[20] = 0x80;
+ PUTU32(blocks[i].c + 60, (64 + 20) * 8);
+# endif
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* finalize MACs */
+ sha1_multi_block(ctx, edges, n4x);
+
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
+ unsigned char *out0 = out;
+
+ memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
+ ciph_d[i].inp = ciph_d[i].out;
+
+ out += 5 + 16 + len;
+
+ /* write MAC */
+ PUTU32(out + 0, ctx->A[i]);
+ PUTU32(out + 4, ctx->B[i]);
+ PUTU32(out + 8, ctx->C[i]);
+ PUTU32(out + 12, ctx->D[i]);
+ PUTU32(out + 16, ctx->E[i]);
+ out += 20;
+ len += 20;
+
+ /* pad */
+ pad = 15 - len % 16;
+ for (j = 0; j <= pad; j++)
+ *(out++) = pad;
+ len += pad + 1;
+
+ ciph_d[i].blocks = (len - processed) / 16;
+ len += 16; /* account for explicit iv */
+
+ /* arrange header */
+ out0[0] = ((u8 *)key->md.data)[8];
+ out0[1] = ((u8 *)key->md.data)[9];
+ out0[2] = ((u8 *)key->md.data)[10];
+ out0[3] = (u8)(len >> 8);
+ out0[4] = (u8)(len);
+
+ ret += len + 5;
+ inp += frag;
+ }
+
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ OPENSSL_cleanse(blocks, sizeof(blocks));
+ OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+ return ret;
+}
+# endif
+
+static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ unsigned int l;
+ size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
+ * later */
+ sha_off = 0;
+# if defined(STITCHED_CALL)
+ size_t aes_off = 0, blocks;
+
+ sha_off = SHA_CBLOCK - key->md.num;
+# endif
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ if (len % AES_BLOCK_SIZE)
+ return 0;
+
+ if (ctx->encrypt) {
+ if (plen == NO_PAYLOAD_LENGTH)
+ plen = len;
+ else if (len !=
+ ((plen + SHA_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
+ return 0;
+ else if (key->aux.tls_ver >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+# if defined(STITCHED_CALL)
+ if (plen > (sha_off + iv)
+ && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) {
+ SHA1_Update(&key->md, in + iv, sha_off);
+
+ aesni_cbc_sha1_enc(in, out, blocks, &key->ks,
+ ctx->iv, &key->md, in + iv + sha_off);
+ blocks *= SHA_CBLOCK;
+ aes_off += blocks;
+ sha_off += blocks;
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else {
+ sha_off = 0;
+ }
+# endif
+ sha_off += iv;
+ SHA1_Update(&key->md, in + sha_off, plen - sha_off);
+
+ if (plen != len) { /* "TLS" mode of operation */
+ if (in != out)
+ memcpy(out + aes_off, in + aes_off, plen - aes_off);
+
+ /* calculate HMAC and append it to payload */
+ SHA1_Final(out + plen, &key->md);
+ key->md = key->tail;
+ SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH);
+ SHA1_Final(out + plen, &key->md);
+
+ /* pad the payload|hmac */
+ plen += SHA_DIGEST_LENGTH;
+ for (l = len - plen - 1; plen < len; plen++)
+ out[plen] = l;
+ /* encrypt HMAC|padding at once */
+ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ } else {
+ aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ }
+ } else {
+ union {
+ unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)];
+ unsigned char c[32 + SHA_DIGEST_LENGTH];
+ } mac, *pmac;
+
+ /* arrange cache line alignment */
+ pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32));
+
+ if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ size_t inp_len, mask, j, i;
+ unsigned int res, maxpad, pad, bitlen;
+ int ret = 1;
+ union {
+ unsigned int u[SHA_LBLOCK];
+ unsigned char c[SHA_CBLOCK];
+ } *data = (void *)key->md.data;
+# if defined(STITCHED_DECRYPT_CALL)
+ unsigned char tail_iv[AES_BLOCK_SIZE];
+ int stitch = 0;
+# endif
+
+ if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
+ >= TLS1_1_VERSION) {
+ if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))
+ return 0;
+
+ /* omit explicit iv */
+ memcpy(ctx->iv, in, AES_BLOCK_SIZE);
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ len -= AES_BLOCK_SIZE;
+ } else if (len < (SHA_DIGEST_LENGTH + 1))
+ return 0;
+
+# if defined(STITCHED_DECRYPT_CALL)
+ if (len >= 1024 && ctx->key_len == 32) {
+ /* decrypt last block */
+ memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE,
+ AES_BLOCK_SIZE);
+ aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE,
+ out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE,
+ &key->ks, tail_iv, 0);
+ stitch = 1;
+ } else
+# endif
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+ /* figure out payload length */
+ pad = out[len - 1];
+ maxpad = len - (SHA_DIGEST_LENGTH + 1);
+ maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+ maxpad &= 255;
+
+ ret &= constant_time_ge(maxpad, pad);
+
+ inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
+ mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
+ inp_len &= mask;
+ ret &= (int)mask;
+
+ key->aux.tls_aad[plen - 2] = inp_len >> 8;
+ key->aux.tls_aad[plen - 1] = inp_len;
+
+ /* calculate HMAC */
+ key->md = key->head;
+ SHA1_Update(&key->md, key->aux.tls_aad, plen);
+
+# if defined(STITCHED_DECRYPT_CALL)
+ if (stitch) {
+ blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK;
+ aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK;
+ sha_off = SHA_CBLOCK - plen;
+
+ aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
+
+ SHA1_Update(&key->md, out, sha_off);
+ aesni256_cbc_sha1_dec(in + aes_off,
+ out + aes_off, blocks, &key->ks,
+ ctx->iv, &key->md, out + sha_off);
+
+ sha_off += blocks *= SHA_CBLOCK;
+ out += sha_off;
+ len -= sha_off;
+ inp_len -= sha_off;
+
+ key->md.Nl += (blocks << 3); /* at most 18 bits */
+ memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE);
+ }
+# endif
+
+# if 1
+ len -= SHA_DIGEST_LENGTH; /* amend mac */
+ if (len >= (256 + SHA_CBLOCK)) {
+ j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK);
+ j += SHA_CBLOCK - key->md.num;
+ SHA1_Update(&key->md, out, j);
+ out += j;
+ len -= j;
+ inp_len -= j;
+ }
+
+ /* but pretend as if we hashed padded payload */
+ bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
+# ifdef BSWAP4
+ bitlen = BSWAP4(bitlen);
+# else
+ mac.c[0] = 0;
+ mac.c[1] = (unsigned char)(bitlen >> 16);
+ mac.c[2] = (unsigned char)(bitlen >> 8);
+ mac.c[3] = (unsigned char)bitlen;
+ bitlen = mac.u[0];
+# endif
+
+ pmac->u[0] = 0;
+ pmac->u[1] = 0;
+ pmac->u[2] = 0;
+ pmac->u[3] = 0;
+ pmac->u[4] = 0;
+
+ for (res = key->md.num, j = 0; j < len; j++) {
+ size_t c = out[j];
+ mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+ c &= mask;
+ c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+ data->c[res++] = (unsigned char)c;
+
+ if (res != SHA_CBLOCK)
+ continue;
+
+ /* j is not incremented yet */
+ mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha1_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+ res = 0;
+ }
+
+ for (i = res; i < SHA_CBLOCK; i++, j++)
+ data->c[i] = 0;
+
+ if (res > SHA_CBLOCK - 8) {
+ mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha1_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+ memset(data, 0, SHA_CBLOCK);
+ j += 64;
+ }
+ data->u[SHA_LBLOCK - 1] = bitlen;
+ sha1_block_data_order(&key->md, data, 1);
+ mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+# ifdef BSWAP4
+ pmac->u[0] = BSWAP4(pmac->u[0]);
+ pmac->u[1] = BSWAP4(pmac->u[1]);
+ pmac->u[2] = BSWAP4(pmac->u[2]);
+ pmac->u[3] = BSWAP4(pmac->u[3]);
+ pmac->u[4] = BSWAP4(pmac->u[4]);
+# else
+ for (i = 0; i < 5; i++) {
+ res = pmac->u[i];
+ pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+ pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+ pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+ pmac->c[4 * i + 3] = (unsigned char)res;
+ }
+# endif
+ len += SHA_DIGEST_LENGTH;
+# else
+ SHA1_Update(&key->md, out, inp_len);
+ res = key->md.num;
+ SHA1_Final(pmac->c, &key->md);
+
+ {
+ unsigned int inp_blocks, pad_blocks;
+
+ /* but pretend as if we hashed padded payload */
+ inp_blocks =
+ 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ res += (unsigned int)(len - inp_len);
+ pad_blocks = res / SHA_CBLOCK;
+ res %= SHA_CBLOCK;
+ pad_blocks +=
+ 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ for (; inp_blocks < pad_blocks; inp_blocks++)
+ sha1_block_data_order(&key->md, data, 1);
+ }
+# endif
+ key->md = key->tail;
+ SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH);
+ SHA1_Final(pmac->c, &key->md);
+
+ /* verify HMAC */
+ out += inp_len;
+ len -= inp_len;
+# if 1
+ {
+ unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH;
+ size_t off = out - p;
+ unsigned int c, cmask;
+
+ maxpad += SHA_DIGEST_LENGTH;
+ for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+ c = p[j];
+ cmask =
+ ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) *
+ 8 - 1);
+ res |= (c ^ pad) & ~cmask; /* ... and padding */
+ cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
+ res |= (c ^ pmac->c[i]) & cmask;
+ i += 1 & cmask;
+ }
+ maxpad -= SHA_DIGEST_LENGTH;
+
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+ }
+# else
+ for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++)
+ res |= out[i] ^ pmac->c[i];
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+
+ /* verify padding */
+ pad = (pad & ~res) | (maxpad & res);
+ out = out + len - 1 - pad;
+ for (res = 0, i = 0; i < pad; i++)
+ res |= out[i] ^ pad;
+
+ res = (0 - res) >> (sizeof(res) * 8 - 1);
+ ret &= (int)~res;
+# endif
+ return ret;
+ } else {
+# if defined(STITCHED_DECRYPT_CALL)
+ if (len >= 1024 && ctx->key_len == 32) {
+ if (sha_off %= SHA_CBLOCK)
+ blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK;
+ else
+ blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK;
+ aes_off = len - blocks * SHA_CBLOCK;
+
+ aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
+ SHA1_Update(&key->md, out, sha_off);
+ aesni256_cbc_sha1_dec(in + aes_off,
+ out + aes_off, blocks, &key->ks,
+ ctx->iv, &key->md, out + sha_off);
+
+ sha_off += blocks *= SHA_CBLOCK;
+ out += sha_off;
+ len -= sha_off;
+
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else
+# endif
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+ SHA1_Update(&key->md, out, len);
+ }
+ }
+
+ return 1;
+}
+
+static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr)
+{
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+
+ switch (type) {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset(hmac_key, 0, sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head, ptr, arg);
+ SHA1_Final(hmac_key, &key->head);
+ } else {
+ memcpy(hmac_key, ptr, arg);
+ }
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+ SHA1_Init(&key->tail);
+ SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+ OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p = ptr;
+ unsigned int len;
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
+
+ if (ctx->encrypt) {
+ key->payload_length = len;
+ if ((key->aux.tls_ver =
+ p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+ len -= AES_BLOCK_SIZE;
+ p[arg - 2] = len >> 8;
+ p[arg - 1] = len;
+ }
+ key->md = key->head;
+ SHA1_Update(&key->md, p, arg);
+
+ return (int)(((len + SHA_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
+ - len);
+ } else {
+ memcpy(key->aux.tls_aad, ptr, arg);
+ key->payload_length = arg;
+
+ return SHA_DIGEST_LENGTH;
+ }
+ }
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
+ return (int)(5 + 16 + ((arg + 20 + 16) & -16));
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+ unsigned int n4x = 1, x4;
+ unsigned int frag, last, packlen, inp_len;
+
+ if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
+ return -1;
+
+ inp_len = param->inp[11] << 8 | param->inp[12];
+
+ if (ctx->encrypt) {
+ if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
+ return -1;
+
+ if (inp_len) {
+ if (inp_len < 4096)
+ return 0; /* too short */
+
+ if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
+ n4x = 2; /* AVX2 */
+ } else if ((n4x = param->interleave / 4) && n4x <= 2)
+ inp_len = param->len;
+ else
+ return -1;
+
+ key->md = key->head;
+ SHA1_Update(&key->md, param->inp, 13);
+
+ x4 = 4 * n4x;
+ n4x += 1;
+
+ frag = inp_len >> n4x;
+ last = inp_len + frag - (frag << n4x);
+ if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 20 + 16) & -16);
+ packlen = (packlen << n4x) - packlen;
+ packlen += 5 + 16 + ((last + 20 + 16) & -16);
+
+ param->interleave = x4;
+
+ return (int)packlen;
+ } else
+ return -1; /* not yet */
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+
+ return (int)tls1_1_multi_block_encrypt(key, param->out,
+ param->inp, param->len,
+ param->interleave / 4);
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
+# endif
+ default:
+ return -1;
+ }
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = {
+# ifdef NID_aes_128_cbc_hmac_sha1
+ NID_aes_128_cbc_hmac_sha1,
+# else
+ NID_undef,
+# endif
+ 16, 16, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = {
+# ifdef NID_aes_256_cbc_hmac_sha1
+ NID_aes_256_cbc_hmac_sha1,
+# else
+ NID_undef,
+# endif
+ 16, 32, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+{
+ return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+ &aesni_128_cbc_hmac_sha1_cipher : NULL);
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+{
+ return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+ &aesni_256_cbc_hmac_sha1_cipher : NULL);
+}
+# else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+{
+ return NULL;
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+{
+ return NULL;
+}
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
new file mode 100644
index 00000000..46c9d033
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
@@ -0,0 +1,985 @@
+/* ====================================================================
+ * Copyright (c) 2011-2013 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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA256)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/aes.h>
+# include <openssl/sha.h>
+# include <openssl/rand.h>
+# include "modes_lcl.h"
+# include "constant_time_locl.h"
+
+# ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+# endif
+
+# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
+# define EVP_CIPH_FLAG_DEFAULT_ASN1 0
+# endif
+
+# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+# endif
+
+# define TLS1_1_VERSION 0x0302
+
+typedef struct {
+ AES_KEY ks;
+ SHA256_CTX head, tail, md;
+ size_t payload_length; /* AAD length in decrypt case */
+ union {
+ unsigned int tls_ver;
+ unsigned char tls_aad[16]; /* 13 used */
+ } aux;
+} EVP_AES_HMAC_SHA256;
+
+# define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+# if defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+# define AESNI_CAPABLE (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+
+int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA256_CTX *ctx, const void *in0);
+
+# define data(ctx) ((EVP_AES_HMAC_SHA256 *)(ctx)->cipher_data)
+
+static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_HMAC_SHA256 *key = data(ctx);
+ int ret;
+
+ if (enc)
+ memset(&key->ks, 0, sizeof(key->ks.rd_key)),
+ ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks);
+ else
+ ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks);
+
+ SHA256_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return ret < 0 ? 0 : 1;
+}
+
+# define STITCHED_CALL
+
+# if !defined(STITCHED_CALL)
+# define aes_off 0
+# endif
+
+void sha256_block_data_order(void *c, const void *p, size_t len);
+
+static void sha256_update(SHA256_CTX *c, const void *data, size_t len)
+{
+ const unsigned char *ptr = data;
+ size_t res;
+
+ if ((res = c->num)) {
+ res = SHA256_CBLOCK - res;
+ if (len < res)
+ res = len;
+ SHA256_Update(c, ptr, res);
+ ptr += res;
+ len -= res;
+ }
+
+ res = len % SHA256_CBLOCK;
+ len -= res;
+
+ if (len) {
+ sha256_block_data_order(c, ptr, len / SHA256_CBLOCK);
+
+ ptr += len;
+ c->Nh += len >> 29;
+ c->Nl += len <<= 3;
+ if (c->Nl < (unsigned int)len)
+ c->Nh++;
+ }
+
+ if (res)
+ SHA256_Update(c, ptr, res);
+}
+
+# ifdef SHA256_Update
+# undef SHA256_Update
+# endif
+# define SHA256_Update sha256_update
+
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+
+typedef struct {
+ unsigned int A[8], B[8], C[8], D[8], E[8], F[8], G[8], H[8];
+} SHA256_MB_CTX;
+typedef struct {
+ const unsigned char *ptr;
+ int blocks;
+} HASH_DESC;
+
+void sha256_multi_block(SHA256_MB_CTX *, const HASH_DESC *, int);
+
+typedef struct {
+ const unsigned char *inp;
+ unsigned char *out;
+ int blocks;
+ u64 iv[2];
+} CIPH_DESC;
+
+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
+
+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA256 *key,
+ unsigned char *out,
+ const unsigned char *inp,
+ size_t inp_len, int n4x)
+{ /* n4x is 1 or 2 */
+ HASH_DESC hash_d[8], edges[8];
+ CIPH_DESC ciph_d[8];
+ unsigned char storage[sizeof(SHA256_MB_CTX) + 32];
+ union {
+ u64 q[16];
+ u32 d[32];
+ u8 c[128];
+ } blocks[8];
+ SHA256_MB_CTX *ctx;
+ unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
+ 0;
+ size_t ret = 0;
+ u8 *IVs;
+# if defined(BSWAP8)
+ u64 seqnum;
+# endif
+
+ /* ask for IVs in bulk */
+ if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
+ return 0;
+
+ /* align */
+ ctx = (SHA256_MB_CTX *) (storage + 32 - ((size_t)storage % 32));
+
+ frag = (unsigned int)inp_len >> (1 + n4x);
+ last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
+ if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 32 + 16) & -16);
+
+ /* populate descriptors with pointers and IVs */
+ hash_d[0].ptr = inp;
+ ciph_d[0].inp = inp;
+ /* 5+16 is place for header and explicit IV */
+ ciph_d[0].out = out + 5 + 16;
+ memcpy(ciph_d[0].out - 16, IVs, 16);
+ memcpy(ciph_d[0].iv, IVs, 16);
+ IVs += 16;
+
+ for (i = 1; i < x4; i++) {
+ ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
+ ciph_d[i].out = ciph_d[i - 1].out + packlen;
+ memcpy(ciph_d[i].out - 16, IVs, 16);
+ memcpy(ciph_d[i].iv, IVs, 16);
+ IVs += 16;
+ }
+
+# if defined(BSWAP8)
+ memcpy(blocks[0].c, key->md.data, 8);
+ seqnum = BSWAP8(blocks[0].q[0]);
+# endif
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag);
+# if !defined(BSWAP8)
+ unsigned int carry, j;
+# endif
+
+ ctx->A[i] = key->md.h[0];
+ ctx->B[i] = key->md.h[1];
+ ctx->C[i] = key->md.h[2];
+ ctx->D[i] = key->md.h[3];
+ ctx->E[i] = key->md.h[4];
+ ctx->F[i] = key->md.h[5];
+ ctx->G[i] = key->md.h[6];
+ ctx->H[i] = key->md.h[7];
+
+ /* fix seqnum */
+# if defined(BSWAP8)
+ blocks[i].q[0] = BSWAP8(seqnum + i);
+# else
+ for (carry = i, j = 8; j--;) {
+ blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
+ carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
+ }
+# endif
+ blocks[i].c[8] = ((u8 *)key->md.data)[8];
+ blocks[i].c[9] = ((u8 *)key->md.data)[9];
+ blocks[i].c[10] = ((u8 *)key->md.data)[10];
+ /* fix length */
+ blocks[i].c[11] = (u8)(len >> 8);
+ blocks[i].c[12] = (u8)(len);
+
+ memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
+ hash_d[i].ptr += 64 - 13;
+ hash_d[i].blocks = (len - (64 - 13)) / 64;
+
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* hash 13-byte headers and first 64-13 bytes of inputs */
+ sha256_multi_block(ctx, edges, n4x);
+ /* hash bulk inputs */
+# define MAXCHUNKSIZE 2048
+# if MAXCHUNKSIZE%64
+# error "MAXCHUNKSIZE is not divisible by 64"
+# elif MAXCHUNKSIZE
+ /*
+ * goal is to minimize pressure on L1 cache by moving in shorter steps,
+ * so that hashed data is still in the cache by the time we encrypt it
+ */
+ minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
+ if (minblocks > MAXCHUNKSIZE / 64) {
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ }
+ do {
+ sha256_multi_block(ctx, edges, n4x);
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
+ hash_d[i].blocks -= MAXCHUNKSIZE / 64;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].inp += MAXCHUNKSIZE;
+ ciph_d[i].out += MAXCHUNKSIZE;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
+ }
+ processed += MAXCHUNKSIZE;
+ minblocks -= MAXCHUNKSIZE / 64;
+ } while (minblocks > MAXCHUNKSIZE / 64);
+ }
+# endif
+# undef MAXCHUNKSIZE
+ sha256_multi_block(ctx, hash_d, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag),
+ off = hash_d[i].blocks * 64;
+ const unsigned char *ptr = hash_d[i].ptr + off;
+
+ off = (len - processed) - (64 - 13) - off; /* remainder actually */
+ memcpy(blocks[i].c, ptr, off);
+ blocks[i].c[off] = 0x80;
+ len += 64 + 13; /* 64 is HMAC header */
+ len *= 8; /* convert to bits */
+ if (off < (64 - 8)) {
+# ifdef BSWAP4
+ blocks[i].d[15] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 60, len);
+# endif
+ edges[i].blocks = 1;
+ } else {
+# ifdef BSWAP4
+ blocks[i].d[31] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 124, len);
+# endif
+ edges[i].blocks = 2;
+ }
+ edges[i].ptr = blocks[i].c;
+ }
+
+ /* hash input tails and finalize */
+ sha256_multi_block(ctx, edges, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+# ifdef BSWAP4
+ blocks[i].d[0] = BSWAP4(ctx->A[i]);
+ ctx->A[i] = key->tail.h[0];
+ blocks[i].d[1] = BSWAP4(ctx->B[i]);
+ ctx->B[i] = key->tail.h[1];
+ blocks[i].d[2] = BSWAP4(ctx->C[i]);
+ ctx->C[i] = key->tail.h[2];
+ blocks[i].d[3] = BSWAP4(ctx->D[i]);
+ ctx->D[i] = key->tail.h[3];
+ blocks[i].d[4] = BSWAP4(ctx->E[i]);
+ ctx->E[i] = key->tail.h[4];
+ blocks[i].d[5] = BSWAP4(ctx->F[i]);
+ ctx->F[i] = key->tail.h[5];
+ blocks[i].d[6] = BSWAP4(ctx->G[i]);
+ ctx->G[i] = key->tail.h[6];
+ blocks[i].d[7] = BSWAP4(ctx->H[i]);
+ ctx->H[i] = key->tail.h[7];
+ blocks[i].c[32] = 0x80;
+ blocks[i].d[15] = BSWAP4((64 + 32) * 8);
+# else
+ PUTU32(blocks[i].c + 0, ctx->A[i]);
+ ctx->A[i] = key->tail.h[0];
+ PUTU32(blocks[i].c + 4, ctx->B[i]);
+ ctx->B[i] = key->tail.h[1];
+ PUTU32(blocks[i].c + 8, ctx->C[i]);
+ ctx->C[i] = key->tail.h[2];
+ PUTU32(blocks[i].c + 12, ctx->D[i]);
+ ctx->D[i] = key->tail.h[3];
+ PUTU32(blocks[i].c + 16, ctx->E[i]);
+ ctx->E[i] = key->tail.h[4];
+ PUTU32(blocks[i].c + 20, ctx->F[i]);
+ ctx->F[i] = key->tail.h[5];
+ PUTU32(blocks[i].c + 24, ctx->G[i]);
+ ctx->G[i] = key->tail.h[6];
+ PUTU32(blocks[i].c + 28, ctx->H[i]);
+ ctx->H[i] = key->tail.h[7];
+ blocks[i].c[32] = 0x80;
+ PUTU32(blocks[i].c + 60, (64 + 32) * 8);
+# endif
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* finalize MACs */
+ sha256_multi_block(ctx, edges, n4x);
+
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
+ unsigned char *out0 = out;
+
+ memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
+ ciph_d[i].inp = ciph_d[i].out;
+
+ out += 5 + 16 + len;
+
+ /* write MAC */
+ PUTU32(out + 0, ctx->A[i]);
+ PUTU32(out + 4, ctx->B[i]);
+ PUTU32(out + 8, ctx->C[i]);
+ PUTU32(out + 12, ctx->D[i]);
+ PUTU32(out + 16, ctx->E[i]);
+ PUTU32(out + 20, ctx->F[i]);
+ PUTU32(out + 24, ctx->G[i]);
+ PUTU32(out + 28, ctx->H[i]);
+ out += 32;
+ len += 32;
+
+ /* pad */
+ pad = 15 - len % 16;
+ for (j = 0; j <= pad; j++)
+ *(out++) = pad;
+ len += pad + 1;
+
+ ciph_d[i].blocks = (len - processed) / 16;
+ len += 16; /* account for explicit iv */
+
+ /* arrange header */
+ out0[0] = ((u8 *)key->md.data)[8];
+ out0[1] = ((u8 *)key->md.data)[9];
+ out0[2] = ((u8 *)key->md.data)[10];
+ out0[3] = (u8)(len >> 8);
+ out0[4] = (u8)(len);
+
+ ret += len + 5;
+ inp += frag;
+ }
+
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ OPENSSL_cleanse(blocks, sizeof(blocks));
+ OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+ return ret;
+}
+# endif
+
+static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_HMAC_SHA256 *key = data(ctx);
+ unsigned int l;
+ size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
+ * later */
+ sha_off = 0;
+# if defined(STITCHED_CALL)
+ size_t aes_off = 0, blocks;
+
+ sha_off = SHA256_CBLOCK - key->md.num;
+# endif
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ if (len % AES_BLOCK_SIZE)
+ return 0;
+
+ if (ctx->encrypt) {
+ if (plen == NO_PAYLOAD_LENGTH)
+ plen = len;
+ else if (len !=
+ ((plen + SHA256_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
+ return 0;
+ else if (key->aux.tls_ver >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+# if defined(STITCHED_CALL)
+ /*
+ * Assembly stitch handles AVX-capable processors, but its
+ * performance is not optimal on AMD Jaguar, ~40% worse, for
+ * unknown reasons. Incidentally processor in question supports
+ * AVX, but not AMD-specific XOP extension, which can be used
+ * to identify it and avoid stitch invocation. So that after we
+ * establish that current CPU supports AVX, we even see if it's
+ * either even XOP-capable Bulldozer-based or GenuineIntel one.
+ */
+ if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */
+ ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */
+ | (OPENSSL_ia32cap_P[0] & (1<<30))) && /* "Intel CPU"? */
+ plen > (sha_off + iv) &&
+ (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) {
+ SHA256_Update(&key->md, in + iv, sha_off);
+
+ (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks,
+ ctx->iv, &key->md, in + iv + sha_off);
+ blocks *= SHA256_CBLOCK;
+ aes_off += blocks;
+ sha_off += blocks;
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else {
+ sha_off = 0;
+ }
+# endif
+ sha_off += iv;
+ SHA256_Update(&key->md, in + sha_off, plen - sha_off);
+
+ if (plen != len) { /* "TLS" mode of operation */
+ if (in != out)
+ memcpy(out + aes_off, in + aes_off, plen - aes_off);
+
+ /* calculate HMAC and append it to payload */
+ SHA256_Final(out + plen, &key->md);
+ key->md = key->tail;
+ SHA256_Update(&key->md, out + plen, SHA256_DIGEST_LENGTH);
+ SHA256_Final(out + plen, &key->md);
+
+ /* pad the payload|hmac */
+ plen += SHA256_DIGEST_LENGTH;
+ for (l = len - plen - 1; plen < len; plen++)
+ out[plen] = l;
+ /* encrypt HMAC|padding at once */
+ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ } else {
+ aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ }
+ } else {
+ union {
+ unsigned int u[SHA256_DIGEST_LENGTH / sizeof(unsigned int)];
+ unsigned char c[64 + SHA256_DIGEST_LENGTH];
+ } mac, *pmac;
+
+ /* arrange cache line alignment */
+ pmac = (void *)(((size_t)mac.c + 63) & ((size_t)0 - 64));
+
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+ if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ size_t inp_len, mask, j, i;
+ unsigned int res, maxpad, pad, bitlen;
+ int ret = 1;
+ union {
+ unsigned int u[SHA_LBLOCK];
+ unsigned char c[SHA256_CBLOCK];
+ } *data = (void *)key->md.data;
+
+ if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
+ >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+ if (len < (iv + SHA256_DIGEST_LENGTH + 1))
+ return 0;
+
+ /* omit explicit iv */
+ out += iv;
+ len -= iv;
+
+ /* figure out payload length */
+ pad = out[len - 1];
+ maxpad = len - (SHA256_DIGEST_LENGTH + 1);
+ maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+ maxpad &= 255;
+
+ ret &= constant_time_ge(maxpad, pad);
+
+ inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
+ mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
+ inp_len &= mask;
+ ret &= (int)mask;
+
+ key->aux.tls_aad[plen - 2] = inp_len >> 8;
+ key->aux.tls_aad[plen - 1] = inp_len;
+
+ /* calculate HMAC */
+ key->md = key->head;
+ SHA256_Update(&key->md, key->aux.tls_aad, plen);
+
+# if 1
+ len -= SHA256_DIGEST_LENGTH; /* amend mac */
+ if (len >= (256 + SHA256_CBLOCK)) {
+ j = (len - (256 + SHA256_CBLOCK)) & (0 - SHA256_CBLOCK);
+ j += SHA256_CBLOCK - key->md.num;
+ SHA256_Update(&key->md, out, j);
+ out += j;
+ len -= j;
+ inp_len -= j;
+ }
+
+ /* but pretend as if we hashed padded payload */
+ bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
+# ifdef BSWAP4
+ bitlen = BSWAP4(bitlen);
+# else
+ mac.c[0] = 0;
+ mac.c[1] = (unsigned char)(bitlen >> 16);
+ mac.c[2] = (unsigned char)(bitlen >> 8);
+ mac.c[3] = (unsigned char)bitlen;
+ bitlen = mac.u[0];
+# endif
+
+ pmac->u[0] = 0;
+ pmac->u[1] = 0;
+ pmac->u[2] = 0;
+ pmac->u[3] = 0;
+ pmac->u[4] = 0;
+ pmac->u[5] = 0;
+ pmac->u[6] = 0;
+ pmac->u[7] = 0;
+
+ for (res = key->md.num, j = 0; j < len; j++) {
+ size_t c = out[j];
+ mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+ c &= mask;
+ c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+ data->c[res++] = (unsigned char)c;
+
+ if (res != SHA256_CBLOCK)
+ continue;
+
+ /* j is not incremented yet */
+ mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha256_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h[0] & mask;
+ pmac->u[1] |= key->md.h[1] & mask;
+ pmac->u[2] |= key->md.h[2] & mask;
+ pmac->u[3] |= key->md.h[3] & mask;
+ pmac->u[4] |= key->md.h[4] & mask;
+ pmac->u[5] |= key->md.h[5] & mask;
+ pmac->u[6] |= key->md.h[6] & mask;
+ pmac->u[7] |= key->md.h[7] & mask;
+ res = 0;
+ }
+
+ for (i = res; i < SHA256_CBLOCK; i++, j++)
+ data->c[i] = 0;
+
+ if (res > SHA256_CBLOCK - 8) {
+ mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha256_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h[0] & mask;
+ pmac->u[1] |= key->md.h[1] & mask;
+ pmac->u[2] |= key->md.h[2] & mask;
+ pmac->u[3] |= key->md.h[3] & mask;
+ pmac->u[4] |= key->md.h[4] & mask;
+ pmac->u[5] |= key->md.h[5] & mask;
+ pmac->u[6] |= key->md.h[6] & mask;
+ pmac->u[7] |= key->md.h[7] & mask;
+
+ memset(data, 0, SHA256_CBLOCK);
+ j += 64;
+ }
+ data->u[SHA_LBLOCK - 1] = bitlen;
+ sha256_block_data_order(&key->md, data, 1);
+ mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h[0] & mask;
+ pmac->u[1] |= key->md.h[1] & mask;
+ pmac->u[2] |= key->md.h[2] & mask;
+ pmac->u[3] |= key->md.h[3] & mask;
+ pmac->u[4] |= key->md.h[4] & mask;
+ pmac->u[5] |= key->md.h[5] & mask;
+ pmac->u[6] |= key->md.h[6] & mask;
+ pmac->u[7] |= key->md.h[7] & mask;
+
+# ifdef BSWAP4
+ pmac->u[0] = BSWAP4(pmac->u[0]);
+ pmac->u[1] = BSWAP4(pmac->u[1]);
+ pmac->u[2] = BSWAP4(pmac->u[2]);
+ pmac->u[3] = BSWAP4(pmac->u[3]);
+ pmac->u[4] = BSWAP4(pmac->u[4]);
+ pmac->u[5] = BSWAP4(pmac->u[5]);
+ pmac->u[6] = BSWAP4(pmac->u[6]);
+ pmac->u[7] = BSWAP4(pmac->u[7]);
+# else
+ for (i = 0; i < 8; i++) {
+ res = pmac->u[i];
+ pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+ pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+ pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+ pmac->c[4 * i + 3] = (unsigned char)res;
+ }
+# endif
+ len += SHA256_DIGEST_LENGTH;
+# else
+ SHA256_Update(&key->md, out, inp_len);
+ res = key->md.num;
+ SHA256_Final(pmac->c, &key->md);
+
+ {
+ unsigned int inp_blocks, pad_blocks;
+
+ /* but pretend as if we hashed padded payload */
+ inp_blocks =
+ 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ res += (unsigned int)(len - inp_len);
+ pad_blocks = res / SHA256_CBLOCK;
+ res %= SHA256_CBLOCK;
+ pad_blocks +=
+ 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ for (; inp_blocks < pad_blocks; inp_blocks++)
+ sha1_block_data_order(&key->md, data, 1);
+ }
+# endif
+ key->md = key->tail;
+ SHA256_Update(&key->md, pmac->c, SHA256_DIGEST_LENGTH);
+ SHA256_Final(pmac->c, &key->md);
+
+ /* verify HMAC */
+ out += inp_len;
+ len -= inp_len;
+# if 1
+ {
+ unsigned char *p =
+ out + len - 1 - maxpad - SHA256_DIGEST_LENGTH;
+ size_t off = out - p;
+ unsigned int c, cmask;
+
+ maxpad += SHA256_DIGEST_LENGTH;
+ for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+ c = p[j];
+ cmask =
+ ((int)(j - off - SHA256_DIGEST_LENGTH)) >>
+ (sizeof(int) * 8 - 1);
+ res |= (c ^ pad) & ~cmask; /* ... and padding */
+ cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
+ res |= (c ^ pmac->c[i]) & cmask;
+ i += 1 & cmask;
+ }
+ maxpad -= SHA256_DIGEST_LENGTH;
+
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+ }
+# else
+ for (res = 0, i = 0; i < SHA256_DIGEST_LENGTH; i++)
+ res |= out[i] ^ pmac->c[i];
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+
+ /* verify padding */
+ pad = (pad & ~res) | (maxpad & res);
+ out = out + len - 1 - pad;
+ for (res = 0, i = 0; i < pad; i++)
+ res |= out[i] ^ pad;
+
+ res = (0 - res) >> (sizeof(res) * 8 - 1);
+ ret &= (int)~res;
+# endif
+ return ret;
+ } else {
+ SHA256_Update(&key->md, out, len);
+ }
+ }
+
+ return 1;
+}
+
+static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr)
+{
+ EVP_AES_HMAC_SHA256 *key = data(ctx);
+
+ switch (type) {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset(hmac_key, 0, sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ SHA256_Init(&key->head);
+ SHA256_Update(&key->head, ptr, arg);
+ SHA256_Final(hmac_key, &key->head);
+ } else {
+ memcpy(hmac_key, ptr, arg);
+ }
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ SHA256_Init(&key->head);
+ SHA256_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+ SHA256_Init(&key->tail);
+ SHA256_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+ OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p = ptr;
+ unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ if (ctx->encrypt) {
+ key->payload_length = len;
+ if ((key->aux.tls_ver =
+ p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+ len -= AES_BLOCK_SIZE;
+ p[arg - 2] = len >> 8;
+ p[arg - 1] = len;
+ }
+ key->md = key->head;
+ SHA256_Update(&key->md, p, arg);
+
+ return (int)(((len + SHA256_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
+ - len);
+ } else {
+ memcpy(key->aux.tls_aad, ptr, arg);
+ key->payload_length = arg;
+
+ return SHA256_DIGEST_LENGTH;
+ }
+ }
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
+ return (int)(5 + 16 + ((arg + 32 + 16) & -16));
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+ unsigned int n4x = 1, x4;
+ unsigned int frag, last, packlen, inp_len;
+
+ if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
+ return -1;
+
+ inp_len = param->inp[11] << 8 | param->inp[12];
+
+ if (ctx->encrypt) {
+ if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
+ return -1;
+
+ if (inp_len) {
+ if (inp_len < 4096)
+ return 0; /* too short */
+
+ if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
+ n4x = 2; /* AVX2 */
+ } else if ((n4x = param->interleave / 4) && n4x <= 2)
+ inp_len = param->len;
+ else
+ return -1;
+
+ key->md = key->head;
+ SHA256_Update(&key->md, param->inp, 13);
+
+ x4 = 4 * n4x;
+ n4x += 1;
+
+ frag = inp_len >> n4x;
+ last = inp_len + frag - (frag << n4x);
+ if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 32 + 16) & -16);
+ packlen = (packlen << n4x) - packlen;
+ packlen += 5 + 16 + ((last + 32 + 16) & -16);
+
+ param->interleave = x4;
+
+ return (int)packlen;
+ } else
+ return -1; /* not yet */
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+
+ return (int)tls1_1_multi_block_encrypt(key, param->out,
+ param->inp, param->len,
+ param->interleave / 4);
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
+# endif
+ default:
+ return -1;
+ }
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = {
+# ifdef NID_aes_128_cbc_hmac_sha256
+ NID_aes_128_cbc_hmac_sha256,
+# else
+ NID_undef,
+# endif
+ 16, 16, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha256_init_key,
+ aesni_cbc_hmac_sha256_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA256),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha256_ctrl,
+ NULL
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = {
+# ifdef NID_aes_256_cbc_hmac_sha256
+ NID_aes_256_cbc_hmac_sha256,
+# else
+ NID_undef,
+# endif
+ 16, 32, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha256_init_key,
+ aesni_cbc_hmac_sha256_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA256),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha256_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
+{
+ return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
+ aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
+ &aesni_128_cbc_hmac_sha256_cipher : NULL);
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
+{
+ return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
+ aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
+ &aesni_256_cbc_hmac_sha256_cipher : NULL);
+}
+# else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
+{
+ return NULL;
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
+{
+ return NULL;
+}
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_bf.c b/Cryptlib/OpenSSL/crypto/evp/e_bf.c
new file mode 100644
index 00000000..d6a01782
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_bf.c
@@ -0,0 +1,87 @@
+/* crypto/evp/e_bf.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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_BF
+# include <openssl/evp.h>
+# include "evp_locl.h"
+# include <openssl/objects.h>
+# include <openssl/blowfish.h>
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+typedef struct {
+ BF_KEY ks;
+} EVP_BF_KEY;
+
+# define data(ctx) EVP_C_DATA(EVP_BF_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_camellia.c b/Cryptlib/OpenSSL/crypto/evp/e_camellia.c
new file mode 100644
index 00000000..f273f9c9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_camellia.c
@@ -0,0 +1,394 @@
+/* crypto/evp/e_camellia.c */
+/* ====================================================================
+ * 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
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_CAMELLIA
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/camellia.h>
+# include "evp_locl.h"
+# include "modes_lcl.h"
+
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+/* Camellia subkey Structure */
+typedef struct {
+ CAMELLIA_KEY ks;
+ block128_f block;
+ union {
+ cbc128_f cbc;
+ ctr128_f ctr;
+ } stream;
+} EVP_CAMELLIA_KEY;
+
+# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
+
+/* Attribute operation for Camellia */
+# define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ---------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
+
+void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
+void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
+ const CAMELLIA_KEY *key);
+void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
+ const CAMELLIA_KEY *key);
+
+void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+
+static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode, bits;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ bits = ctx->key_len * 8;
+
+ cmll_t4_set_key(key, bits, &dat->ks);
+
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ ret = 0;
+ dat->block = (block128_f) cmll_t4_decrypt;
+ switch (bits) {
+ case 128:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
+ break;
+ case 192:
+ case 256:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ } else {
+ ret = 0;
+ dat->block = (block128_f) cmll_t4_encrypt;
+ switch (bits) {
+ case 128:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ case 192:
+ case 256:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+# define cmll_t4_cbc_cipher camellia_cbc_cipher
+static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_ecb_cipher camellia_ecb_cipher
+static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_ofb_cipher camellia_ofb_cipher
+static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_cfb_cipher camellia_cfb_cipher
+static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_cfb8_cipher camellia_cfb8_cipher
+static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_cfb1_cipher camellia_cfb1_cipher
+static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_ctr_cipher camellia_ctr_cipher
+static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ cmll_t4_init_key, \
+ cmll_t4_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_CAMELLIA_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER camellia_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ camellia_init_key, \
+ camellia_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_CAMELLIA_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
+{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
+
+# else
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER camellia_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ camellia_init_key, \
+ camellia_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_CAMELLIA_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
+{ return &camellia_##keylen##_##mode; }
+
+# endif
+
+# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)
+# if 0 /* not yet, missing NID */
+BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
+# endif
+/* The subkey for Camellia is generated. */
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ ret = Camellia_set_key(key, ctx->key_len * 8, &dat->ks);
+ if (ret < 0) {
+ EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ dat->block = (block128_f) Camellia_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) Camellia_cbc_encrypt : NULL;
+ } else {
+ dat->block = (block128_f) Camellia_encrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) Camellia_cbc_encrypt : NULL;
+ }
+
+ return 1;
+}
+
+static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (dat->stream.cbc)
+ (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
+ else if (ctx->encrypt)
+ CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+ else
+ CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+
+ return 1;
+}
+
+static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+ size_t i;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (len < bl)
+ return 1;
+
+ for (i = 0, len -= bl; i <= len; i += bl)
+ (*dat->block) (in + i, out + i, &dat->ks);
+
+ return 1;
+}
+
+static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, dat->block);
+ return 1;
+}
+
+static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) {
+ CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+ }
+
+ while (len >= MAXBITCHUNK) {
+ CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ len -= MAXBITCHUNK;
+ }
+ if (len)
+ CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+
+ return 1;
+}
+
+# if 0 /* not yet, missing NID */
+static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ unsigned int num = ctx->num;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (dat->stream.ctr)
+ CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->stream.ctr);
+ else
+ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->block);
+ ctx->num = (size_t)num;
+ return 1;
+}
+# endif
+
+BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
+ BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
+ BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
+#else
+
+# ifdef PEDANTIC
+static void *dummy = &dummy;
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_cast.c b/Cryptlib/OpenSSL/crypto/evp/e_cast.c
new file mode 100644
index 00000000..3f745485
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_cast.c
@@ -0,0 +1,89 @@
+/* crypto/evp/e_cast.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_CAST
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/cast.h>
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+typedef struct {
+ CAST_KEY ks;
+} EVP_CAST_KEY;
+
+# define data(ctx) EVP_C_DATA(EVP_CAST_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY,
+ NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_des.c b/Cryptlib/OpenSSL/crypto/evp/e_des.c
new file mode 100644
index 00000000..8ca65cd0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_des.c
@@ -0,0 +1,269 @@
+/* crypto/evp/e_des.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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/des.h>
+# include <openssl/rand.h>
+
+typedef struct {
+ union {
+ double align;
+ DES_key_schedule ks;
+ } ks;
+ union {
+ void (*cbc) (const void *, void *, size_t,
+ const DES_key_schedule *, unsigned char *);
+ } stream;
+} EVP_DES_KEY;
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ----------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
+
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule *ks, unsigned char iv[8]);
+void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule *ks, unsigned char iv[8]);
+# endif
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+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, size_t inl)
+{
+ BLOCK_CIPHER_ecb_loop()
+ DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
+ ctx->cipher_data, ctx->encrypt);
+ return 1;
+}
+
+static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ 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, size_t inl)
+{
+ EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+
+ if (dat->stream.cbc != NULL) {
+ (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv);
+ return 1;
+ }
+ 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, size_t inl)
+{
+ 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;
+}
+
+/*
+ * 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, size_t inl)
+{
+ size_t n, chunk = EVP_MAXCHUNK / 8;
+ unsigned char c[1], d[1];
+
+ if (inl < chunk)
+ chunk = inl;
+
+ while (inl && inl >= chunk) {
+ 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 >> (unsigned int)(n % 8))) |
+ ((d[0] & 0x80) >> (unsigned int)(n % 8));
+ }
+ inl -= chunk;
+ in += chunk;
+ out += chunk;
+ if (inl < chunk)
+ chunk = inl;
+ }
+
+ return 1;
+}
+
+static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ 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, EVP_DES_KEY, NID_des, 8, 8, 8, 64,
+ 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, EVP_DES_KEY, NID_des, 8, 8, 1,
+ 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, EVP_DES_KEY, NID_des, 8, 8, 8,
+ EVP_CIPH_RAND_KEY, des_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+ EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+
+ dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+ if (SPARC_DES_CAPABLE) {
+ int mode = ctx->cipher->flags & EVP_CIPH_MODE;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ des_t4_key_expand(key, &dat->ks.ks);
+ dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt;
+ return 1;
+ }
+ }
+# endif
+# ifdef EVP_CHECK_DES_KEY
+ if (DES_set_key_checked(deskey, dat->ks.ks) != 0)
+ return 0;
+# else
+ DES_set_key_unchecked(deskey, ctx->cipher_data);
+# endif
+ return 1;
+}
+
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+
+ switch (type) {
+ case EVP_CTRL_RAND_KEY:
+ if (RAND_bytes(ptr, 8) <= 0)
+ return 0;
+ DES_set_odd_parity((DES_cblock *)ptr);
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_des3.c b/Cryptlib/OpenSSL/crypto/evp/e_des3.c
new file mode 100644
index 00000000..0e910d6d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_des3.c
@@ -0,0 +1,495 @@
+/* crypto/evp/e_des3.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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/des.h>
+# include <openssl/rand.h>
+
+/* Block use of implementations in FIPS mode */
+# undef EVP_CIPH_FLAG_FIPS
+# define EVP_CIPH_FLAG_FIPS 0
+
+typedef struct {
+ union {
+ double align;
+ DES_key_schedule ks[3];
+ } ks;
+ union {
+ void (*cbc) (const void *, void *, size_t,
+ const DES_key_schedule *, unsigned char *);
+ } stream;
+} DES_EDE_KEY;
+# define ks1 ks.ks[0]
+# define ks2 ks.ks[1]
+# define ks3 ks.ks[2]
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ---------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
+
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule ks[3], unsigned char iv[8]);
+void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule ks[3], unsigned char iv[8]);
+# endif
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
+
+/*
+ * 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, size_t inl)
+{
+ BLOCK_CIPHER_ecb_loop()
+ DES_ecb3_encrypt((const_DES_cblock *)(in + i),
+ (DES_cblock *)(out + i),
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, ctx->encrypt);
+ return 1;
+}
+
+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (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, size_t inl)
+{
+ DES_EDE_KEY *dat = data(ctx);
+
+# ifdef KSSL_DEBUG
+ {
+ int i;
+ fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx,
+ ctx->buf_len);
+ fprintf(stderr, "\t iv= ");
+ for (i = 0; i < 8; i++)
+ fprintf(stderr, "%02X", ctx->iv[i]);
+ fprintf(stderr, "\n");
+ }
+# endif /* KSSL_DEBUG */
+ if (dat->stream.cbc) {
+ (*dat->stream.cbc) (in, out, inl, dat->ks.ks, ctx->iv);
+ return 1;
+ }
+
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
+ &dat->ks1, &dat->ks2, &dat->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,
+ &dat->ks1, &dat->ks2, &dat->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, size_t inl)
+{
+ while (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, size_t inl)
+{
+ size_t n;
+ unsigned char c[1], d[1];
+
+ for (n = 0; n < inl; ++n) {
+ c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+ 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 >> (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, size_t 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_DEFAULT_ASN1,
+ des_ede_init_key, NULL, NULL, NULL, des3_ctrl)
+# define des_ede3_cfb64_cipher des_ede_cfb64_cipher
+# define des_ede3_ofb_cipher des_ede_ofb_cipher
+# define des_ede3_cbc_cipher des_ede_cbc_cipher
+# 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,
+ 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, 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, des3_ctrl)
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+ DES_EDE_KEY *dat = data(ctx);
+
+ dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+ if (SPARC_DES_CAPABLE) {
+ int mode = ctx->cipher->flags & EVP_CIPH_MODE;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ des_t4_key_expand(&deskey[0], &dat->ks1);
+ des_t4_key_expand(&deskey[1], &dat->ks2);
+ memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
+ dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+ des_t4_ede3_cbc_decrypt;
+ return 1;
+ }
+ }
+# endif
+# ifdef EVP_CHECK_DES_KEY
+ if (DES_set_key_checked(&deskey[0], &dat->ks1)
+ || DES_set_key_checked(&deskey[1], &dat->ks2))
+ return 0;
+# else
+ DES_set_key_unchecked(&deskey[0], &dat->ks1);
+ DES_set_key_unchecked(&deskey[1], &dat->ks2);
+# endif
+ memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
+ return 1;
+}
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+ DES_EDE_KEY *dat = data(ctx);
+
+# ifdef KSSL_DEBUG
+ {
+ int i;
+ fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx);
+ fprintf(stderr, "\tKEY= ");
+ for (i = 0; i < 24; i++)
+ fprintf(stderr, "%02X", key[i]);
+ fprintf(stderr, "\n");
+ if (iv) {
+ fprintf(stderr, "\t IV= ");
+ for (i = 0; i < 8; i++)
+ fprintf(stderr, "%02X", iv[i]);
+ fprintf(stderr, "\n");
+ }
+ }
+# endif /* KSSL_DEBUG */
+
+ dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+ if (SPARC_DES_CAPABLE) {
+ int mode = ctx->cipher->flags & EVP_CIPH_MODE;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ des_t4_key_expand(&deskey[0], &dat->ks1);
+ des_t4_key_expand(&deskey[1], &dat->ks2);
+ des_t4_key_expand(&deskey[2], &dat->ks3);
+ dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+ des_t4_ede3_cbc_decrypt;
+ return 1;
+ }
+ }
+# endif
+# ifdef EVP_CHECK_DES_KEY
+ if (DES_set_key_checked(&deskey[0], &dat->ks1)
+ || DES_set_key_checked(&deskey[1], &dat->ks2)
+ || DES_set_key_checked(&deskey[2], &dat->ks3))
+ return 0;
+# else
+ DES_set_key_unchecked(&deskey[0], &dat->ks1);
+ DES_set_key_unchecked(&deskey[1], &dat->ks2);
+ DES_set_key_unchecked(&deskey[2], &dat->ks3);
+# endif
+ return 1;
+}
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+
+ DES_cblock *deskey = ptr;
+
+ switch (type) {
+ case EVP_CTRL_RAND_KEY:
+ if (RAND_bytes(ptr, c->key_len) <= 0)
+ return 0;
+ DES_set_odd_parity(deskey);
+ if (c->key_len >= 16)
+ DES_set_odd_parity(deskey + 1);
+ if (c->key_len >= 24)
+ DES_set_odd_parity(deskey + 2);
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+const EVP_CIPHER *EVP_des_ede(void)
+{
+ return &des_ede_ecb;
+}
+
+const EVP_CIPHER *EVP_des_ede3(void)
+{
+ return &des_ede3_ecb;
+}
+
+# ifndef OPENSSL_NO_SHA
+
+# include <openssl/sha.h>
+
+static const unsigned char wrap_iv[8] =
+ { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
+
+static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH];
+ int rv = -1;
+ if (inl < 24)
+ return -1;
+ if (out == NULL)
+ return inl - 16;
+ memcpy(ctx->iv, wrap_iv, 8);
+ /* Decrypt first block which will end up as icv */
+ des_ede_cbc_cipher(ctx, icv, in, 8);
+ /* Decrypt central blocks */
+ /*
+ * If decrypting in place move whole output along a block so the next
+ * des_ede_cbc_cipher is in place.
+ */
+ if (out == in) {
+ memmove(out, out + 8, inl - 8);
+ in -= 8;
+ }
+ des_ede_cbc_cipher(ctx, out, in + 8, inl - 16);
+ /* Decrypt final block which will be IV */
+ des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8);
+ /* Reverse order of everything */
+ BUF_reverse(icv, NULL, 8);
+ BUF_reverse(out, NULL, inl - 16);
+ BUF_reverse(ctx->iv, iv, 8);
+ /* Decrypt again using new IV */
+ des_ede_cbc_cipher(ctx, out, out, inl - 16);
+ des_ede_cbc_cipher(ctx, icv, icv, 8);
+ /* Work out SHA1 hash of first portion */
+ SHA1(out, inl - 16, sha1tmp);
+
+ if (!CRYPTO_memcmp(sha1tmp, icv, 8))
+ rv = inl - 16;
+ OPENSSL_cleanse(icv, 8);
+ OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+ OPENSSL_cleanse(iv, 8);
+ OPENSSL_cleanse(ctx->iv, 8);
+ if (rv == -1)
+ OPENSSL_cleanse(out, inl - 16);
+
+ return rv;
+}
+
+static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ unsigned char sha1tmp[SHA_DIGEST_LENGTH];
+ if (out == NULL)
+ return inl + 16;
+ /* Copy input to output buffer + 8 so we have space for IV */
+ memmove(out + 8, in, inl);
+ /* Work out ICV */
+ SHA1(in, inl, sha1tmp);
+ memcpy(out + inl + 8, sha1tmp, 8);
+ OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+ /* Generate random IV */
+ if (RAND_bytes(ctx->iv, 8) <= 0)
+ return -1;
+ memcpy(out, ctx->iv, 8);
+ /* Encrypt everything after IV in place */
+ des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8);
+ BUF_reverse(out, NULL, inl + 16);
+ memcpy(ctx->iv, wrap_iv, 8);
+ des_ede_cbc_cipher(ctx, out, out, inl + 16);
+ return inl + 16;
+}
+
+static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ /*
+ * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK
+ * is more than will ever be needed. Also input length must be a multiple
+ * of 8 bits.
+ */
+ if (inl >= EVP_MAXCHUNK || inl % 8)
+ return -1;
+ if (ctx->encrypt)
+ return des_ede3_wrap(ctx, out, in, inl);
+ else
+ return des_ede3_unwrap(ctx, out, in, inl);
+}
+
+static const EVP_CIPHER des3_wrap = {
+ NID_id_smime_alg_CMS3DESwrap,
+ 8, 24, 0,
+ EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
+ | EVP_CIPH_FLAG_DEFAULT_ASN1,
+ des_ede3_init_key, des_ede3_wrap_cipher,
+ NULL,
+ sizeof(DES_EDE_KEY),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_des_ede3_wrap(void)
+{
+ return &des3_wrap;
+}
+
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_idea.c b/Cryptlib/OpenSSL/crypto/evp/e_idea.c
new file mode 100644
index 00000000..cac72b33
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_idea.c
@@ -0,0 +1,119 @@
+/* crypto/evp/e_idea.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/idea.h>
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+/*
+ * NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a
+ * special case
+ */
+
+static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ BLOCK_CIPHER_ecb_loop()
+ idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
+ return 1;
+}
+
+/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */
+
+typedef struct {
+ IDEA_KEY_SCHEDULE ks;
+} EVP_IDEA_KEY;
+
+BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks)
+ BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks)
+ BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks)
+
+ BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
+ 0, idea_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ if (!enc) {
+ if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
+ enc = 1;
+ else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
+ enc = 1;
+ }
+ if (enc)
+ idea_set_encrypt_key(key, ctx->cipher_data);
+ else {
+ IDEA_KEY_SCHEDULE tmp;
+
+ idea_set_encrypt_key(key, &tmp);
+ idea_set_decrypt_key(&tmp, ctx->cipher_data);
+ OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE));
+ }
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_null.c b/Cryptlib/OpenSSL/crypto/evp/e_null.c
new file mode 100644
index 00000000..599fcb80
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_null.c
@@ -0,0 +1,100 @@
+/* crypto/evp/e_null.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+
+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, size_t inl);
+static const EVP_CIPHER n_cipher = {
+ NID_undef,
+ 1, 0, 0,
+ 0,
+ null_init_key,
+ null_cipher,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const EVP_CIPHER *EVP_enc_null(void)
+{
+ return (&n_cipher);
+}
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ /* memset(&(ctx->c),0,sizeof(ctx->c)); */
+ return 1;
+}
+
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ if (in != out)
+ memcpy((char *)out, (const char *)in, inl);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_old.c b/Cryptlib/OpenSSL/crypto/evp/e_old.c
new file mode 100644
index 00000000..a23d143b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_old.c
@@ -0,0 +1,164 @@
+/* crypto/evp/e_old.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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).
+ *
+ */
+
+#ifdef OPENSSL_NO_DEPRECATED
+static void *dummy = &dummy;
+#else
+
+# include <openssl/evp.h>
+
+/*
+ * Define some deprecated functions, so older programs don't crash and burn
+ * too quickly. On Windows and VMS, these will never be used, since
+ * functions and variables in shared libraries are selected by entry point
+ * location, not by name.
+ */
+
+# ifndef OPENSSL_NO_BF
+# undef EVP_bf_cfb
+const EVP_CIPHER *EVP_bf_cfb(void);
+const EVP_CIPHER *EVP_bf_cfb(void)
+{
+ return EVP_bf_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_DES
+# undef EVP_des_cfb
+const EVP_CIPHER *EVP_des_cfb(void);
+const EVP_CIPHER *EVP_des_cfb(void)
+{
+ return EVP_des_cfb64();
+}
+
+# undef EVP_des_ede3_cfb
+const EVP_CIPHER *EVP_des_ede3_cfb(void);
+const EVP_CIPHER *EVP_des_ede3_cfb(void)
+{
+ return EVP_des_ede3_cfb64();
+}
+
+# undef EVP_des_ede_cfb
+const EVP_CIPHER *EVP_des_ede_cfb(void);
+const EVP_CIPHER *EVP_des_ede_cfb(void)
+{
+ return EVP_des_ede_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_IDEA
+# undef EVP_idea_cfb
+const EVP_CIPHER *EVP_idea_cfb(void);
+const EVP_CIPHER *EVP_idea_cfb(void)
+{
+ return EVP_idea_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_RC2
+# undef EVP_rc2_cfb
+const EVP_CIPHER *EVP_rc2_cfb(void);
+const EVP_CIPHER *EVP_rc2_cfb(void)
+{
+ return EVP_rc2_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_CAST
+# undef EVP_cast5_cfb
+const EVP_CIPHER *EVP_cast5_cfb(void);
+const EVP_CIPHER *EVP_cast5_cfb(void)
+{
+ return EVP_cast5_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_RC5
+# undef EVP_rc5_32_12_16_cfb
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void)
+{
+ return EVP_rc5_32_12_16_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_AES
+# undef EVP_aes_128_cfb
+const EVP_CIPHER *EVP_aes_128_cfb(void);
+const EVP_CIPHER *EVP_aes_128_cfb(void)
+{
+ return EVP_aes_128_cfb128();
+}
+
+# undef EVP_aes_192_cfb
+const EVP_CIPHER *EVP_aes_192_cfb(void);
+const EVP_CIPHER *EVP_aes_192_cfb(void)
+{
+ return EVP_aes_192_cfb128();
+}
+
+# undef EVP_aes_256_cfb
+const EVP_CIPHER *EVP_aes_256_cfb(void);
+const EVP_CIPHER *EVP_aes_256_cfb(void)
+{
+ return EVP_aes_256_cfb128();
+}
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc2.c b/Cryptlib/OpenSSL/crypto/evp/e_rc2.c
new file mode 100644
index 00000000..718cc869
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc2.c
@@ -0,0 +1,235 @@
+/* crypto/evp/e_rc2.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/rc2.h>
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
+static int rc2_magic_to_meth(int i);
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+ int key_bits; /* effective key bits */
+ RC2_KEY ks; /* key schedule */
+} EVP_RC2_KEY;
+
+# define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data)
+
+IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
+ 8,
+ RC2_KEY_LENGTH, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ rc2_init_key, NULL,
+ rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
+ rc2_ctrl)
+# define RC2_40_MAGIC 0xa0
+# define RC2_64_MAGIC 0x78
+# define RC2_128_MAGIC 0x3a
+static const EVP_CIPHER r2_64_cbc_cipher = {
+ NID_rc2_64_cbc,
+ 8, 8 /* 64 bit */ , 8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ rc2_init_key,
+ rc2_cbc_cipher,
+ NULL,
+ sizeof(EVP_RC2_KEY),
+ rc2_set_asn1_type_and_iv,
+ rc2_get_asn1_type_and_iv,
+ rc2_ctrl,
+ NULL
+};
+
+static const EVP_CIPHER r2_40_cbc_cipher = {
+ NID_rc2_40_cbc,
+ 8, 5 /* 40 bit */ , 8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ rc2_init_key,
+ rc2_cbc_cipher,
+ NULL,
+ sizeof(EVP_RC2_KEY),
+ rc2_set_asn1_type_and_iv,
+ rc2_get_asn1_type_and_iv,
+ rc2_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_rc2_64_cbc(void)
+{
+ return (&r2_64_cbc_cipher);
+}
+
+const EVP_CIPHER *EVP_rc2_40_cbc(void)
+{
+ return (&r2_40_cbc_cipher);
+}
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+ key, data(ctx)->key_bits);
+ return 1;
+}
+
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
+{
+ int i;
+
+ EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
+ if (i == 128)
+ return (RC2_128_MAGIC);
+ else if (i == 64)
+ return (RC2_64_MAGIC);
+ else if (i == 40)
+ return (RC2_40_MAGIC);
+ else
+ return (0);
+}
+
+static int rc2_magic_to_meth(int i)
+{
+ if (i == RC2_128_MAGIC)
+ return 128;
+ else if (i == RC2_64_MAGIC)
+ return 64;
+ else if (i == RC2_40_MAGIC)
+ return 40;
+ else {
+ EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE);
+ return (0);
+ }
+}
+
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ long num = 0;
+ int i = 0;
+ int key_bits;
+ unsigned int l;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+
+ if (type != NULL) {
+ l = EVP_CIPHER_CTX_iv_length(c);
+ OPENSSL_assert(l <= sizeof(iv));
+ i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
+ if (i != (int)l)
+ return (-1);
+ key_bits = rc2_magic_to_meth((int)num);
+ if (!key_bits)
+ return (-1);
+ if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
+ return -1;
+ EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
+ EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
+ }
+ return (i);
+}
+
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ long num;
+ int i = 0, j;
+
+ if (type != NULL) {
+ num = rc2_meth_to_magic(c);
+ j = EVP_CIPHER_CTX_iv_length(c);
+ i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
+ }
+ return (i);
+}
+
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ switch (type) {
+ case EVP_CTRL_INIT:
+ data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
+ return 1;
+
+ case EVP_CTRL_GET_RC2_KEY_BITS:
+ *(int *)ptr = data(c)->key_bits;
+ return 1;
+
+ case EVP_CTRL_SET_RC2_KEY_BITS:
+ if (arg > 0) {
+ data(c)->key_bits = arg;
+ return 1;
+ }
+ return 0;
+# ifdef PBE_PRF_TEST
+ case EVP_CTRL_PBE_PRF_NID:
+ *(int *)ptr = NID_hmacWithMD5;
+ return 1;
+# endif
+
+ default:
+ return -1;
+ }
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc4.c b/Cryptlib/OpenSSL/crypto/evp/e_rc4.c
new file mode 100644
index 00000000..08e48f39
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc4.c
@@ -0,0 +1,133 @@
+/* crypto/evp/e_rc4.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC4
+
+# include <openssl/evp.h>
+# include "evp_locl.h"
+# include <openssl/objects.h>
+# include <openssl/rc4.h>
+
+/* FIXME: surely this is available elsewhere? */
+# define EVP_RC4_KEY_SIZE 16
+
+typedef struct {
+ RC4_KEY ks; /* working key */
+} EVP_RC4_KEY;
+
+# define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data)
+
+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, size_t inl);
+static const EVP_CIPHER r4_cipher = {
+ NID_rc4,
+ 1, EVP_RC4_KEY_SIZE, 0,
+ EVP_CIPH_VARIABLE_LENGTH,
+ rc4_init_key,
+ rc4_cipher,
+ NULL,
+ sizeof(EVP_RC4_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static const EVP_CIPHER r4_40_cipher = {
+ NID_rc4_40,
+ 1, 5 /* 40 bit */ , 0,
+ EVP_CIPH_VARIABLE_LENGTH,
+ rc4_init_key,
+ rc4_cipher,
+ NULL,
+ sizeof(EVP_RC4_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const EVP_CIPHER *EVP_rc4(void)
+{
+ return (&r4_cipher);
+}
+
+const EVP_CIPHER *EVP_rc4_40(void)
+{
+ return (&r4_40_cipher);
+}
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+ return 1;
+}
+
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ RC4(&data(ctx)->ks, inl, in, out);
+ return 1;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c b/Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c
new file mode 100644
index 00000000..2da11178
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c
@@ -0,0 +1,308 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+
+# include <openssl/crypto.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/rc4.h>
+# include <openssl/md5.h>
+
+# ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+# endif
+
+/* FIXME: surely this is available elsewhere? */
+# define EVP_RC4_KEY_SIZE 16
+
+typedef struct {
+ RC4_KEY ks;
+ MD5_CTX head, tail, md;
+ size_t payload_length;
+} EVP_RC4_HMAC_MD5;
+
+# define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out,
+ MD5_CTX *ctx, const void *inp, size_t blocks);
+
+# define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
+
+static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+{
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey);
+
+ MD5_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+}
+
+# if !defined(OPENSSL_NO_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) ) && \
+ !(defined(__APPLE__) && defined(__MACH__))
+# define STITCHED_CALL
+# endif
+
+# if !defined(STITCHED_CALL)
+# define rc4_off 0
+# define md5_off 0
+# endif
+
+static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+# if defined(STITCHED_CALL)
+ size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from
+ * rc4_md5-x86_64.pl */
+ md5_off = MD5_CBLOCK - key->md.num, blocks;
+ unsigned int l;
+ extern unsigned int OPENSSL_ia32cap_P[];
+# endif
+ size_t plen = key->payload_length;
+
+ if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH))
+ return 0;
+
+ if (ctx->encrypt) {
+ if (plen == NO_PAYLOAD_LENGTH)
+ plen = len;
+# if defined(STITCHED_CALL)
+ /* cipher has to "fall behind" */
+ if (rc4_off > md5_off)
+ md5_off += MD5_CBLOCK;
+
+ if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+ MD5_Update(&key->md, in, md5_off);
+ RC4(&key->ks, rc4_off, in, out);
+
+ rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+ &key->md, in + md5_off, blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else {
+ rc4_off = 0;
+ md5_off = 0;
+ }
+# endif
+ MD5_Update(&key->md, in + md5_off, plen - md5_off);
+
+ if (plen != len) { /* "TLS" mode of operation */
+ if (in != out)
+ memcpy(out + rc4_off, in + rc4_off, plen - rc4_off);
+
+ /* calculate HMAC and append it to payload */
+ MD5_Final(out + plen, &key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH);
+ MD5_Final(out + plen, &key->md);
+ /* encrypt HMAC at once */
+ RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off);
+ } else {
+ RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+ }
+ } else {
+ unsigned char mac[MD5_DIGEST_LENGTH];
+# if defined(STITCHED_CALL)
+ /* digest has to "fall behind" */
+ if (md5_off > rc4_off)
+ rc4_off += 2 * MD5_CBLOCK;
+ else
+ rc4_off += MD5_CBLOCK;
+
+ if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+ RC4(&key->ks, rc4_off, in, out);
+ MD5_Update(&key->md, out, md5_off);
+
+ rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+ &key->md, out + md5_off, blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ l = (key->md.Nl + (blocks << 3)) & 0xffffffffU;
+ if (l < key->md.Nl)
+ key->md.Nh++;
+ key->md.Nl = l;
+ key->md.Nh += blocks >> 29;
+ } else {
+ md5_off = 0;
+ rc4_off = 0;
+ }
+# endif
+ /* decrypt HMAC at once */
+ RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+ if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ MD5_Update(&key->md, out + md5_off, plen - md5_off);
+
+ /* calculate HMAC and verify it */
+ MD5_Final(mac, &key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH);
+ MD5_Final(mac, &key->md);
+
+ if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
+ return 0;
+ } else {
+ MD5_Update(&key->md, out + md5_off, len - md5_off);
+ }
+ }
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+}
+
+static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr)
+{
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ switch (type) {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset(hmac_key, 0, sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ MD5_Init(&key->head);
+ MD5_Update(&key->head, ptr, arg);
+ MD5_Final(hmac_key, &key->head);
+ } else {
+ memcpy(hmac_key, ptr, arg);
+ }
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ MD5_Init(&key->head);
+ MD5_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+ MD5_Init(&key->tail);
+ MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p = ptr;
+ unsigned int len;
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
+
+ if (!ctx->encrypt) {
+ len -= MD5_DIGEST_LENGTH;
+ p[arg - 2] = len >> 8;
+ p[arg - 1] = len;
+ }
+ key->payload_length = len;
+ key->md = key->head;
+ MD5_Update(&key->md, p, arg);
+
+ return MD5_DIGEST_LENGTH;
+ }
+ default:
+ return -1;
+ }
+}
+
+static EVP_CIPHER r4_hmac_md5_cipher = {
+# ifdef NID_rc4_hmac_md5
+ NID_rc4_hmac_md5,
+# else
+ NID_undef,
+# endif
+ 1, EVP_RC4_KEY_SIZE, 0,
+ EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH |
+ EVP_CIPH_FLAG_AEAD_CIPHER,
+ rc4_hmac_md5_init_key,
+ rc4_hmac_md5_cipher,
+ NULL,
+ sizeof(EVP_RC4_HMAC_MD5),
+ NULL,
+ NULL,
+ rc4_hmac_md5_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_rc4_hmac_md5(void)
+{
+ return (&r4_hmac_md5_cipher);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc5.c b/Cryptlib/OpenSSL/crypto/evp/e_rc5.c
new file mode 100644
index 00000000..f17e99d0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc5.c
@@ -0,0 +1,122 @@
+/* crypto/evp/e_rc5.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC5
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/rc5.h>
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+ int rounds; /* number of rounds */
+ RC5_32_KEY ks; /* key schedule */
+} EVP_RC5_KEY;
+
+# define data(ctx) EVP_C_DATA(EVP_RC5_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
+ 8, RC5_32_KEY_LENGTH, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl)
+
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ switch (type) {
+ case EVP_CTRL_INIT:
+ data(c)->rounds = RC5_12_ROUNDS;
+ return 1;
+
+ case EVP_CTRL_GET_RC5_ROUNDS:
+ *(int *)ptr = data(c)->rounds;
+ return 1;
+
+ case EVP_CTRL_SET_RC5_ROUNDS:
+ switch (arg) {
+ case RC5_8_ROUNDS:
+ case RC5_12_ROUNDS:
+ case RC5_16_ROUNDS:
+ data(c)->rounds = arg;
+ return 1;
+
+ default:
+ EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS);
+ return 0;
+ }
+
+ default:
+ return -1;
+ }
+}
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+ key, data(ctx)->rounds);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_seed.c b/Cryptlib/OpenSSL/crypto/evp/e_seed.c
new file mode 100644
index 00000000..7249d1b1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_seed.c
@@ -0,0 +1,82 @@
+/* crypto/evp/e_seed.c */
+/* ====================================================================
+ * 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
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_SEED
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/seed.h>
+# include "evp_locl.h"
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+typedef struct {
+ 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/Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c b/Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c
new file mode 100644
index 00000000..3430df9e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c
@@ -0,0 +1,130 @@
+/* crypto/evp/e_xcbc_d.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_DES
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/des.h>
+
+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, size_t inl);
+
+typedef struct {
+ DES_key_schedule ks; /* key schedule */
+ DES_cblock inw;
+ DES_cblock outw;
+} DESX_CBC_KEY;
+
+# define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data)
+
+static const EVP_CIPHER d_xcbc_cipher = {
+ NID_desx_cbc,
+ 8, 24, 8,
+ EVP_CIPH_CBC_MODE,
+ desx_cbc_init_key,
+ desx_cbc_cipher,
+ NULL,
+ sizeof(DESX_CBC_KEY),
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ NULL,
+ NULL
+};
+
+const EVP_CIPHER *EVP_desx_cbc(void)
+{
+ return (&d_xcbc_cipher);
+}
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+
+ DES_set_key_unchecked(deskey, &data(ctx)->ks);
+ memcpy(&data(ctx)->inw[0], &key[8], 8);
+ memcpy(&data(ctx)->outw[0], &key[16], 8);
+
+ return 1;
+}
+
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ 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/Cryptlib/OpenSSL/crypto/evp/encode.c b/Cryptlib/OpenSSL/crypto/evp/encode.c
new file mode 100644
index 00000000..c6c775e0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/encode.c
@@ -0,0 +1,460 @@
+/* crypto/evp/encode.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 <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+
+static unsigned char conv_ascii2bin(unsigned char a);
+#ifndef CHARSET_EBCDIC
+# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
+#else
+/*
+ * We assume that PEM encoded files are EBCDIC files (i.e., printable text
+ * files). Convert them here while decoding. When encoding, output is EBCDIC
+ * (text) format again. (No need for conversion in the conv_bin2ascii macro,
+ * as the underlying textstring data_bin2ascii[] is already EBCDIC)
+ */
+# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
+#endif
+
+/*-
+ * 64 char lines
+ * pad input with 0
+ * left over chars are set to =
+ * 1 byte => xx==
+ * 2 bytes => xxx=
+ * 3 bytes => xxxx
+ */
+#define BIN_PER_LINE (64/4*3)
+#define CHUNKS_PER_LINE (64/4)
+#define CHAR_PER_LINE (64+1)
+
+static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*-
+ * 0xF0 is a EOLN
+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
+ * 0xF2 is EOF
+ * 0xE0 is ignore at start of line.
+ * 0xFF is error
+ */
+
+#define B64_EOLN 0xF0
+#define B64_CR 0xF1
+#define B64_EOF 0xF2
+#define B64_WS 0xE0
+#define B64_ERROR 0xFF
+#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
+#define B64_BASE64(a) !B64_NOT_BASE64(a)
+
+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,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+ 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+#ifndef CHARSET_EBCDIC
+static unsigned char conv_ascii2bin(unsigned char a)
+{
+ if (a & 0x80)
+ return B64_ERROR;
+ return data_ascii2bin[a];
+}
+#else
+static unsigned char conv_ascii2bin(unsigned char a)
+{
+ a = os_toascii[a];
+ if (a & 0x80)
+ return B64_ERROR;
+ return data_ascii2bin[a];
+}
+#endif
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
+{
+ ctx->length = 48;
+ ctx->num = 0;
+ ctx->line_num = 0;
+}
+
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int i, j;
+ size_t total = 0;
+
+ *outl = 0;
+ if (inl <= 0)
+ return;
+ OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
+ if (ctx->length - ctx->num > inl) {
+ memcpy(&(ctx->enc_data[ctx->num]), in, inl);
+ ctx->num += inl;
+ return;
+ }
+ if (ctx->num != 0) {
+ i = ctx->length - ctx->num;
+ memcpy(&(ctx->enc_data[ctx->num]), in, i);
+ in += i;
+ inl -= i;
+ j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
+ ctx->num = 0;
+ out += j;
+ *(out++) = '\n';
+ *out = '\0';
+ total = j + 1;
+ }
+ while (inl >= ctx->length && total <= INT_MAX) {
+ j = EVP_EncodeBlock(out, in, ctx->length);
+ in += ctx->length;
+ inl -= ctx->length;
+ out += j;
+ *(out++) = '\n';
+ *out = '\0';
+ total += j + 1;
+ }
+ if (total > INT_MAX) {
+ /* Too much output data! */
+ *outl = 0;
+ return;
+ }
+ if (inl != 0)
+ memcpy(&(ctx->enc_data[0]), in, inl);
+ ctx->num = inl;
+ *outl = total;
+}
+
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+ unsigned int ret = 0;
+
+ if (ctx->num != 0) {
+ ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
+ out[ret++] = '\n';
+ out[ret] = '\0';
+ ctx->num = 0;
+ }
+ *outl = ret;
+}
+
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
+{
+ int i, ret = 0;
+ unsigned long l;
+
+ for (i = dlen; i > 0; i -= 3) {
+ if (i >= 3) {
+ l = (((unsigned long)f[0]) << 16L) |
+ (((unsigned long)f[1]) << 8L) | f[2];
+ *(t++) = conv_bin2ascii(l >> 18L);
+ *(t++) = conv_bin2ascii(l >> 12L);
+ *(t++) = conv_bin2ascii(l >> 6L);
+ *(t++) = conv_bin2ascii(l);
+ } else {
+ l = ((unsigned long)f[0]) << 16L;
+ if (i == 2)
+ l |= ((unsigned long)f[1] << 8L);
+
+ *(t++) = conv_bin2ascii(l >> 18L);
+ *(t++) = conv_bin2ascii(l >> 12L);
+ *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
+ *(t++) = '=';
+ }
+ ret += 4;
+ f += 3;
+ }
+
+ *t = '\0';
+ return (ret);
+}
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
+{
+ /* Only ctx->num is used during decoding. */
+ ctx->num = 0;
+ ctx->length = 0;
+ ctx->line_num = 0;
+ ctx->expect_nl = 0;
+}
+
+/*-
+ * -1 for error
+ * 0 for last line
+ * 1 for full line
+ *
+ * Note: even though EVP_DecodeUpdate attempts to detect and report end of
+ * content, the context doesn't currently remember it and will accept more data
+ * in the next call. Therefore, the caller is responsible for checking and
+ * rejecting a 0 return value in the middle of content.
+ *
+ * Note: even though EVP_DecodeUpdate has historically tried to detect end of
+ * content based on line length, this has never worked properly. Therefore,
+ * we now return 0 when one of the following is true:
+ * - Padding or B64_EOF was detected and the last block is complete.
+ * - Input has zero-length.
+ * -1 is returned if:
+ * - Invalid characters are detected.
+ * - There is extra trailing padding, or data after padding.
+ * - B64_EOF is detected after an incomplete base64 block.
+ */
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
+ unsigned char *d;
+
+ n = ctx->num;
+ d = ctx->enc_data;
+
+ if (n > 0 && d[n - 1] == '=') {
+ eof++;
+ if (n > 1 && d[n - 2] == '=')
+ eof++;
+ }
+
+ /* Legacy behaviour: an empty input chunk signals end of input. */
+ if (inl == 0) {
+ rv = 0;
+ goto end;
+ }
+
+ for (i = 0; i < inl; i++) {
+ tmp = *(in++);
+ v = conv_ascii2bin(tmp);
+ if (v == B64_ERROR) {
+ rv = -1;
+ goto end;
+ }
+
+ if (tmp == '=') {
+ eof++;
+ } else if (eof > 0 && B64_BASE64(v)) {
+ /* More data after padding. */
+ rv = -1;
+ goto end;
+ }
+
+ if (eof > 2) {
+ rv = -1;
+ goto end;
+ }
+
+ if (v == B64_EOF) {
+ seof = 1;
+ goto tail;
+ }
+
+ /* Only save valid base64 characters. */
+ if (B64_BASE64(v)) {
+ if (n >= 64) {
+ /*
+ * We increment n once per loop, and empty the buffer as soon as
+ * we reach 64 characters, so this can only happen if someone's
+ * manually messed with the ctx. Refuse to write any more data.
+ */
+ rv = -1;
+ goto end;
+ }
+ OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
+ d[n++] = tmp;
+ }
+
+ if (n == 64) {
+ decoded_len = EVP_DecodeBlock(out, d, n);
+ n = 0;
+ if (decoded_len < 0 || eof > decoded_len) {
+ rv = -1;
+ goto end;
+ }
+ ret += decoded_len - eof;
+ out += decoded_len - eof;
+ }
+ }
+
+ /*
+ * Legacy behaviour: if the current line is a full base64-block (i.e., has
+ * 0 mod 4 base64 characters), it is processed immediately. We keep this
+ * behaviour as applications may not be calling EVP_DecodeFinal properly.
+ */
+tail:
+ if (n > 0) {
+ if ((n & 3) == 0) {
+ decoded_len = EVP_DecodeBlock(out, d, n);
+ n = 0;
+ if (decoded_len < 0 || eof > decoded_len) {
+ rv = -1;
+ goto end;
+ }
+ ret += (decoded_len - eof);
+ } else if (seof) {
+ /* EOF in the middle of a base64 block. */
+ rv = -1;
+ goto end;
+ }
+ }
+
+ rv = seof || (n == 0 && eof) ? 0 : 1;
+end:
+ /* Legacy behaviour. This should probably rather be zeroed on error. */
+ *outl = ret;
+ ctx->num = n;
+ return (rv);
+}
+
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
+{
+ int i, ret = 0, a, b, c, d;
+ unsigned long l;
+
+ /* trim white space from the start of the line. */
+ while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
+ f++;
+ n--;
+ }
+
+ /*
+ * strip off stuff at the end of the line ascii2bin values B64_WS,
+ * B64_EOLN, B64_EOLN and B64_EOF
+ */
+ while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
+ n--;
+
+ if (n % 4 != 0)
+ return (-1);
+
+ for (i = 0; i < n; i += 4) {
+ a = conv_ascii2bin(*(f++));
+ b = conv_ascii2bin(*(f++));
+ c = conv_ascii2bin(*(f++));
+ d = conv_ascii2bin(*(f++));
+ if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
+ return (-1);
+ l = ((((unsigned long)a) << 18L) |
+ (((unsigned long)b) << 12L) |
+ (((unsigned long)c) << 6L) | (((unsigned long)d)));
+ *(t++) = (unsigned char)(l >> 16L) & 0xff;
+ *(t++) = (unsigned char)(l >> 8L) & 0xff;
+ *(t++) = (unsigned char)(l) & 0xff;
+ ret += 3;
+ }
+ return (ret);
+}
+
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i;
+
+ *outl = 0;
+ if (ctx->num != 0) {
+ i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
+ if (i < 0)
+ return (-1);
+ ctx->num = 0;
+ *outl = i;
+ return (1);
+ } else
+ return (1);
+}
+
+#ifdef undef
+int EVP_DecodeValid(unsigned char *buf, int len)
+{
+ int i, num = 0, bad = 0;
+
+ if (len == 0)
+ return (-1);
+ while (conv_ascii2bin(*buf) == B64_WS) {
+ buf++;
+ len--;
+ if (len == 0)
+ return (-1);
+ }
+
+ for (i = len; i >= 4; i -= 4) {
+ if ((conv_ascii2bin(buf[0]) >= 0x40) ||
+ (conv_ascii2bin(buf[1]) >= 0x40) ||
+ (conv_ascii2bin(buf[2]) >= 0x40) ||
+ (conv_ascii2bin(buf[3]) >= 0x40))
+ return (-1);
+ buf += 4;
+ num += 1 + (buf[2] != '=') + (buf[3] != '=');
+ }
+ if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN))
+ return (num);
+ if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) &&
+ (conv_ascii2bin(buf[0]) == B64_EOLN))
+ return (num);
+ return (1);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_acnf.c b/Cryptlib/OpenSSL/crypto/evp/evp_acnf.c
new file mode 100644
index 00000000..9703116e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_acnf.c
@@ -0,0 +1,73 @@
+/* evp_acnf.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/conf.h>
+
+/*
+ * Load all algorithms and configure OpenSSL. This function is called
+ * automatically when OPENSSL_LOAD_CONF is set.
+ */
+
+void OPENSSL_add_all_algorithms_conf(void)
+{
+ OPENSSL_add_all_algorithms_noconf();
+ OPENSSL_config(NULL);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_cnf.c b/Cryptlib/OpenSSL/crypto/evp/evp_cnf.c
new file mode 100644
index 00000000..6fd3a6da
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_cnf.c
@@ -0,0 +1,118 @@
+/* evp_cnf.c */
+/*
+ * Written by Stephen 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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+ 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))) {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+ return 0;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(sktmp); 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 {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+ ERR_add_error_data(4, "name=", oval->name,
+ ", value=", oval->value);
+ }
+
+ }
+ return 1;
+}
+
+void EVP_add_alg_module(void)
+{
+ CONF_module_add("alg_section", alg_module_init, 0);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_enc.c b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
new file mode 100644
index 00000000..7d7be245
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
@@ -0,0 +1,666 @@
+/* crypto/evp/evp_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include "evp_locl.h"
+
+#ifdef OPENSSL_FIPS
+# define M_do_cipher(ctx, out, in, inl) FIPS_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);
+ if (ctx)
+ EVP_CIPHER_CTX_init(ctx);
+ return ctx;
+}
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv, int enc)
+{
+ if (cipher)
+ EVP_CIPHER_CTX_init(ctx);
+ 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).
+ */
+ if (ctx->cipher) {
+ unsigned long flags = ctx->flags;
+ EVP_CIPHER_CTX_cleanup(ctx);
+ /* Restore encrypt and flags */
+ ctx->encrypt = enc;
+ ctx->flags = flags;
+ }
+#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
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode()) {
+ const EVP_CIPHER *fcipher;
+ if (cipher)
+ fcipher = evp_get_fips_cipher(cipher);
+ if (fcipher)
+ cipher = fcipher;
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+ }
+#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;
+ /* Preserve wrap enable flag, zero everything else */
+ ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
+ 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
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+#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 (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW)
+ && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) {
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED);
+ return 0;
+ }
+
+ 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;
+ /* fall-through */
+
+ 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;
+
+ case EVP_CIPH_CTR_MODE:
+ ctx->num = 0;
+ /* Don't reuse IV for CTR mode */
+ if (iv)
+ memcpy(ctx->iv, iv, 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)
+{
+ if (ctx->encrypt)
+ return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+ else
+ return EVP_DecryptUpdate(ctx, out, outl, in, inl);
+}
+
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ if (ctx->encrypt)
+ return EVP_EncryptFinal_ex(ctx, out, outl);
+ else
+ return EVP_DecryptFinal_ex(ctx, out, outl);
+}
+
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ if (ctx->encrypt)
+ return EVP_EncryptFinal(ctx, out, outl);
+ else
+ return EVP_DecryptFinal(ctx, out, outl);
+}
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv)
+{
+ return EVP_CipherInit(ctx, cipher, key, iv, 1);
+}
+
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv)
+{
+ return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
+}
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv)
+{
+ return EVP_CipherInit(ctx, cipher, key, iv, 0);
+}
+
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv)
+{
+ return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
+}
+
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int i, j, bl;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ i = M_do_cipher(ctx, out, in, inl);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
+ if (inl <= 0) {
+ *outl = 0;
+ return inl == 0;
+ }
+
+ if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) {
+ if (M_do_cipher(ctx, out, in, inl)) {
+ *outl = inl;
+ return 1;
+ } else {
+ *outl = 0;
+ return 0;
+ }
+ }
+ i = ctx->buf_len;
+ bl = ctx->cipher->block_size;
+ OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
+ if (i != 0) {
+ if (bl - i > inl) {
+ memcpy(&(ctx->buf[i]), in, inl);
+ ctx->buf_len += inl;
+ *outl = 0;
+ return 1;
+ } else {
+ j = bl - i;
+ memcpy(&(ctx->buf[i]), in, j);
+ if (!M_do_cipher(ctx, out, ctx->buf, bl))
+ return 0;
+ inl -= j;
+ in += j;
+ out += bl;
+ *outl = bl;
+ }
+ } else
+ *outl = 0;
+ i = inl & (bl - 1);
+ inl -= i;
+ if (inl > 0) {
+ if (!M_do_cipher(ctx, out, in, inl))
+ return 0;
+ *outl += inl;
+ }
+
+ if (i != 0)
+ memcpy(ctx->buf, &(in[inl]), i);
+ ctx->buf_len = i;
+ return 1;
+}
+
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int ret;
+ ret = EVP_EncryptFinal_ex(ctx, out, outl);
+ return ret;
+}
+
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int n, ret;
+ unsigned int i, b, bl;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ ret = M_do_cipher(ctx, out, NULL, 0);
+ if (ret < 0)
+ return 0;
+ else
+ *outl = ret;
+ return 1;
+ }
+
+ b = ctx->cipher->block_size;
+ OPENSSL_assert(b <= sizeof ctx->buf);
+ if (b == 1) {
+ *outl = 0;
+ return 1;
+ }
+ bl = ctx->buf_len;
+ if (ctx->flags & EVP_CIPH_NO_PADDING) {
+ if (bl) {
+ EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
+ EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ return 0;
+ }
+ *outl = 0;
+ return 1;
+ }
+
+ n = b - bl;
+ for (i = bl; i < b; i++)
+ ctx->buf[i] = n;
+ ret = M_do_cipher(ctx, out, ctx->buf, b);
+
+ if (ret)
+ *outl = b;
+
+ return ret;
+}
+
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int fix_len;
+ unsigned int b;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ fix_len = M_do_cipher(ctx, out, in, inl);
+ if (fix_len < 0) {
+ *outl = 0;
+ return 0;
+ } else
+ *outl = fix_len;
+ return 1;
+ }
+
+ if (inl <= 0) {
+ *outl = 0;
+ return inl == 0;
+ }
+
+ if (ctx->flags & EVP_CIPH_NO_PADDING)
+ return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+
+ b = ctx->cipher->block_size;
+ OPENSSL_assert(b <= sizeof ctx->final);
+
+ if (ctx->final_used) {
+ memcpy(out, ctx->final, b);
+ out += b;
+ fix_len = 1;
+ } else
+ fix_len = 0;
+
+ if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
+ return 0;
+
+ /*
+ * if we have 'decrypted' a multiple of block size, make sure we have a
+ * copy of this last block
+ */
+ if (b > 1 && !ctx->buf_len) {
+ *outl -= b;
+ ctx->final_used = 1;
+ memcpy(ctx->final, &out[*outl], b);
+ } else
+ ctx->final_used = 0;
+
+ if (fix_len)
+ *outl += b;
+
+ return 1;
+}
+
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int ret;
+ ret = EVP_DecryptFinal_ex(ctx, out, outl);
+ return ret;
+}
+
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i, n;
+ unsigned int b;
+ *outl = 0;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ i = M_do_cipher(ctx, out, NULL, 0);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
+ b = ctx->cipher->block_size;
+ if (ctx->flags & EVP_CIPH_NO_PADDING) {
+ if (ctx->buf_len) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+ EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ return 0;
+ }
+ *outl = 0;
+ return 1;
+ }
+ if (b > 1) {
+ if (ctx->buf_len || !ctx->final_used) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+ return (0);
+ }
+ OPENSSL_assert(b <= sizeof ctx->final);
+
+ /*
+ * The following assumes that the ciphertext has been authenticated.
+ * Otherwise it provides a padding oracle.
+ */
+ n = ctx->final[b - 1];
+ if (n == 0 || n > (int)b) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+ return (0);
+ }
+ for (i = 0; i < n; i++) {
+ if (ctx->final[--b] != n) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+ return (0);
+ }
+ }
+ n = ctx->cipher->block_size - n;
+ for (i = 0; i < n; i++)
+ out[i] = ctx->final[i];
+ *outl = n;
+ } else
+ *outl = 0;
+ return (1);
+}
+
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+ if (ctx) {
+ EVP_CIPHER_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+{
+#ifndef OPENSSL_FIPS
+ 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);
+#endif
+#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
+#ifdef OPENSSL_FIPS
+ FIPS_cipher_ctx_cleanup(c);
+#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)
+ return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
+ if (c->key_len == keylen)
+ return 1;
+ if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
+ c->key_len = keylen;
+ return 1;
+ }
+ EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH);
+ return 0;
+}
+
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
+{
+ if (pad)
+ ctx->flags &= ~EVP_CIPH_NO_PADDING;
+ else
+ ctx->flags |= EVP_CIPH_NO_PADDING;
+ 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)
+ return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
+ if (RAND_bytes(key, ctx->key_len) <= 0)
+ return 0;
+ return 1;
+}
+
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
+{
+ if ((in == NULL) || (in->cipher == NULL)) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED);
+ return 0;
+ }
+#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) {
+ out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
+ if (!out->cipher_data) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
+ }
+
+ if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+ return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_err.c b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
new file mode 100644
index 00000000..15cf5532
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
@@ -0,0 +1,254 @@
+/* crypto/evp/evp_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2013 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
+
+static ERR_STRING_DATA EVP_str_functs[] = {
+ {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"},
+ {ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"},
+ {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
+ {ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "AES_T4_INIT_KEY"},
+ {ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"},
+ {ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"},
+ {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"},
+ {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"},
+ {ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"},
+ {ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "CMLL_T4_INIT_KEY"},
+ {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"},
+ {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_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_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_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH),
+ "FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
+ {ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"},
+ {ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"},
+ {ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"},
+ {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_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_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}
+};
+
+static ERR_STRING_DATA EVP_str_reasons[] = {
+ {ERR_REASON(EVP_R_AES_IV_SETUP_FAILED), "aes iv setup failed"},
+ {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"},
+ {ERR_REASON(EVP_R_ASN1_LIB), "asn1 lib"},
+ {ERR_REASON(EVP_R_BAD_BLOCK_LENGTH), "bad block length"},
+ {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"},
+ {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_DIFFERENT_PARAMETERS), "different parameters"},
+ {ERR_REASON(EVP_R_DISABLED_FOR_FIPS), "disabled for fips"},
+ {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_DIGEST), "invalid digest"},
+ {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
+ {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_TOO_LARGE), "too large"},
+ {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
+ {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"},
+ {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"},
+ {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"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),
+ "unsupported private key algorithm"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"},
+ {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"},
+ {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
+ {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_EVP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, EVP_str_functs);
+ ERR_load_strings(0, EVP_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_key.c b/Cryptlib/OpenSSL/crypto/evp/evp_key.c
new file mode 100644
index 00000000..63c8866e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_key.c
@@ -0,0 +1,197 @@
+/* crypto/evp/evp_key.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/ui.h>
+
+#ifndef OPENSSL_NO_UI
+/* should be init to zeros. */
+static char prompt_string[80];
+
+void EVP_set_pw_prompt(const char *prompt)
+{
+ if (prompt == NULL)
+ prompt_string[0] = '\0';
+ else {
+ strncpy(prompt_string, prompt, 79);
+ prompt_string[79] = '\0';
+ }
+}
+
+char *EVP_get_pw_prompt(void)
+{
+ if (prompt_string[0] == '\0')
+ return (NULL);
+ else
+ return (prompt_string);
+}
+
+/*
+ * For historical reasons, the standard function for reading passwords is 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];
+ UI *ui;
+
+ if ((prompt == NULL) && (prompt_string[0] != '\0'))
+ prompt = prompt_string;
+ ui = UI_new();
+ if (ui == NULL)
+ return -1;
+ UI_add_input_string(ui, prompt, 0, buf, min,
+ (len >= BUFSIZ) ? BUFSIZ - 1 : len);
+ if (verify)
+ UI_add_verify_string(ui, prompt, 0,
+ buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len,
+ buf);
+ ret = UI_process(ui);
+ UI_free(ui);
+ OPENSSL_cleanse(buff, BUFSIZ);
+ return ret;
+}
+#endif /* OPENSSL_NO_UI */
+
+int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+ const unsigned char *salt, const unsigned char *data,
+ int datal, int count, unsigned char *key,
+ unsigned char *iv)
+{
+ EVP_MD_CTX c;
+ unsigned char md_buf[EVP_MAX_MD_SIZE];
+ int niv, nkey, addmd = 0;
+ unsigned int mds = 0, i;
+ int rv = 0;
+ nkey = type->key_len;
+ niv = type->iv_len;
+ OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
+ OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
+
+ if (data == NULL)
+ return (nkey);
+
+ EVP_MD_CTX_init(&c);
+ for (;;) {
+ if (!EVP_DigestInit_ex(&c, md, NULL))
+ goto err;
+ if (addmd++)
+ if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+ goto err;
+ if (!EVP_DigestUpdate(&c, data, datal))
+ goto err;
+ if (salt != NULL)
+ if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+ goto err;
+
+ for (i = 1; i < (unsigned int)count; i++) {
+ if (!EVP_DigestInit_ex(&c, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+ goto err;
+ }
+ i = 0;
+ if (nkey) {
+ for (;;) {
+ if (nkey == 0)
+ break;
+ if (i == mds)
+ break;
+ if (key != NULL)
+ *(key++) = md_buf[i];
+ nkey--;
+ i++;
+ }
+ }
+ if (niv && (i != mds)) {
+ for (;;) {
+ if (niv == 0)
+ break;
+ if (i == mds)
+ break;
+ if (iv != NULL)
+ *(iv++) = md_buf[i];
+ niv--;
+ i++;
+ }
+ }
+ if ((nkey == 0) && (niv == 0))
+ break;
+ }
+ rv = type->key_len;
+ err:
+ EVP_MD_CTX_cleanup(&c);
+ OPENSSL_cleanse(md_buf, sizeof(md_buf));
+ return rv;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_lib.c b/Cryptlib/OpenSSL/crypto/evp/evp_lib.c
new file mode 100644
index 00000000..7e0bab90
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_lib.c
@@ -0,0 +1,391 @@
+/* crypto/evp/evp_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include "evp_locl.h"
+#endif
+
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int ret;
+
+ 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) {
+ switch (EVP_CIPHER_CTX_mode(c)) {
+ case EVP_CIPH_WRAP_MODE:
+ if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
+ ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
+ ret = 1;
+ break;
+
+ case EVP_CIPH_GCM_MODE:
+ case EVP_CIPH_CCM_MODE:
+ case EVP_CIPH_XTS_MODE:
+ ret = -1;
+ break;
+
+ default:
+ ret = EVP_CIPHER_set_asn1_iv(c, type);
+ }
+ } else
+ ret = -1;
+ return (ret);
+}
+
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int ret;
+
+ 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) {
+ switch (EVP_CIPHER_CTX_mode(c)) {
+
+ case EVP_CIPH_WRAP_MODE:
+ ret = 1;
+ break;
+
+ case EVP_CIPH_GCM_MODE:
+ case EVP_CIPH_CCM_MODE:
+ case EVP_CIPH_XTS_MODE:
+ ret = -1;
+ break;
+
+ default:
+ ret = EVP_CIPHER_get_asn1_iv(c, type);
+ break;
+ }
+ } else
+ ret = -1;
+ return (ret);
+}
+
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int i = 0;
+ unsigned int l;
+
+ if (type != NULL) {
+ l = EVP_CIPHER_CTX_iv_length(c);
+ OPENSSL_assert(l <= sizeof(c->iv));
+ i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
+ if (i != (int)l)
+ return (-1);
+ else if (i > 0)
+ memcpy(c->iv, c->oiv, l);
+ }
+ return (i);
+}
+
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int i = 0;
+ unsigned int j;
+
+ if (type != NULL) {
+ j = EVP_CIPHER_CTX_iv_length(c);
+ OPENSSL_assert(j <= sizeof(c->iv));
+ i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
+ }
+ return (i);
+}
+
+/* Convert the various cipher NIDs and dummies to a proper OID NID */
+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
+{
+ int nid;
+ ASN1_OBJECT *otmp;
+ nid = EVP_CIPHER_nid(ctx);
+
+ switch (nid) {
+
+ case NID_rc2_cbc:
+ case NID_rc2_64_cbc:
+ case NID_rc2_40_cbc:
+
+ return NID_rc2_cbc;
+
+ case NID_rc4:
+ case NID_rc4_40:
+
+ return NID_rc4;
+
+ case NID_aes_128_cfb128:
+ case NID_aes_128_cfb8:
+ case NID_aes_128_cfb1:
+
+ return NID_aes_128_cfb128;
+
+ case NID_aes_192_cfb128:
+ case NID_aes_192_cfb8:
+ case NID_aes_192_cfb1:
+
+ return NID_aes_192_cfb128;
+
+ case NID_aes_256_cfb128:
+ case NID_aes_256_cfb8:
+ case NID_aes_256_cfb1:
+
+ return NID_aes_256_cfb128;
+
+ case NID_des_cfb64:
+ case NID_des_cfb8:
+ case NID_des_cfb1:
+
+ return NID_des_cfb64;
+
+ case NID_des_ede3_cfb64:
+ case NID_des_ede3_cfb8:
+ case NID_des_ede3_cfb1:
+
+ return NID_des_cfb64;
+
+ default:
+ /* Check it has an OID and it is valid */
+ otmp = OBJ_nid2obj(nid);
+ if (!otmp || !otmp->data)
+ nid = NID_undef;
+ ASN1_OBJECT_free(otmp);
+ return nid;
+ }
+}
+
+int EVP_CIPHER_block_size(const EVP_CIPHER *e)
+{
+ return e->block_size;
+}
+
+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;
+}
+
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
+{
+#ifdef OPENSSL_FIPS
+ const EVP_CIPHER *fcipher;
+ fcipher = evp_get_fips_cipher(cipher);
+ if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS)
+ return cipher->flags | EVP_CIPH_FLAG_FIPS;
+#endif
+ return cipher->flags;
+}
+
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+{
+#ifdef OPENSSL_FIPS
+ return EVP_CIPHER_flags(ctx->cipher);
+#else
+ return ctx->cipher->flags;
+#endif
+}
+
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->app_data;
+}
+
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+{
+ ctx->app_data = data;
+}
+
+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;
+}
+
+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;
+}
+
+int EVP_MD_block_size(const EVP_MD *md)
+{
+ return md->block_size;
+}
+
+int EVP_MD_type(const EVP_MD *md)
+{
+ return md->type;
+}
+
+int EVP_MD_pkey_type(const EVP_MD *md)
+{
+ return md->pkey_type;
+}
+
+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;
+}
+
+#ifdef OPENSSL_FIPS
+
+const EVP_MD *evp_get_fips_md(const EVP_MD *md)
+{
+ int nid = EVP_MD_type(md);
+ if (nid == NID_dsa)
+ return FIPS_evp_dss1();
+ else if (nid == NID_dsaWithSHA)
+ return FIPS_evp_dss();
+ else if (nid == NID_ecdsa_with_SHA1)
+ return FIPS_evp_ecdsa();
+ else
+ return FIPS_get_digestbynid(nid);
+}
+
+const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher)
+{
+ int nid = cipher->nid;
+ if (nid == NID_undef)
+ return FIPS_evp_enc_null();
+ else
+ return FIPS_get_cipherbynid(nid);
+}
+
+#endif
+
+unsigned long EVP_MD_flags(const EVP_MD *md)
+{
+#ifdef OPENSSL_FIPS
+ const EVP_MD *fmd;
+ fmd = evp_get_fips_md(md);
+ if (fmd && fmd->flags & EVP_MD_FLAG_FIPS)
+ return md->flags | EVP_MD_FLAG_FIPS;
+#endif
+ return md->flags;
+}
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+{
+ if (!ctx)
+ return NULL;
+ return ctx->digest;
+}
+
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
+{
+ ctx->flags |= flags;
+}
+
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
+{
+ ctx->flags &= ~flags;
+}
+
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
+{
+ return (ctx->flags & flags);
+}
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+ ctx->flags |= flags;
+}
+
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+ ctx->flags &= ~flags;
+}
+
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+{
+ return (ctx->flags & flags);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_locl.h b/Cryptlib/OpenSSL/crypto/evp/evp_locl.h
new file mode 100644
index 00000000..2bb709a0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_locl.h
@@ -0,0 +1,373 @@
+/* evp_locl.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define BLOCK_CIPHER_ecb_loop() \
+ 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, 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, size_t inl) \
+{\
+ 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, size_t inl) \
+{\
+ 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, size_t inl) \
+{\
+ size_t chunk=EVP_MAXCHUNK;\
+ if (cbits==1) chunk>>=3;\
+ if (inl<chunk) chunk=inl;\
+ while(inl && 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(inl<chunk) chunk=inl;\
+ }\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+ BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+ BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
+
+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
+ key_len, iv_len, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+static const EVP_CIPHER cname##_##mode = { \
+ nid##_##nmode, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_##MODE##_MODE, \
+ init_key, \
+ cname##_##mode##_cipher, \
+ cleanup, \
+ sizeof(kstruct), \
+ set_asn1, get_asn1,\
+ ctrl, \
+ NULL \
+}; \
+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
+
+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
+ iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
+ iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
+ iv_len, cbits, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
+ key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
+ iv_len, cbits, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
+ key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
+ flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
+ 0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+ nid, block_size, key_len, iv_len, cbits, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
+ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
+ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+/*-
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+ nid, block_size, key_len, iv_len, flags,\
+ init_key, cleanup, set_asn1, get_asn1, ctrl)\
+static const EVP_CIPHER cname##_cbc = {\
+ nid##_cbc, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_CBC_MODE,\
+ init_key,\
+ cname##_cbc_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl, \
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+ nid##_cfb64, 1, key_len, iv_len, \
+ flags | EVP_CIPH_CFB_MODE,\
+ init_key,\
+ cname##_cfb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+ nid##_ofb64, 1, key_len, iv_len, \
+ flags | EVP_CIPH_OFB_MODE,\
+ init_key,\
+ cname##_ofb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+ nid##_ecb, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_ECB_MODE,\
+ init_key,\
+ cname##_ecb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+ block_size, key_len, iv_len, cbits, \
+ flags, init_key, \
+ cleanup, set_asn1, get_asn1, ctrl) \
+ BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+ cbits, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data)
+
+#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, \
+ 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);
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md,
+ int en_de);
+
+const EVP_MD *evp_get_fips_md(const EVP_MD *md);
+const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher);
+
+#ifdef OPENSSL_FIPS
+
+# ifdef OPENSSL_DOING_MAKEDEPEND
+# undef SHA1_Init
+# undef SHA1_Update
+# undef SHA224_Init
+# undef SHA256_Init
+# undef SHA384_Init
+# undef SHA512_Init
+# undef DES_set_key_unchecked
+# endif
+
+# define RIPEMD160_Init private_RIPEMD160_Init
+# define WHIRLPOOL_Init private_WHIRLPOOL_Init
+# 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
+# define SHA1_Init private_SHA1_Init
+# define SHA224_Init private_SHA224_Init
+# define SHA256_Init private_SHA256_Init
+# define SHA384_Init private_SHA384_Init
+# define SHA512_Init private_SHA512_Init
+
+# define BF_set_key private_BF_set_key
+# define CAST_set_key private_CAST_set_key
+# define idea_set_encrypt_key private_idea_set_encrypt_key
+# define SEED_set_key private_SEED_set_key
+# define RC2_set_key private_RC2_set_key
+# define RC4_set_key private_RC4_set_key
+# define DES_set_key_unchecked private_DES_set_key_unchecked
+# define Camellia_set_key private_Camellia_set_key
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_pbe.c b/Cryptlib/OpenSSL/crypto/evp/evp_pbe.c
new file mode 100644
index 00000000..7934c95f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_pbe.c
@@ -0,0 +1,312 @@
+/* evp_pbe.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+#include "evp_locl.h"
+
+/* Password based encryption (PBE) functions */
+
+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_type;
+ int pbe_nid;
+ int cipher_nid;
+ int md_nid;
+ EVP_PBE_KEYGEN *keygen;
+} EVP_PBE_CTL;
+
+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},
+
+#ifndef OPENSSL_NO_HMAC
+ {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#endif
+
+ {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 (!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);
+
+ 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;
+}
+
+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_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 == NULL) {
+ pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
+ if (pbe_algs == NULL)
+ goto err;
+ }
+
+ if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL)
+ goto err;
+
+ 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_EVP_PBE_CTL_push(pbe_algs, pbe_tmp);
+ return 1;
+
+ err:
+ EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+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_nid(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_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
+ pbe_algs = NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_pkey.c b/Cryptlib/OpenSSL/crypto/evp/evp_pkey.c
new file mode 100644
index 00000000..6a456297
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_pkey.c
@@ -0,0 +1,229 @@
+/* evp_pkey.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#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;
+ ASN1_OBJECT *algoid;
+ char obj_tmp[80];
+
+ 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;
+ }
+
+ if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
+ 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 (pkey->ameth->priv_decode) {
+ if (!pkey->ameth->priv_decode(pkey, p8)) {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR);
+ goto error;
+ }
+ } else {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+
+ return pkey;
+
+ error:
+ EVP_PKEY_free(pkey);
+ return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
+{
+ return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
+}
+
+/* Turn a private key into a PKCS8 structure */
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
+{
+ PKCS8_PRIV_KEY_INFO *p8;
+
+ if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
+ EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ p8->broken = broken;
+
+ 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;
+ }
+ } else {
+ EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+ EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ goto error;
+ }
+ 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)
+{
+ switch (broken) {
+
+ case PKCS8_OK:
+ p8->broken = PKCS8_OK;
+ return p8;
+ break;
+
+ case PKCS8_NO_OCTET:
+ p8->broken = PKCS8_NO_OCTET;
+ p8->pkey->type = V_ASN1_SEQUENCE;
+ return p8;
+ break;
+
+ default:
+ EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
+ return NULL;
+ }
+}
+
+/* EVP_PKEY attribute functions */
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
+{
+ return X509at_get_attr_count(key->attributes);
+}
+
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
+{
+ return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+}
+
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
+{
+ return X509at_get_attr(key->attributes, loc);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
+{
+ return X509at_delete_attr(key->attributes, loc);
+}
+
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
+{
+ if (X509at_add1_attr(&key->attributes, attr))
+ return 1;
+ return 0;
+}
+
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+ const ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
+ return 1;
+ return 0;
+}
+
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+ int nid, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
+ return 1;
+ return 0;
+}
+
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+ const char *attrname, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len))
+ return 1;
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_dss.c b/Cryptlib/OpenSSL/crypto/evp/m_dss.c
new file mode 100644
index 00000000..14784486
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_dss.c
@@ -0,0 +1,104 @@
+/* crypto/evp/m_dss.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/sha.h>
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#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 dsa_md = {
+ NID_dsaWithSHA,
+ NID_dsaWithSHA,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_DIGEST,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_DSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_dss(void)
+{
+ return (&dsa_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_dss1.c b/Cryptlib/OpenSSL/crypto/evp/m_dss1.c
new file mode 100644
index 00000000..e36fabff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_dss1.c
@@ -0,0 +1,105 @@
+/* crypto/evp/m_dss1.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SHA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/sha.h>
+# ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+# endif
+
+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 dss1_md = {
+ NID_dsa,
+ NID_dsaWithSHA1,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_DIGEST,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_DSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_dss1(void)
+{
+ return (&dss1_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c b/Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c
new file mode 100644
index 00000000..803d3149
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c
@@ -0,0 +1,154 @@
+/* crypto/evp/m_ecdsa.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+#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,
+ EVP_MD_FLAG_PKEY_DIGEST,
+ 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);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_md2.c b/Cryptlib/OpenSSL/crypto/evp/m_md2.c
new file mode 100644
index 00000000..3c4cd7bf
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_md2.c
@@ -0,0 +1,106 @@
+/* crypto/evp/m_md2.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md2.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MD2_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MD2_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MD2_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md2_md = {
+ NID_md2,
+ NID_md2WithRSAEncryption,
+ MD2_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ MD2_BLOCK,
+ sizeof(EVP_MD *) + sizeof(MD2_CTX),
+};
+
+const EVP_MD *EVP_md2(void)
+{
+ return (&md2_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_md4.c b/Cryptlib/OpenSSL/crypto/evp/m_md4.c
new file mode 100644
index 00000000..851de69f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_md4.c
@@ -0,0 +1,108 @@
+/* crypto/evp/m_md4.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD4
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md4.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MD4_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MD4_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MD4_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md4_md = {
+ NID_md4,
+ NID_md4WithRSAEncryption,
+ MD4_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ MD4_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(MD4_CTX),
+};
+
+const EVP_MD *EVP_md4(void)
+{
+ return (&md4_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_md5.c b/Cryptlib/OpenSSL/crypto/evp/m_md5.c
new file mode 100644
index 00000000..e5d5f71b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_md5.c
@@ -0,0 +1,107 @@
+/* crypto/evp/m_md5.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD5
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md5.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MD5_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MD5_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MD5_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md5_md = {
+ NID_md5,
+ NID_md5WithRSAEncryption,
+ MD5_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ MD5_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(MD5_CTX),
+};
+
+const EVP_MD *EVP_md5(void)
+{
+ return (&md5_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_mdc2.c b/Cryptlib/OpenSSL/crypto/evp/m_mdc2.c
new file mode 100644
index 00000000..94e12a6b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_mdc2.c
@@ -0,0 +1,108 @@
+/* crypto/evp/m_mdc2.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MDC2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/mdc2.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MDC2_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MDC2_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MDC2_Final(md, ctx->md_data);
+}
+
+static const EVP_MD mdc2_md = {
+ NID_mdc2,
+ NID_mdc2WithRSA,
+ MDC2_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_ASN1_OCTET_STRING_method,
+ MDC2_BLOCK,
+ sizeof(EVP_MD *) + sizeof(MDC2_CTX),
+};
+
+const EVP_MD *EVP_mdc2(void)
+{
+ return (&mdc2_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_null.c b/Cryptlib/OpenSSL/crypto/evp/m_null.c
new file mode 100644
index 00000000..017e1feb
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_null.c
@@ -0,0 +1,98 @@
+/* crypto/evp/m_null.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return 1;
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return 1;
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return 1;
+}
+
+static const EVP_MD null_md = {
+ NID_undef,
+ NID_undef,
+ 0,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_NULL_method,
+ 0,
+ sizeof(EVP_MD *),
+};
+
+const EVP_MD *EVP_md_null(void)
+{
+ return (&null_md);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_ripemd.c b/Cryptlib/OpenSSL/crypto/evp/m_ripemd.c
new file mode 100644
index 00000000..81de0ef4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_ripemd.c
@@ -0,0 +1,107 @@
+/* crypto/evp/m_ripemd.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RIPEMD
+
+# include <openssl/ripemd.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return RIPEMD160_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return RIPEMD160_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return RIPEMD160_Final(md, ctx->md_data);
+}
+
+static const EVP_MD ripemd160_md = {
+ NID_ripemd160,
+ NID_ripemd160WithRSA,
+ RIPEMD160_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ RIPEMD160_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
+};
+
+const EVP_MD *EVP_ripemd160(void)
+{
+ return (&ripemd160_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sha.c b/Cryptlib/OpenSSL/crypto/evp/m_sha.c
new file mode 100644
index 00000000..e1e22e0c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_sha.c
@@ -0,0 +1,106 @@
+/* crypto/evp/m_sha.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 <stdio.h>
+#include "cryptlib.h"
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return SHA_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha_md = {
+ NID_sha,
+ NID_shaWithRSAEncryption,
+ SHA_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_sha(void)
+{
+ return (&sha_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sha1.c b/Cryptlib/OpenSSL/crypto/evp/m_sha1.c
new file mode 100644
index 00000000..a74e6b77
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_sha1.c
@@ -0,0 +1,235 @@
+/* crypto/evp/m_sha1.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SHA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/sha.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+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 sha1_md = {
+ NID_sha1,
+ NID_sha1WithRSAEncryption,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_sha1(void)
+{
+ return (&sha1_md);
+}
+#endif
+
+#ifndef OPENSSL_NO_SHA256
+static int init224(EVP_MD_CTX *ctx)
+{
+ return SHA224_Init(ctx->md_data);
+}
+
+static int init256(EVP_MD_CTX *ctx)
+{
+ return SHA256_Init(ctx->md_data);
+}
+
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA256_Update(ctx->md_data, data, count);
+}
+
+static int final256(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA256_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha224_md = {
+ NID_sha224,
+ NID_sha224WithRSAEncryption,
+ SHA224_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init224,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha224(void)
+{
+ return (&sha224_md);
+}
+
+static const EVP_MD sha256_md = {
+ NID_sha256,
+ NID_sha256WithRSAEncryption,
+ SHA256_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init256,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha256(void)
+{
+ return (&sha256_md);
+}
+#endif /* ifndef OPENSSL_NO_SHA256 */
+
+#ifndef OPENSSL_NO_SHA512
+static int init384(EVP_MD_CTX *ctx)
+{
+ return SHA384_Init(ctx->md_data);
+}
+
+static int init512(EVP_MD_CTX *ctx)
+{
+ return SHA512_Init(ctx->md_data);
+}
+
+/* See comment in SHA224/256 section */
+static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA512_Update(ctx->md_data, data, count);
+}
+
+static int final512(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA512_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha384_md = {
+ NID_sha384,
+ NID_sha384WithRSAEncryption,
+ SHA384_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init384,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha384(void)
+{
+ return (&sha384_md);
+}
+
+static const EVP_MD sha512_md = {
+ NID_sha512,
+ NID_sha512WithRSAEncryption,
+ SHA512_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init512,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha512(void)
+{
+ return (&sha512_md);
+}
+#endif /* ifndef OPENSSL_NO_SHA512 */
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sigver.c b/Cryptlib/OpenSSL/crypto/evp/m_sigver.c
new file mode 100644
index 00000000..4492d207
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_sigver.c
@@ -0,0 +1,203 @@
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#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 (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
+
+ 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 (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
+ return 1;
+ 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;
+ EVP_PKEY_CTX *pctx = ctx->pctx;
+ if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
+ EVP_PKEY_CTX *dctx;
+ if (!sigret)
+ return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
+ dctx = EVP_PKEY_CTX_dup(ctx->pctx);
+ if (!dctx)
+ return 0;
+ r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
+ EVP_PKEY_CTX_free(dctx);
+ return r;
+ }
+ if (pctx->pmeth->signctx)
+ sctx = 1;
+ else
+ sctx = 0;
+ if (sigret) {
+ 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 (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
+ return 0;
+ } else {
+ int s = EVP_MD_size(ctx->digest);
+ if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+ size_t siglen)
+{
+ 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/Cryptlib/OpenSSL/crypto/evp/m_wp.c b/Cryptlib/OpenSSL/crypto/evp/m_wp.c
new file mode 100644
index 00000000..a890939e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_wp.c
@@ -0,0 +1,48 @@
+/* crypto/evp/m_wp.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/whrlpool.h>
+# include "evp_locl.h"
+
+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/Cryptlib/OpenSSL/crypto/evp/names.c b/Cryptlib/OpenSSL/crypto/evp/names.c
new file mode 100644
index 00000000..ff115a31
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/names.c
@@ -0,0 +1,215 @@
+/* crypto/evp/names.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_add_cipher(const EVP_CIPHER *c)
+{
+ int r;
+
+ if (c == NULL)
+ return 0;
+
+ OPENSSL_init();
+
+ 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;
+ OPENSSL_init();
+
+ 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->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);
+ }
+ return (r);
+}
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
+{
+ const EVP_CIPHER *cp;
+
+ cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
+ return (cp);
+}
+
+const EVP_MD *EVP_get_digestbyname(const char *name)
+{
+ const EVP_MD *cp;
+
+ cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
+ return (cp);
+}
+
+void EVP_cleanup(void)
+{
+ OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
+ OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
+ /*
+ * The above calls will only clean out the contents of the name hash
+ * table, but not the hash table itself. The following line does that
+ * part. -- Richard Levitte
+ */
+ 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/Cryptlib/OpenSSL/crypto/evp/p5_crpt.c b/Cryptlib/OpenSSL/crypto/evp/p5_crpt.c
new file mode 100644
index 00000000..d06ab90a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p5_crpt.c
@@ -0,0 +1,149 @@
+/* p5_crpt.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+
+/*
+ * Doesn't do anything now: Builtin PBE algorithms in static table.
+ */
+
+void PKCS5_PBE_add(void)
+{
+}
+
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
+ ASN1_TYPE *param, const EVP_CIPHER *cipher,
+ const EVP_MD *md, int en_de)
+{
+ EVP_MD_CTX ctx;
+ unsigned char md_tmp[EVP_MAX_MD_SIZE];
+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+ int i;
+ PBEPARAM *pbe;
+ int saltlen, iter;
+ unsigned char *salt;
+ const unsigned char *pbuf;
+ int mdsize;
+ int rv = 0;
+ EVP_MD_CTX_init(&ctx);
+
+ /* Extract useful info from parameter */
+ if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ return 0;
+ }
+
+ pbuf = param->value.sequence->data;
+ if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+ EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ return 0;
+ }
+
+ if (!pbe->iter)
+ iter = 1;
+ else
+ iter = ASN1_INTEGER_get(pbe->iter);
+ salt = pbe->salt->data;
+ saltlen = pbe->salt->length;
+
+ if (!pass)
+ passlen = 0;
+ else if (passlen == -1)
+ passlen = strlen(pass);
+
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, pass, passlen))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, salt, saltlen))
+ goto err;
+ PBEPARAM_free(pbe);
+ if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+ goto err;
+ mdsize = EVP_MD_size(md);
+ if (mdsize < 0)
+ return 0;
+ for (i = 1; i < iter; i++) {
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+ goto err;
+ }
+ OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
+ memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
+ OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
+ memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
+ EVP_CIPHER_iv_length(cipher));
+ if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
+ goto err;
+ OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
+ OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+ OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+ rv = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return rv;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c b/Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c
new file mode 100644
index 00000000..f2ae1e57
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c
@@ -0,0 +1,334 @@
+/* p5_crpt2.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
+# include <openssl/x509.h>
+# include <openssl/evp.h>
+# include <openssl/hmac.h>
+# include "evp_locl.h"
+
+/* set this to print out info about the keygen algorithm */
+/* #define DEBUG_PKCS5V2 */
+
+# ifdef DEBUG_PKCS5V2
+static void h__dump(const unsigned char *p, int len);
+# endif
+
+/*
+ * This is an implementation of PKCS#5 v2.0 password based encryption key
+ * derivation function PBKDF2. SHA1 version verified against test vectors
+ * posted by Peter Gutmann <pgut001@cs.auckland.ac.nz> to the PKCS-TNG
+ * <pkcs-tng@rsa.com> mailing list.
+ */
+
+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[EVP_MAX_MD_SIZE], *p, itmp[4];
+ int cplen, j, k, tkeylen, mdlen;
+ unsigned long i = 1;
+ HMAC_CTX hctx_tpl, hctx;
+
+ mdlen = EVP_MD_size(digest);
+ if (mdlen < 0)
+ return 0;
+
+ HMAC_CTX_init(&hctx_tpl);
+ p = out;
+ tkeylen = keylen;
+ if (!pass)
+ passlen = 0;
+ else if (passlen == -1)
+ passlen = strlen(pass);
+ if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ 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...
+ */
+ itmp[0] = (unsigned char)((i >> 24) & 0xff);
+ itmp[1] = (unsigned char)((i >> 16) & 0xff);
+ itmp[2] = (unsigned char)((i >> 8) & 0xff);
+ itmp[3] = (unsigned char)(i & 0xff);
+ if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ if (!HMAC_Update(&hctx, salt, saltlen)
+ || !HMAC_Update(&hctx, itmp, 4)
+ || !HMAC_Final(&hctx, digtmp, NULL)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hctx);
+ memcpy(p, digtmp, cplen);
+ for (j = 1; j < iter; j++) {
+ if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ if (!HMAC_Update(&hctx, digtmp, mdlen)
+ || !HMAC_Final(&hctx, digtmp, NULL)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hctx);
+ for (k = 0; k < cplen; k++)
+ p[k] ^= digtmp[k];
+ }
+ tkeylen -= cplen;
+ i++;
+ p += cplen;
+ }
+ HMAC_CTX_cleanup(&hctx_tpl);
+# ifdef DEBUG_PKCS5V2
+ fprintf(stderr, "Password:\n");
+ h__dump(pass, passlen);
+ fprintf(stderr, "Salt:\n");
+ h__dump(salt, saltlen);
+ fprintf(stderr, "Iteration count %d\n", iter);
+ fprintf(stderr, "Key:\n");
+ 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()
+{
+ unsigned char out[4];
+ unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 };
+ PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
+ fprintf(stderr, "Out %02X %02X %02X %02X\n",
+ out[0], out[1], out[2], out[3]);
+}
+
+# endif
+
+/*
+ * Now the key derivation function itself. This is a bit evil because it has
+ * to check the ASN1 parameters are valid: and there are quite a few of
+ * them...
+ */
+
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param, const EVP_CIPHER *c,
+ const EVP_MD *md, int en_de)
+{
+ const unsigned char *pbuf;
+ int plen;
+ PBE2PARAM *pbe2 = NULL;
+ const EVP_CIPHER *cipher;
+
+ int rv = 0;
+
+ if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+ if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* See if we recognise the key derivation function */
+
+ if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+ goto err;
+ }
+
+ /*
+ * lets see if we recognise the encryption algorithm.
+ */
+
+ cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
+
+ if (!cipher) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+
+ /* Fixup cipher based on AlgorithmIdentifier */
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR);
+ goto err;
+ }
+ rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
+ pbe2->keyfunc->parameter, c, md, en_de);
+ err:
+ PBE2PARAM_free(pbe2);
+ return rv;
+}
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+ unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+ const unsigned char *pbuf;
+ int saltlen, iter, plen;
+ int rv = 0;
+ unsigned int keylen = 0;
+ int prf_nid, hmac_md_nid;
+ PBKDF2PARAM *kdf = NULL;
+ const EVP_MD *prfmd;
+
+ if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
+ goto err;
+ }
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+ OPENSSL_assert(keylen <= sizeof key);
+
+ /* Decode parameter */
+
+ if (!param || (param->type != V_ASN1_SEQUENCE)) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+
+ if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen))) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+ /* Now check the parameters of the kdf */
+
+ if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH);
+ goto err;
+ }
+
+ 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_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ goto err;
+ }
+
+ prfmd = EVP_get_digestbynid(hmac_md_nid);
+ if (prfmd == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ goto err;
+ }
+
+ if (kdf->salt->type != V_ASN1_OCTET_STRING) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE);
+ goto err;
+ }
+
+ /* it seems that its all OK */
+ salt = kdf->salt->value.octet_string->data;
+ saltlen = kdf->salt->value.octet_string->length;
+ iter = ASN1_INTEGER_get(kdf->iter);
+ if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
+ keylen, key))
+ goto err;
+ rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+ err:
+ OPENSSL_cleanse(key, keylen);
+ PBKDF2PARAM_free(kdf);
+ return rv;
+}
+
+# ifdef DEBUG_PKCS5V2
+static void h__dump(const unsigned char *p, int len)
+{
+ for (; len--; p++)
+ fprintf(stderr, "%02X ", *p);
+ fprintf(stderr, "\n");
+}
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_dec.c b/Cryptlib/OpenSSL/crypto/evp/p_dec.c
new file mode 100644
index 00000000..225b8b45
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_dec.c
@@ -0,0 +1,87 @@
+/* crypto/evp/p_dec.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
+ EVP_PKEY *priv)
+{
+ int ret = -1;
+
+#ifndef OPENSSL_NO_RSA
+ if (priv->type != EVP_PKEY_RSA) {
+#endif
+ EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+ goto err;
+ }
+
+ ret =
+ RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa, RSA_PKCS1_PADDING);
+ err:
+#endif
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_enc.c b/Cryptlib/OpenSSL/crypto/evp/p_enc.c
new file mode 100644
index 00000000..f565f33f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_enc.c
@@ -0,0 +1,87 @@
+/* crypto/evp/p_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key,
+ int key_len, EVP_PKEY *pubk)
+{
+ int ret = 0;
+
+#ifndef OPENSSL_NO_RSA
+ if (pubk->type != EVP_PKEY_RSA) {
+#endif
+ EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+ goto err;
+ }
+ ret =
+ RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa,
+ RSA_PKCS1_PADDING);
+ err:
+#endif
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_lib.c b/Cryptlib/OpenSSL/crypto/evp/p_lib.c
new file mode 100644
index 00000000..c0171244
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_lib.c
@@ -0,0 +1,456 @@
+/* crypto/evp/p_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#include "asn1_locl.h"
+
+static void EVP_PKEY_free_it(EVP_PKEY *x);
+
+int EVP_PKEY_bits(EVP_PKEY *pkey)
+{
+ 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 && pkey->ameth && pkey->ameth->pkey_size)
+ return pkey->ameth->pkey_size(pkey);
+ return 0;
+}
+
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
+{
+#ifndef OPENSSL_NO_DSA
+ if (pkey->type == EVP_PKEY_DSA) {
+ int ret = pkey->save_parameters;
+
+ if (mode >= 0)
+ pkey->save_parameters = mode;
+ return (ret);
+ }
+#endif
+#ifndef OPENSSL_NO_EC
+ if (pkey->type == EVP_PKEY_EC) {
+ int ret = pkey->save_parameters;
+
+ if (mode >= 0)
+ pkey->save_parameters = mode;
+ return (ret);
+ }
+#endif
+ return (0);
+}
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+ if (to->type != from->type) {
+ EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
+ goto err;
+ }
+
+ if (EVP_PKEY_missing_parameters(from)) {
+ EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
+ goto err;
+ }
+ if (from->ameth && from->ameth->param_copy)
+ return from->ameth->param_copy(to, from);
+ err:
+ return 0;
+}
+
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
+{
+ 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)
+{
+ 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)
+{
+ if (a->type != b->type)
+ return -1;
+
+ if (a->ameth) {
+ int ret;
+ /* Compare parameters if the algorithm has them */
+ if (a->ameth->param_cmp) {
+ ret = a->ameth->param_cmp(a, b);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (a->ameth->pub_cmp)
+ return a->ameth->pub_cmp(a, b);
+ }
+
+ return -2;
+}
+
+EVP_PKEY *EVP_PKEY_new(void)
+{
+ EVP_PKEY *ret;
+
+ ret = (EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
+ if (ret == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+ 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);
+}
+
+/*
+ * 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)
+{
+ 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 (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
+ return 0;
+ pkey->pkey.ptr = key;
+ return (key != NULL);
+}
+
+void *EVP_PKEY_get0(EVP_PKEY *pkey)
+{
+ return pkey->pkey.ptr;
+}
+
+#ifndef OPENSSL_NO_RSA
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+{
+ int ret = EVP_PKEY_assign_RSA(pkey, key);
+ if (ret)
+ RSA_up_ref(key);
+ return ret;
+}
+
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_RSA) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+ return NULL;
+ }
+ RSA_up_ref(pkey->pkey.rsa);
+ return pkey->pkey.rsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+ int ret = EVP_PKEY_assign_DSA(pkey, key);
+ if (ret)
+ DSA_up_ref(key);
+ return ret;
+}
+
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_DSA) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+ return NULL;
+ }
+ DSA_up_ref(pkey->pkey.dsa);
+ return pkey->pkey.dsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
+{
+ int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
+ if (ret)
+ EC_KEY_up_ref(key);
+ return ret;
+}
+
+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_EC) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+ return NULL;
+ }
+ EC_KEY_up_ref(pkey->pkey.ec);
+ return pkey->pkey.ec;
+}
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
+{
+ int ret = EVP_PKEY_assign_DH(pkey, key);
+ if (ret)
+ DH_up_ref(key);
+ return ret;
+}
+
+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
+ return NULL;
+ }
+ DH_up_ref(pkey->pkey.dh);
+ return pkey->pkey.dh;
+}
+#endif
+
+int EVP_PKEY_type(int type)
+{
+ 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)
+{
+ int i;
+
+ if (x == NULL)
+ return;
+
+ i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+ REF_PRINT("EVP_PKEY", x);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "EVP_PKEY_free, bad reference count\n");
+ abort();
+ }
+#endif
+ EVP_PKEY_free_it(x);
+ if (x->attributes)
+ sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
+ OPENSSL_free(x);
+}
+
+static void EVP_PKEY_free_it(EVP_PKEY *x)
+{
+ if (x->ameth && x->ameth->pkey_free) {
+ x->ameth->pkey_free(x);
+ x->pkey.ptr = NULL;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ if (x->engine) {
+ 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/Cryptlib/OpenSSL/crypto/evp/p_open.c b/Cryptlib/OpenSSL/crypto/evp/p_open.c
new file mode 100644
index 00000000..229eb641
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_open.c
@@ -0,0 +1,129 @@
+/* crypto/evp/p_open.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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RSA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/rsa.h>
+
+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+ const unsigned char *ek, int ekl, const unsigned char *iv,
+ EVP_PKEY *priv)
+{
+ unsigned char *key = NULL;
+ int i, size = 0, ret = 0;
+
+ if (type) {
+ EVP_CIPHER_CTX_init(ctx);
+ if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
+ return 0;
+ }
+
+ if (!priv)
+ return 1;
+
+ if (priv->type != EVP_PKEY_RSA) {
+ EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA);
+ goto err;
+ }
+
+ size = RSA_size(priv->pkey.rsa);
+ key = (unsigned char *)OPENSSL_malloc(size + 2);
+ if (key == NULL) {
+ /* ERROR */
+ EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ i = EVP_PKEY_decrypt_old(key, ek, ekl, priv);
+ if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) {
+ /* ERROR */
+ goto err;
+ }
+ if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
+ goto err;
+
+ ret = 1;
+ err:
+ if (key != NULL)
+ OPENSSL_cleanse(key, size);
+ OPENSSL_free(key);
+ return (ret);
+}
+
+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i;
+
+ i = EVP_DecryptFinal_ex(ctx, out, outl);
+ if (i)
+ i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+ return (i);
+}
+#else /* !OPENSSL_NO_RSA */
+
+# ifdef PEDANTIC
+static void *dummy = &dummy;
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_seal.c b/Cryptlib/OpenSSL/crypto/evp/p_seal.c
new file mode 100644
index 00000000..ba9dfff2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_seal.c
@@ -0,0 +1,121 @@
+/* crypto/evp/p_seal.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+ unsigned char **ek, int *ekl, unsigned char *iv,
+ EVP_PKEY **pubk, int npubk)
+{
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ int i;
+
+ if (type) {
+ EVP_CIPHER_CTX_init(ctx);
+ if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
+ return 0;
+ }
+ if ((npubk <= 0) || !pubk)
+ return 1;
+ if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+ return 0;
+ if (EVP_CIPHER_CTX_iv_length(ctx)
+ && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0)
+ return 0;
+
+ if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
+ return 0;
+
+ for (i = 0; i < npubk; i++) {
+ ekl[i] =
+ EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx),
+ pubk[i]);
+ if (ekl[i] <= 0)
+ return (-1);
+ }
+ return (npubk);
+}
+
+/*- MACRO
+void EVP_SealUpdate(ctx,out,outl,in,inl)
+EVP_CIPHER_CTX *ctx;
+unsigned char *out;
+int *outl;
+unsigned char *in;
+int inl;
+ {
+ EVP_EncryptUpdate(ctx,out,outl,in,inl);
+ }
+*/
+
+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i;
+ i = EVP_EncryptFinal_ex(ctx, out, outl);
+ if (i)
+ i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+ return i;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_sign.c b/Cryptlib/OpenSSL/crypto/evp/p_sign.c
new file mode 100644
index 00000000..1b9ba060
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_sign.c
@@ -0,0 +1,133 @@
+/* crypto/evp/p_sign.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+#ifdef undef
+void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+{
+ EVP_DigestInit_ex(ctx, type);
+}
+
+void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count)
+{
+ EVP_DigestUpdate(ctx, data, count);
+}
+#endif
+
+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+ unsigned int *siglen, EVP_PKEY *pkey)
+{
+ unsigned char m[EVP_MAX_MD_SIZE];
+ unsigned int m_len;
+ int i = 0, ok = 0, v;
+ EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
+
+ *siglen = 0;
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
+ goto err;
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+
+ if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+ 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];
+ if (v == 0)
+ break;
+ if (pkey->type == v) {
+ ok = 1;
+ break;
+ }
+ }
+ if (!ok) {
+ 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);
+ }
+ return (ctx->digest->sign(ctx->digest->type, m, m_len, sigret, siglen,
+ pkey->pkey.ptr));
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_verify.c b/Cryptlib/OpenSSL/crypto/evp/p_verify.c
new file mode 100644
index 00000000..65e1e216
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_verify.c
@@ -0,0 +1,116 @@
+/* crypto/evp/p_verify.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+ unsigned int siglen, EVP_PKEY *pkey)
+{
+ unsigned char m[EVP_MAX_MD_SIZE];
+ unsigned int m_len;
+ int i = 0, ok = 0, v;
+ EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
+
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
+ goto err;
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+
+ if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+ 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];
+ if (v == 0)
+ break;
+ if (pkey->type == v) {
+ ok = 1;
+ break;
+ }
+ }
+ if (!ok) {
+ EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE);
+ return (-1);
+ }
+ if (ctx->digest->verify == NULL) {
+ EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
+ return (0);
+ }
+
+ return (ctx->digest->verify(ctx->digest->type, m, m_len,
+ sigbuf, siglen, pkey->pkey.ptr));
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c
new file mode 100644
index 00000000..a8b7f2f6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c
@@ -0,0 +1,346 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#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/Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c
new file mode 100644
index 00000000..6435f1b6
--- /dev/null
+++ b/Cryptlib/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 <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#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 == NULL)
+ return -1;
+
+ if (*ppkey == NULL)
+ *ppkey = EVP_PKEY_new();
+
+ if (*ppkey == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ 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,
+ const 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, (void *)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/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c
new file mode 100644
index 00000000..9f81d100
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c
@@ -0,0 +1,613 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#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, cmac_pkey_meth;
+extern const EVP_PKEY_METHOD dhx_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,
+ &cmac_pkey_meth,
+#ifndef OPENSSL_NO_DH
+ &dhx_pkey_meth
+#endif
+};
+
+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
+ if (pkey && pkey->engine)
+ e = pkey->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;
+
+ memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));
+
+ 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_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth)
+{
+ if (ppkey_id)
+ *ppkey_id = meth->pkey_id;
+ if (pflags)
+ *pflags = meth->flags;
+}
+
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
+{
+
+ dst->init = src->init;
+ dst->copy = src->copy;
+ dst->cleanup = src->cleanup;
+
+ dst->paramgen_init = src->paramgen_init;
+ dst->paramgen = src->paramgen;
+
+ dst->keygen_init = src->keygen_init;
+ dst->keygen = src->keygen;
+
+ dst->sign_init = src->sign_init;
+ dst->sign = src->sign;
+
+ dst->verify_init = src->verify_init;
+ dst->verify = src->verify;
+
+ dst->verify_recover_init = src->verify_recover_init;
+ dst->verify_recover = src->verify_recover;
+
+ dst->signctx_init = src->signctx_init;
+ dst->signctx = src->signctx;
+
+ dst->verifyctx_init = src->verifyctx_init;
+ dst->verifyctx = src->verifyctx;
+
+ dst->encrypt_init = src->encrypt_init;
+ dst->encrypt = src->encrypt;
+
+ dst->decrypt_init = src->decrypt_init;
+ dst->decrypt = src->decrypt;
+
+ dst->derive_init = src->derive_init;
+ dst->derive = src->derive;
+
+ dst->ctrl = src->ctrl;
+ dst->ctrl_str = src->ctrl_str;
+}
+
+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/Cryptlib/OpenSSL/crypto/ex_data.c b/Cryptlib/OpenSSL/crypto/ex_data.c
new file mode 100644
index 00000000..f96a5178
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ex_data.c
@@ -0,0 +1,646 @@
+/* crypto/ex_data.c */
+
+/*
+ * Overhaul notes;
+ *
+ * This code is now *mostly* thread-safe. It is now easier to understand in what
+ * ways it is safe and in what ways it is not, which is an improvement. Firstly,
+ * all per-class stacks and index-counters for ex_data are stored in the same
+ * global LHASH table (keyed by class). This hash table uses locking for all
+ * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be
+ * called when no other threads can possibly race against it (even if it was
+ * locked, the race would mean it's possible the hash table might have been
+ * recreated after the cleanup). As classes can only be added to the hash table,
+ * and within each class, the stack of methods can only be incremented, the
+ * locking mechanics are simpler than they would otherwise be. For example, the
+ * new/dup/free ex_data functions will lock the hash table, copy the method
+ * pointers it needs from the relevant class, then unlock the hash table before
+ * actually applying those method pointers to the task of the new/dup/free
+ * operations. As they can't be removed from the method-stack, only
+ * supplemented, there's no race conditions associated with using them outside
+ * the lock. The get/set_ex_data functions are not locked because they do not
+ * involve this global state at all - they operate directly with a previously
+ * obtained per-class method index and a particular "ex_data" variable. These
+ * variables are usually instantiated per-context (eg. each RSA structure has
+ * one) so locking on read/write access to that variable can be locked locally
+ * if required (eg. using the "RSA" lock to synchronise access to a
+ * per-RSA-structure ex_data variable if required).
+ * [Geoff]
+ */
+
+/* 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 "cryptlib.h"
+#include <openssl/lhash.h>
+
+/* What an "implementation of ex_data functionality" looks like */
+struct st_CRYPTO_EX_DATA_IMPL {
+ /*********************/
+ /* GLOBAL OPERATIONS */
+ /* Return a new class index */
+ int (*cb_new_class) (void);
+ /* Cleanup all state used by the implementation */
+ void (*cb_cleanup) (void);
+ /************************/
+ /* PER-CLASS OPERATIONS */
+ /* Get a new method index within a class */
+ int (*cb_get_new_index) (int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+ /* Initialise a new CRYPTO_EX_DATA of a given class */
+ int (*cb_new_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad);
+ /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
+ int (*cb_dup_ex_data) (int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from);
+ /* Cleanup a CRYPTO_EX_DATA of a given class */
+ void (*cb_free_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad);
+};
+
+/* The implementation we use at run-time */
+static const CRYPTO_EX_DATA_IMPL *impl = NULL;
+
+/*
+ * To call "impl" functions, use this macro rather than referring to 'impl'
+ * directly, eg. EX_IMPL(get_new_index)(...);
+ */
+#define EX_IMPL(a) impl->cb_##a
+
+/* Predeclare the "default" ex_data implementation */
+static int int_new_class(void);
+static void int_cleanup(void);
+static int int_get_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from);
+static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+static CRYPTO_EX_DATA_IMPL impl_default = {
+ int_new_class,
+ int_cleanup,
+ int_get_new_index,
+ int_new_ex_data,
+ int_dup_ex_data,
+ int_free_ex_data
+};
+
+/*
+ * Internal function that checks whether "impl" is set and if not, sets it to
+ * the default.
+ */
+static void impl_check(void)
+{
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ if (!impl)
+ impl = &impl_default;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+}
+
+/*
+ * A macro wrapper for impl_check that first uses a non-locked test before
+ * invoking the function (which checks again inside a lock).
+ */
+#define IMPL_CHECK if(!impl) impl_check();
+
+/* API functions to get/set the "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void)
+{
+ IMPL_CHECK return impl;
+}
+
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
+{
+ int toret = 0;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ if (!impl) {
+ impl = i;
+ toret = 1;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+/****************************************************************************/
+/*
+ * Interal (default) implementation of "ex_data" support. API functions are
+ * further down.
+ */
+
+/*
+ * The type that represents what each "class" used to implement locally. A
+ * STACK of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is
+ * the global value representing the class that is used to distinguish these
+ * items.
+ */
+typedef struct st_ex_class_item {
+ int class_index;
+ STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
+ int meth_num;
+} EX_CLASS_ITEM;
+
+/* When assigning new class indexes, this is our counter */
+static int ex_class = CRYPTO_EX_INDEX_USER;
+
+/* The global hash table of EX_CLASS_ITEM items */
+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_class_item_hash(const EX_CLASS_ITEM *a)
+{
+ return a->class_index;
+}
+
+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 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
+ */
+static int ex_data_check(void)
+{
+ int toret = 1;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ if (!ex_data && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
+ toret = 0;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+/*
+ * This macros helps reduce the locking from repeated checks because the
+ * ex_data_check() function checks ex_data again inside a lock.
+ */
+#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
+
+/* This "inner" callback is used by the callback function that follows it */
+static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
+{
+ OPENSSL_free(funcs);
+}
+
+/*
+ * This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
+ * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't
+ * do any locking.
+ */
+static void def_cleanup_cb(void *a_void)
+{
+ EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
+ sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
+ OPENSSL_free(item);
+}
+
+/*
+ * Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to
+ * a given class. Handles locking.
+ */
+static EX_CLASS_ITEM *def_get_class(int class_index)
+{
+ EX_CLASS_ITEM d, *p, *gen;
+ EX_DATA_CHECK(return NULL;)
+ d.class_index = class_index;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
+ if (!p) {
+ gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
+ if (gen) {
+ gen->class_index = class_index;
+ gen->meth_num = 0;
+ gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
+ if (!gen->meth)
+ OPENSSL_free(gen);
+ else {
+ /*
+ * Because we're inside the ex_data lock, the return value
+ * from the insert will be NULL
+ */
+ (void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
+ p = gen;
+ }
+ }
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ if (!p)
+ CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE);
+ return p;
+}
+
+/*
+ * Add a new method to the given EX_CLASS_ITEM and return the corresponding
+ * index (or -1 for error). Handles locking.
+ */
+static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ int toret = -1;
+ CRYPTO_EX_DATA_FUNCS *a =
+ (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS));
+ if (!a) {
+ CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ a->argl = argl;
+ a->argp = argp;
+ a->new_func = new_func;
+ a->dup_func = dup_func;
+ a->free_func = free_func;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) {
+ if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) {
+ CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(a);
+ goto err;
+ }
+ }
+ toret = item->meth_num++;
+ (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
+ err:
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+/**************************************************************/
+/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
+
+static int int_new_class(void)
+{
+ int toret;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ toret = ex_class++;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+static void int_cleanup(void)
+{
+ EX_DATA_CHECK(return;)
+ lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
+ lh_EX_CLASS_ITEM_free(ex_data);
+ ex_data = NULL;
+ impl = NULL;
+}
+
+static int int_get_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ EX_CLASS_ITEM *item = def_get_class(class_index);
+ if (!item)
+ return -1;
+ return def_add_index(item, argl, argp, new_func, dup_func, free_func);
+}
+
+/*
+ * Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries
+ * in the lock, then using them outside the lock. NB: Thread-safety only
+ * applies to the global "ex_data" state (ie. class definitions), not
+ * thread-safe on 'ad' itself.
+ */
+static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ int mx, i;
+ void *ptr;
+ CRYPTO_EX_DATA_FUNCS **storage = NULL;
+ EX_CLASS_ITEM *item = def_get_class(class_index);
+ if (!item)
+ /* error is already set */
+ return 0;
+ ad->sk = NULL;
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+ if (mx > 0) {
+ storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
+ if (!storage)
+ goto skip;
+ for (i = 0; i < mx; i++)
+ storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ }
+ skip:
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ if ((mx > 0) && !storage) {
+ CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ for (i = 0; i < mx; i++) {
+ if (storage[i] && storage[i]->new_func) {
+ ptr = CRYPTO_get_ex_data(ad, i);
+ storage[i]->new_func(obj, ptr, ad, i,
+ storage[i]->argl, storage[i]->argp);
+ }
+ }
+ if (storage)
+ OPENSSL_free(storage);
+ return 1;
+}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from)
+{
+ int mx, j, i;
+ char *ptr;
+ CRYPTO_EX_DATA_FUNCS **storage = NULL;
+ EX_CLASS_ITEM *item;
+ if (!from->sk)
+ /* 'to' should be "blank" which *is* just like 'from' */
+ return 1;
+ if ((item = def_get_class(class_index)) == NULL)
+ return 0;
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+ j = sk_void_num(from->sk);
+ if (j < mx)
+ mx = j;
+ if (mx > 0) {
+ storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
+ if (!storage)
+ goto skip;
+ for (i = 0; i < mx; i++)
+ storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ }
+ skip:
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ if ((mx > 0) && !storage) {
+ CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ for (i = 0; i < mx; i++) {
+ ptr = CRYPTO_get_ex_data(from, i);
+ if (storage[i] && storage[i]->dup_func)
+ storage[i]->dup_func(to, from, &ptr, i,
+ storage[i]->argl, storage[i]->argp);
+ CRYPTO_set_ex_data(to, i, ptr);
+ }
+ if (storage)
+ OPENSSL_free(storage);
+ return 1;
+}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ int mx, i;
+ EX_CLASS_ITEM *item;
+ void *ptr;
+ CRYPTO_EX_DATA_FUNCS **storage = NULL;
+ if (ex_data == NULL)
+ return;
+ if ((item = def_get_class(class_index)) == NULL)
+ return;
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+ if (mx > 0) {
+ storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
+ if (!storage)
+ goto skip;
+ for (i = 0; i < mx; i++)
+ storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ }
+ skip:
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ if ((mx > 0) && !storage) {
+ CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return;
+ }
+ for (i = 0; i < mx; i++) {
+ if (storage[i] && storage[i]->free_func) {
+ ptr = CRYPTO_get_ex_data(ad, i);
+ storage[i]->free_func(obj, ptr, ad, i,
+ storage[i]->argl, storage[i]->argp);
+ }
+ }
+ if (storage)
+ OPENSSL_free(storage);
+ if (ad->sk) {
+ sk_void_free(ad->sk);
+ ad->sk = NULL;
+ }
+}
+
+/********************************************************************/
+/*
+ * API functions that defer all "state" operations to the "ex_data"
+ * implementation we have set.
+ */
+
+/*
+ * Obtain an index for a new class (not the same as getting a new index
+ * within an existing class - this is actually getting a new *class*)
+ */
+int CRYPTO_ex_data_new_class(void)
+{
+ IMPL_CHECK return EX_IMPL(new_class) ();
+}
+
+/*
+ * Release all "ex_data" state to prevent memory leaks. This can't be made
+ * thread-safe without overhauling a lot of stuff, and shouldn't really be
+ * called under potential race-conditions anyway (it's for program shutdown
+ * after all).
+ */
+void CRYPTO_cleanup_all_ex_data(void)
+{
+ IMPL_CHECK EX_IMPL(cleanup) ();
+}
+
+/* Inside an existing class, get/register a new index. */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ int ret = -1;
+
+ IMPL_CHECK
+ ret = EX_IMPL(get_new_index) (class_index,
+ argl, argp, new_func, dup_func,
+ free_func);
+ return ret;
+}
+
+/*
+ * Initialise a new CRYPTO_EX_DATA for use in a particular class - including
+ * calling new() callbacks for each index in the class used by this variable
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ IMPL_CHECK return EX_IMPL(new_ex_data) (class_index, obj, ad);
+}
+
+/*
+ * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
+ * for each index in the class used by this variable
+ */
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from)
+{
+ IMPL_CHECK return EX_IMPL(dup_ex_data) (class_index, to, from);
+}
+
+/*
+ * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
+ * each index in the class used by this variable
+ */
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ IMPL_CHECK EX_IMPL(free_ex_data) (class_index, obj, ad);
+}
+
+/*
+ * For a given CRYPTO_EX_DATA variable, set the value corresponding to a
+ * particular index in the class used by this variable
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
+{
+ int i;
+
+ if (ad->sk == NULL) {
+ if ((ad->sk = sk_void_new_null()) == NULL) {
+ CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ }
+ i = sk_void_num(ad->sk);
+
+ while (i <= idx) {
+ if (!sk_void_push(ad->sk, NULL)) {
+ CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ i++;
+ }
+ sk_void_set(ad->sk, idx, val);
+ return (1);
+}
+
+/*
+ * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
+ * particular index in the class used by this variable
+ */
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
+{
+ if (ad->sk == NULL)
+ return (0);
+ else if (idx >= sk_void_num(ad->sk))
+ return (0);
+ else
+ return (sk_void_value(ad->sk, idx));
+}
+
+IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
diff --git a/Cryptlib/OpenSSL/crypto/fips_ers.c b/Cryptlib/OpenSSL/crypto/fips_ers.c
new file mode 100644
index 00000000..1788ed28
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/fips_ers.c
@@ -0,0 +1,7 @@
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+# include "fips_err.h"
+#else
+static void *dummy = &dummy;
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/hmac/hm_ameth.c b/Cryptlib/OpenSSL/crypto/hmac/hm_ameth.c
new file mode 100644
index 00000000..944c6c85
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/hmac/hm_ameth.c
@@ -0,0 +1,167 @@
+/*
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#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.
+ */
+
+static int hmac_size(const EVP_PKEY *pkey)
+{
+ return EVP_MAX_MD_SIZE;
+}
+
+static void hmac_key_free(EVP_PKEY *pkey)
+{
+ ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+ if (os) {
+ if (os->data)
+ OPENSSL_cleanse(os->data, os->length);
+ ASN1_OCTET_STRING_free(os);
+ }
+}
+
+static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+ switch (op) {
+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+ *(int *)arg2 = NID_sha256;
+ 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))
+ goto err;
+ if (!EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os))
+ goto err;
+ return 1;
+
+ err:
+ ASN1_OCTET_STRING_free(os);
+ return 0;
+}
+
+static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+ 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, 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/Cryptlib/OpenSSL/crypto/hmac/hm_pmeth.c b/Cryptlib/OpenSSL/crypto/hmac/hm_pmeth.c
new file mode 100644
index 00000000..0ffff79c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/hmac/hm_pmeth.c
@@ -0,0 +1,262 @@
+/*
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#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);
+ if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
+ return 0;
+ if (sctx->ktmp.data) {
+ if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
+ sctx->ktmp.data, sctx->ktmp.length))
+ return 0;
+ }
+ return 1;
+}
+
+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+ HMAC_PKEY_CTX *hctx = ctx->data;
+ 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;
+ if (!HMAC_Update(&hctx->ctx, data, count))
+ return 0;
+ return 1;
+}
+
+static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+ HMAC_PKEY_CTX *hctx = ctx->data;
+ HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
+ 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;
+
+ if (!HMAC_Final(&hctx->ctx, sig, &hlen))
+ return 0;
+ *siglen = (size_t)hlen;
+ return 1;
+}
+
+static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+ HMAC_PKEY_CTX *hctx = ctx->data;
+ ASN1_OCTET_STRING *key;
+ switch (type) {
+
+ case EVP_PKEY_CTRL_SET_MAC_KEY:
+ if ((!p2 && p1 > 0) || (p1 < -1))
+ return 0;
+ if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
+ return 0;
+ break;
+
+ case EVP_PKEY_CTRL_MD:
+ hctx->md = p2;
+ break;
+
+ case EVP_PKEY_CTRL_DIGESTINIT:
+ key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
+ if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
+ ctx->engine))
+ return 0;
+ break;
+
+ default:
+ 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/Cryptlib/OpenSSL/crypto/hmac/hmac.c b/Cryptlib/OpenSSL/crypto/hmac/hmac.c
new file mode 100644
index 00000000..51a0a3ef
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/hmac/hmac.c
@@ -0,0 +1,268 @@
+/* crypto/hmac/hmac.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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/hmac.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+ const EVP_MD *md, ENGINE *impl)
+{
+ int i, j, reset = 0;
+ unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+#ifdef OPENSSL_FIPS
+ /* If FIPS mode switch to approved implementation if possible */
+ if (FIPS_mode()) {
+ const EVP_MD *fipsmd;
+ if (md) {
+ fipsmd = FIPS_get_digestbynid(EVP_MD_type(md));
+ if (fipsmd)
+ md = fipsmd;
+ }
+ }
+
+ if (FIPS_mode()) {
+ /* If we have an ENGINE need to allow non FIPS */
+ if ((impl || ctx->i_ctx.engine)
+ && !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) {
+ EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS);
+ return 0;
+ }
+ /*
+ * Other algorithm blocking will be done in FIPS_cmac_init, via
+ * FIPS_hmac_init_ex().
+ */
+ if (!impl && !ctx->i_ctx.engine)
+ return FIPS_hmac_init_ex(ctx, key, len, md, NULL);
+ }
+#endif
+ /* If we are changing MD then we must have a key */
+ if (md != NULL && md != ctx->md && (key == NULL || len < 0))
+ return 0;
+
+ if (md != NULL) {
+ reset = 1;
+ ctx->md = md;
+ } else if (ctx->md) {
+ md = ctx->md;
+ } else {
+ return 0;
+ }
+
+ if (key != NULL) {
+ reset = 1;
+ j = EVP_MD_block_size(md);
+ OPENSSL_assert(j <= (int)sizeof(ctx->key));
+ if (j < len) {
+ 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 {
+ if (len < 0 || len > (int)sizeof(ctx->key))
+ return 0;
+ memcpy(ctx->key, key, len);
+ ctx->key_length = len;
+ }
+ if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
+ memset(&ctx->key[ctx->key_length], 0,
+ HMAC_MAX_MD_CBLOCK - ctx->key_length);
+ }
+
+ if (reset) {
+ for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+ pad[i] = 0x36 ^ ctx->key[i];
+ 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; i < HMAC_MAX_MD_CBLOCK; i++)
+ pad[i] = 0x5c ^ ctx->key[i];
+ 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;
+ }
+ if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx))
+ goto err;
+ return 1;
+ err:
+ return 0;
+}
+
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
+{
+ if (key && md)
+ HMAC_CTX_init(ctx);
+ return HMAC_Init_ex(ctx, key, len, md, NULL);
+}
+
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->i_ctx.engine)
+ return FIPS_hmac_update(ctx, data, len);
+#endif
+ if (!ctx->md)
+ return 0;
+
+ return EVP_DigestUpdate(&ctx->md_ctx, data, len);
+}
+
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+{
+ unsigned int i;
+ unsigned char buf[EVP_MAX_MD_SIZE];
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->i_ctx.engine)
+ return FIPS_hmac_final(ctx, md, len);
+#endif
+
+ if (!ctx->md)
+ goto err;
+
+ 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)
+{
+ EVP_MD_CTX_init(&ctx->i_ctx);
+ EVP_MD_CTX_init(&ctx->o_ctx);
+ EVP_MD_CTX_init(&ctx->md_ctx);
+ ctx->md = NULL;
+}
+
+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)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !ctx->i_ctx.engine) {
+ FIPS_hmac_ctx_cleanup(ctx);
+ return;
+ }
+#endif
+ EVP_MD_CTX_cleanup(&ctx->i_ctx);
+ EVP_MD_CTX_cleanup(&ctx->o_ctx);
+ EVP_MD_CTX_cleanup(&ctx->md_ctx);
+ memset(ctx, 0, sizeof *ctx);
+}
+
+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)
+{
+ HMAC_CTX c;
+ static unsigned char m[EVP_MAX_MD_SIZE];
+
+ if (md == NULL)
+ md = m;
+ HMAC_CTX_init(&c);
+ 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;
+ err:
+ HMAC_CTX_cleanup(&c);
+ return NULL;
+}
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
+{
+ EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
+ EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
+ EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+}
diff --git a/Cryptlib/OpenSSL/crypto/krb5/krb5_asn.c b/Cryptlib/OpenSSL/crypto/krb5/krb5_asn.c
new file mode 100644
index 00000000..d9851e97
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/krb5/krb5_asn.c
@@ -0,0 +1,162 @@
+/* krb5_asn.c */
+/*
+ * Written by Vern Staats <staatsvr@asc.hpc.mil> 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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/krb5_asn.h>
+
+
+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/Cryptlib/OpenSSL/crypto/lhash/lh_stats.c b/Cryptlib/OpenSSL/crypto/lhash/lh_stats.c
new file mode 100644
index 00000000..0bfec232
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/lhash/lh_stats.c
@@ -0,0 +1,246 @@
+/* crypto/lhash/lh_stats.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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+/*
+ * If you wish to build this outside of SSLeay, remove the following lines
+ * and things should work as expected
+ */
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+#endif
+#include <openssl/lhash.h>
+
+#ifdef OPENSSL_NO_BIO
+
+void lh_stats(LHASH *lh, FILE *out)
+{
+ fprintf(out, "num_items = %lu\n", lh->num_items);
+ fprintf(out, "num_nodes = %u\n", lh->num_nodes);
+ fprintf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes);
+ fprintf(out, "num_expands = %lu\n", lh->num_expands);
+ fprintf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs);
+ fprintf(out, "num_contracts = %lu\n", lh->num_contracts);
+ fprintf(out, "num_contract_reallocs = %lu\n", lh->num_contract_reallocs);
+ fprintf(out, "num_hash_calls = %lu\n", lh->num_hash_calls);
+ fprintf(out, "num_comp_calls = %lu\n", lh->num_comp_calls);
+ fprintf(out, "num_insert = %lu\n", lh->num_insert);
+ fprintf(out, "num_replace = %lu\n", lh->num_replace);
+ fprintf(out, "num_delete = %lu\n", lh->num_delete);
+ fprintf(out, "num_no_delete = %lu\n", lh->num_no_delete);
+ fprintf(out, "num_retrieve = %lu\n", lh->num_retrieve);
+ fprintf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss);
+ fprintf(out, "num_hash_comps = %lu\n", lh->num_hash_comps);
+# if 0
+ fprintf(out, "p = %u\n", lh->p);
+ fprintf(out, "pmax = %u\n", lh->pmax);
+ fprintf(out, "up_load = %lu\n", lh->up_load);
+ fprintf(out, "down_load = %lu\n", lh->down_load);
+# endif
+}
+
+void lh_node_stats(LHASH *lh, FILE *out)
+{
+ LHASH_NODE *n;
+ unsigned int i, num;
+
+ for (i = 0; i < lh->num_nodes; i++) {
+ for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+ num++;
+ fprintf(out, "node %6u -> %3u\n", i, num);
+ }
+}
+
+void lh_node_usage_stats(LHASH *lh, FILE *out)
+{
+ LHASH_NODE *n;
+ unsigned long num;
+ unsigned int i;
+ unsigned long total = 0, n_used = 0;
+
+ for (i = 0; i < lh->num_nodes; i++) {
+ for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+ num++;
+ if (num != 0) {
+ n_used++;
+ total += num;
+ }
+ }
+ fprintf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes);
+ fprintf(out, "%lu items\n", total);
+ if (n_used == 0)
+ return;
+ fprintf(out, "load %d.%02d actual load %d.%02d\n",
+ (int)(total / lh->num_nodes),
+ (int)((total % lh->num_nodes) * 100 / lh->num_nodes),
+ (int)(total / n_used), (int)((total % n_used) * 100 / n_used));
+}
+
+#else
+
+# ifndef OPENSSL_NO_FP_API
+void lh_stats(const _LHASH *lh, FILE *fp)
+{
+ BIO *bp;
+
+ bp = BIO_new(BIO_s_file());
+ if (bp == NULL)
+ goto end;
+ BIO_set_fp(bp, fp, BIO_NOCLOSE);
+ lh_stats_bio(lh, bp);
+ BIO_free(bp);
+ end:;
+}
+
+void lh_node_stats(const _LHASH *lh, FILE *fp)
+{
+ BIO *bp;
+
+ bp = BIO_new(BIO_s_file());
+ if (bp == NULL)
+ goto end;
+ BIO_set_fp(bp, fp, BIO_NOCLOSE);
+ lh_node_stats_bio(lh, bp);
+ BIO_free(bp);
+ end:;
+}
+
+void lh_node_usage_stats(const _LHASH *lh, FILE *fp)
+{
+ BIO *bp;
+
+ bp = BIO_new(BIO_s_file());
+ if (bp == NULL)
+ goto end;
+ BIO_set_fp(bp, fp, BIO_NOCLOSE);
+ lh_node_usage_stats_bio(lh, bp);
+ BIO_free(bp);
+ end:;
+}
+
+# endif
+
+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);
+ BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes);
+ BIO_printf(out, "num_expands = %lu\n", lh->num_expands);
+ BIO_printf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs);
+ BIO_printf(out, "num_contracts = %lu\n", lh->num_contracts);
+ BIO_printf(out, "num_contract_reallocs = %lu\n",
+ lh->num_contract_reallocs);
+ BIO_printf(out, "num_hash_calls = %lu\n", lh->num_hash_calls);
+ BIO_printf(out, "num_comp_calls = %lu\n", lh->num_comp_calls);
+ BIO_printf(out, "num_insert = %lu\n", lh->num_insert);
+ BIO_printf(out, "num_replace = %lu\n", lh->num_replace);
+ BIO_printf(out, "num_delete = %lu\n", lh->num_delete);
+ BIO_printf(out, "num_no_delete = %lu\n", lh->num_no_delete);
+ BIO_printf(out, "num_retrieve = %lu\n", lh->num_retrieve);
+ BIO_printf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss);
+ BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps);
+# if 0
+ BIO_printf(out, "p = %u\n", lh->p);
+ BIO_printf(out, "pmax = %u\n", lh->pmax);
+ BIO_printf(out, "up_load = %lu\n", lh->up_load);
+ BIO_printf(out, "down_load = %lu\n", lh->down_load);
+# endif
+}
+
+void lh_node_stats_bio(const _LHASH *lh, BIO *out)
+{
+ LHASH_NODE *n;
+ unsigned int i, num;
+
+ for (i = 0; i < lh->num_nodes; i++) {
+ for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+ num++;
+ BIO_printf(out, "node %6u -> %3u\n", i, num);
+ }
+}
+
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out)
+{
+ LHASH_NODE *n;
+ unsigned long num;
+ unsigned int i;
+ unsigned long total = 0, n_used = 0;
+
+ for (i = 0; i < lh->num_nodes; i++) {
+ for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+ num++;
+ if (num != 0) {
+ n_used++;
+ total += num;
+ }
+ }
+ BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes);
+ BIO_printf(out, "%lu items\n", total);
+ if (n_used == 0)
+ return;
+ BIO_printf(out, "load %d.%02d actual load %d.%02d\n",
+ (int)(total / lh->num_nodes),
+ (int)((total % lh->num_nodes) * 100 / lh->num_nodes),
+ (int)(total / n_used), (int)((total % n_used) * 100 / n_used));
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/lhash/lhash.c b/Cryptlib/OpenSSL/crypto/lhash/lhash.c
new file mode 100644
index 00000000..53c5c138
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/lhash/lhash.c
@@ -0,0 +1,458 @@
+/* crypto/lhash/lhash.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.]
+ */
+
+/*-
+ * Code for dynamic hash table routines
+ * Author - Eric Young v 2.0
+ *
+ * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
+ * present. eay 18-Jun-98
+ *
+ * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
+ *
+ * 2.0 eay - Fixed a bug that occurred when using lh_delete
+ * from inside lh_doall(). As entries were deleted,
+ * the 'table' was 'contract()ed', making some entries
+ * jump from the end of the table to the start, there by
+ * skipping the lh_doall() processing. eay - 4/12/95
+ *
+ * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
+ * were not being free()ed. 21/11/95
+ *
+ * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
+ * 19/09/95
+ *
+ * 1.7 eay - Removed the fputs() for realloc failures - the code
+ * should silently tolerate them. I have also fixed things
+ * lint complained about 04/05/95
+ *
+ * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
+ *
+ * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
+ *
+ * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
+ *
+ * 1.3 eay - Fixed a few lint problems 19/3/1991
+ *
+ * 1.2 eay - Fixed lh_doall problem 13/3/1991
+ *
+ * 1.1 eay - Added lh_doall
+ *
+ * 1.0 eay - First version
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+
+const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT;
+
+#undef MIN_NODES
+#define MIN_NODES 16
+#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);
+
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
+{
+ _LHASH *ret;
+ int i;
+
+ if ((ret = OPENSSL_malloc(sizeof(_LHASH))) == NULL)
+ goto err0;
+ if ((ret->b = OPENSSL_malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL)
+ goto err1;
+ for (i = 0; i < MIN_NODES; i++)
+ ret->b[i] = NULL;
+ ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c);
+ ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h);
+ ret->num_nodes = MIN_NODES / 2;
+ ret->num_alloc_nodes = MIN_NODES;
+ ret->p = 0;
+ ret->pmax = MIN_NODES / 2;
+ ret->up_load = UP_LOAD;
+ ret->down_load = DOWN_LOAD;
+ ret->num_items = 0;
+
+ ret->num_expands = 0;
+ ret->num_expand_reallocs = 0;
+ ret->num_contracts = 0;
+ ret->num_contract_reallocs = 0;
+ ret->num_hash_calls = 0;
+ ret->num_comp_calls = 0;
+ ret->num_insert = 0;
+ ret->num_replace = 0;
+ ret->num_delete = 0;
+ ret->num_no_delete = 0;
+ ret->num_retrieve = 0;
+ ret->num_retrieve_miss = 0;
+ ret->num_hash_comps = 0;
+
+ ret->error = 0;
+ return (ret);
+ err1:
+ OPENSSL_free(ret);
+ err0:
+ return (NULL);
+}
+
+void lh_free(_LHASH *lh)
+{
+ unsigned int i;
+ LHASH_NODE *n, *nn;
+
+ if (lh == NULL)
+ return;
+
+ for (i = 0; i < lh->num_nodes; i++) {
+ n = lh->b[i];
+ while (n != NULL) {
+ nn = n->next;
+ OPENSSL_free(n);
+ n = nn;
+ }
+ }
+ OPENSSL_free(lh->b);
+ OPENSSL_free(lh);
+}
+
+void *lh_insert(_LHASH *lh, void *data)
+{
+ unsigned long hash;
+ LHASH_NODE *nn, **rn;
+ void *ret;
+
+ lh->error = 0;
+ if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))
+ expand(lh);
+
+ rn = getrn(lh, data, &hash);
+
+ if (*rn == NULL) {
+ if ((nn = (LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL) {
+ lh->error++;
+ return (NULL);
+ }
+ nn->data = data;
+ nn->next = NULL;
+#ifndef OPENSSL_NO_HASH_COMP
+ nn->hash = hash;
+#endif
+ *rn = nn;
+ ret = NULL;
+ lh->num_insert++;
+ lh->num_items++;
+ } else { /* replace same key */
+
+ ret = (*rn)->data;
+ (*rn)->data = data;
+ lh->num_replace++;
+ }
+ return (ret);
+}
+
+void *lh_delete(_LHASH *lh, const void *data)
+{
+ unsigned long hash;
+ LHASH_NODE *nn, **rn;
+ void *ret;
+
+ lh->error = 0;
+ rn = getrn(lh, data, &hash);
+
+ if (*rn == NULL) {
+ lh->num_no_delete++;
+ return (NULL);
+ } else {
+ nn = *rn;
+ *rn = nn->next;
+ ret = nn->data;
+ OPENSSL_free(nn);
+ lh->num_delete++;
+ }
+
+ lh->num_items--;
+ if ((lh->num_nodes > MIN_NODES) &&
+ (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
+ contract(lh);
+
+ return (ret);
+}
+
+void *lh_retrieve(_LHASH *lh, const void *data)
+{
+ unsigned long hash;
+ LHASH_NODE **rn;
+ void *ret;
+
+ lh->error = 0;
+ rn = getrn(lh, data, &hash);
+
+ if (*rn == NULL) {
+ lh->num_retrieve_miss++;
+ return (NULL);
+ } else {
+ ret = (*rn)->data;
+ lh->num_retrieve++;
+ }
+ return (ret);
+}
+
+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--) {
+ a = lh->b[i];
+ while (a != NULL) {
+ /*
+ * 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);
+ else
+ func(a->data);
+ a = n;
+ }
+ }
+}
+
+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)
+{
+ doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
+}
+
+static void expand(_LHASH *lh)
+{
+ LHASH_NODE **n, **n1, **n2, *np;
+ unsigned int p, i, j;
+ unsigned long hash, nni;
+
+ lh->num_nodes++;
+ lh->num_expands++;
+ p = (int)lh->p++;
+ n1 = &(lh->b[p]);
+ 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;) {
+#ifndef OPENSSL_NO_HASH_COMP
+ hash = np->hash;
+#else
+ hash = lh->hash(np->data);
+ lh->num_hash_calls++;
+#endif
+ if ((hash % nni) != p) { /* move it */
+ *n1 = (*n1)->next;
+ np->next = *n2;
+ *n2 = np;
+ } else
+ n1 = &((*n1)->next);
+ 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; i < j; i++) /* 26/02/92 eay */
+ n[i] = NULL; /* 02/03/92 eay */
+ lh->pmax = lh->num_alloc_nodes;
+ lh->num_alloc_nodes = j;
+ lh->num_expand_reallocs++;
+ lh->p = 0;
+ lh->b = n;
+ }
+}
+
+static void contract(_LHASH *lh)
+{
+ LHASH_NODE **n, *n1, *np;
+
+ 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,
+ (unsigned int)(sizeof(LHASH_NODE *)
+ * lh->pmax));
+ if (n == NULL) {
+/* fputs("realloc error in lhash",stderr); */
+ lh->error++;
+ return;
+ }
+ lh->num_contract_reallocs++;
+ lh->num_alloc_nodes /= 2;
+ lh->pmax /= 2;
+ lh->p = lh->pmax - 1;
+ lh->b = n;
+ } else
+ lh->p--;
+
+ lh->num_nodes--;
+ lh->num_contracts++;
+
+ n1 = lh->b[(int)lh->p];
+ if (n1 == NULL)
+ lh->b[(int)lh->p] = np;
+ else {
+ while (n1->next != NULL)
+ n1 = n1->next;
+ n1->next = np;
+ }
+}
+
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
+{
+ LHASH_NODE **ret, *n1;
+ unsigned long hash, nn;
+ LHASH_COMP_FN_TYPE cf;
+
+ hash = (*(lh->hash)) (data);
+ lh->num_hash_calls++;
+ *rhash = hash;
+
+ nn = hash % lh->pmax;
+ if (nn < lh->p)
+ nn = hash % lh->num_alloc_nodes;
+
+ cf = lh->comp;
+ ret = &(lh->b[(int)nn]);
+ for (n1 = *ret; n1 != NULL; n1 = n1->next) {
+#ifndef OPENSSL_NO_HASH_COMP
+ lh->num_hash_comps++;
+ if (n1->hash != hash) {
+ ret = &(n1->next);
+ continue;
+ }
+#endif
+ lh->num_comp_calls++;
+ if (cf(n1->data, data) == 0)
+ break;
+ ret = &(n1->next);
+ }
+ return (ret);
+}
+
+/*
+ * The following hash seems to work very well on normal text strings no
+ * collisions on /usr/dict/words and it distributes on %2^n quite well, not
+ * as good as MD5, but still good.
+ */
+unsigned long lh_strhash(const char *c)
+{
+ unsigned long ret = 0;
+ long n;
+ unsigned long v;
+ int r;
+
+ if ((c == NULL) || (*c == '\0'))
+ return (ret);
+/*-
+ unsigned char b[16];
+ MD5(c,strlen(c),b);
+ return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
+*/
+
+ n = 0x100;
+ while (*c) {
+ v = n | (*c);
+ n += 0x100;
+ r = (int)((v >> 2) ^ v) & 0x0f;
+ ret = (ret << r) | (ret >> (32 - r));
+ ret &= 0xFFFFFFFFL;
+ ret ^= v * v;
+ c++;
+ }
+ return ((ret >> 16) ^ ret);
+}
+
+unsigned long lh_num_items(const _LHASH *lh)
+{
+ return lh ? lh->num_items : 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/md32_common.h b/Cryptlib/OpenSSL/crypto/md32_common.h
new file mode 100644
index 00000000..96828d26
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md32_common.h
@@ -0,0 +1,428 @@
+/* crypto/md32_common.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
+ * 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 is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ * this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ * size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ * has to be at lest 32 bit wide, if it's wider, then
+ * HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ * context structure that at least contains following
+ * members:
+ * typedef struct {
+ * ...
+ * HASH_LONG Nl,Nh;
+ * either {
+ * HASH_LONG data[HASH_LBLOCK];
+ * unsigned char data[HASH_CBLOCK];
+ * };
+ * unsigned int num;
+ * ...
+ * } HASH_CTX;
+ * data[] vector is expected to be zeroed upon first call to
+ * HASH_UPDATE.
+ * HASH_UPDATE
+ * name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ * name of "Transform" function, implemented here.
+ * HASH_FINAL
+ * name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ * name of "block" function capable of treating *unaligned* input
+ * message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ * macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ * #define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ * #define HASH_LONG MD5_LONG
+ * #define HASH_LONG_LOG2 MD5_LONG_LOG2
+ * #define HASH_CTX MD5_CTX
+ * #define HASH_CBLOCK MD5_CBLOCK
+ * #define HASH_UPDATE MD5_Update
+ * #define HASH_TRANSFORM MD5_Transform
+ * #define HASH_FINAL MD5_Final
+ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+# error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+# error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+# error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+# error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+# error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+# error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_DATA_ORDER
+# error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER)
+# define ROTATE(a,n) _lrotl(a,n)
+# elif defined(__ICC)
+# define ROTATE(a,n) _rotl(a,n)
+# elif defined(__MWERKS__)
+# if defined(__POWERPC__)
+# define ROTATE(a,n) __rlwinm(a,n,0,31)
+# elif defined(__MC68K__)
+ /* Motorola specific tweak. <appro@fy.chalmers.se> */
+# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
+# else
+# define ROTATE(a,n) __rol(a,n)
+# endif
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+ /*
+ * Some GNU C inline assembler templates. Note that these are
+ * rotates by *constant* number of bits! But that's exactly
+ * what we need here...
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "roll %1,%0" \
+ : "=r"(ret) \
+ : "I"(n), "0"((unsigned int)(a)) \
+ : "cc"); \
+ ret; \
+ })
+# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+ defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "rlwinm %0,%1,%2,0,31" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+# elif defined(__s390x__)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ("rll %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+# endif
+# endif
+#endif /* PEDANTIC */
+
+#ifndef ROTATE
+# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+# ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
+ (defined(__x86_64) || defined(__x86_64__))
+# if !defined(B_ENDIAN)
+ /*
+ * This gives ~30-40% performance improvement in SHA-256 compiled
+ * with gcc [on P4]. Well, first macro to be frank. We can pull
+ * this trick on x86* platforms only, because these CPUs can fetch
+ * unaligned data without raising an exception.
+ */
+# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \
+ asm ("bswapl %0":"=r"(r):"0"(r)); \
+ (c)+=4; (l)=r; })
+# define HOST_l2c(l,c) ({ unsigned int r=(l); \
+ asm ("bswapl %0":"=r"(r):"0"(r)); \
+ *((unsigned int *)(c))=r; (c)+=4; r; })
+# endif
+# elif defined(__aarch64__)
+# if defined(__BYTE_ORDER__)
+# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
+# define HOST_c2l(c,l) ({ unsigned int r; \
+ asm ("rev %w0,%w1" \
+ :"=r"(r) \
+ :"r"(*((const unsigned int *)(c))));\
+ (c)+=4; (l)=r; })
+# define HOST_l2c(l,c) ({ unsigned int r; \
+ asm ("rev %w0,%w1" \
+ :"=r"(r) \
+ :"r"((unsigned int)(l)));\
+ *((unsigned int *)(c))=r; (c)+=4; r; })
+# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
+# endif
+# endif
+# endif
+# endif
+# if defined(__s390__) || defined(__s390x__)
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
+# endif
+# endif
+
+# ifndef HOST_c2l
+# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ) )
+# endif
+# ifndef HOST_l2c
+# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff), \
+ l)
+# endif
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+# 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,%1" \
+ :"=d"(l) :"m"(*(const unsigned int *)(c)));\
+ (c)+=4; (l); })
+# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \
+ :"=m"(*(unsigned int *)(c)) :"d"(l));\
+ (c)+=4; (l); })
+# endif
+# endif
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+# ifndef B_ENDIAN
+ /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
+# endif
+# endif
+# endif
+
+# ifndef HOST_c2l
+# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24) )
+# endif
+# ifndef HOST_l2c
+# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ l)
+# endif
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+{
+ const unsigned char *data = data_;
+ unsigned char *p;
+ HASH_LONG l;
+ size_t n;
+
+ if (len == 0)
+ return 1;
+
+ l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
+ /*
+ * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
+ * <weidai@eskimo.com> for pointing it out.
+ */
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
+ * 16-bit */
+ c->Nl = l;
+
+ n = c->num;
+ if (n != 0) {
+ p = (unsigned char *)c->data;
+
+ if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
+ memcpy(p + n, data, HASH_CBLOCK - n);
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ n = HASH_CBLOCK - n;
+ data += n;
+ len -= n;
+ c->num = 0;
+ memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
+ } else {
+ memcpy(p + n, data, len);
+ c->num += (unsigned int)len;
+ return 1;
+ }
+ }
+
+ n = len / HASH_CBLOCK;
+ if (n > 0) {
+ HASH_BLOCK_DATA_ORDER(c, data, n);
+ n *= HASH_CBLOCK;
+ data += n;
+ len -= n;
+ }
+
+ if (len != 0) {
+ p = (unsigned char *)c->data;
+ c->num = (unsigned int)len;
+ memcpy(p, data, len);
+ }
+ return 1;
+}
+
+void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
+{
+ HASH_BLOCK_DATA_ORDER(c, data, 1);
+}
+
+int HASH_FINAL(unsigned char *md, HASH_CTX *c)
+{
+ unsigned char *p = (unsigned char *)c->data;
+ size_t n = c->num;
+
+ p[n] = 0x80; /* there is always room for one */
+ n++;
+
+ if (n > (HASH_CBLOCK - 8)) {
+ memset(p + n, 0, HASH_CBLOCK - n);
+ n = 0;
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ }
+ memset(p + n, 0, HASH_CBLOCK - 8 - n);
+
+ p += HASH_CBLOCK - 8;
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+ (void)HOST_l2c(c->Nh, p);
+ (void)HOST_l2c(c->Nl, p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+ (void)HOST_l2c(c->Nl, p);
+ (void)HOST_l2c(c->Nh, p);
+#endif
+ p -= HASH_CBLOCK;
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ c->num = 0;
+ memset(p, 0, HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+# error "HASH_MAKE_STRING must be defined!"
+#else
+ HASH_MAKE_STRING(c, md);
+#endif
+
+ return 1;
+}
+
+#ifndef MD32_REG_T
+# if defined(__alpha) || defined(__sparcv9) || defined(__mips)
+# define MD32_REG_T long
+/*
+ * This comment was originaly written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents*
+ * performance degradation.
+ * <appro@fy.chalmers.se>
+ */
+# else
+/*
+ * Above is not absolute and there are LP64 compilers that
+ * generate better code if MD32_REG_T is defined int. The above
+ * pre-processor condition reflects the circumstances under which
+ * the conclusion was made and is subject to further extension.
+ * <appro@fy.chalmers.se>
+ */
+# define MD32_REG_T int
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/md4/md4_dgst.c b/Cryptlib/OpenSSL/crypto/md4/md4_dgst.c
new file mode 100644
index 00000000..614fca00
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md4/md4_dgst.c
@@ -0,0 +1,199 @@
+/* crypto/md4/md4_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 <stdio.h>
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include "md4_locl.h"
+
+const char MD4_version[] = "MD4" OPENSSL_VERSION_PTEXT;
+
+/*
+ * Implemented from RFC1186 The MD4 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+fips_md_init(MD4)
+{
+ 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;
+ return 1;
+}
+
+#ifndef md4_block_data_order
+# ifdef X
+# undef X
+# endif
+void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num)
+{
+ const unsigned char *data = data_;
+ register unsigned MD32_REG_T A, B, C, D, l;
+# ifndef MD32_XARRAY
+ /* See comment in crypto/sha/sha_locl.h for details. */
+ unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+ XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+# define X(i) XX##i
+# else
+ MD4_LONG XX[MD4_LBLOCK];
+# define X(i) XX[i]
+# endif
+
+ A = c->A;
+ B = c->B;
+ C = c->C;
+ D = c->D;
+
+ for (; num--;) {
+ (void)HOST_c2l(data, l);
+ X(0) = l;
+ (void)HOST_c2l(data, l);
+ X(1) = l;
+ /* Round 0 */
+ R0(A, B, C, D, X(0), 3, 0);
+ (void)HOST_c2l(data, l);
+ X(2) = l;
+ R0(D, A, B, C, X(1), 7, 0);
+ (void)HOST_c2l(data, l);
+ X(3) = l;
+ R0(C, D, A, B, X(2), 11, 0);
+ (void)HOST_c2l(data, l);
+ X(4) = l;
+ R0(B, C, D, A, X(3), 19, 0);
+ (void)HOST_c2l(data, l);
+ X(5) = l;
+ R0(A, B, C, D, X(4), 3, 0);
+ (void)HOST_c2l(data, l);
+ X(6) = l;
+ R0(D, A, B, C, X(5), 7, 0);
+ (void)HOST_c2l(data, l);
+ X(7) = l;
+ R0(C, D, A, B, X(6), 11, 0);
+ (void)HOST_c2l(data, l);
+ X(8) = l;
+ R0(B, C, D, A, X(7), 19, 0);
+ (void)HOST_c2l(data, l);
+ X(9) = l;
+ R0(A, B, C, D, X(8), 3, 0);
+ (void)HOST_c2l(data, l);
+ X(10) = l;
+ R0(D, A, B, C, X(9), 7, 0);
+ (void)HOST_c2l(data, l);
+ X(11) = l;
+ R0(C, D, A, B, X(10), 11, 0);
+ (void)HOST_c2l(data, l);
+ X(12) = l;
+ R0(B, C, D, A, X(11), 19, 0);
+ (void)HOST_c2l(data, l);
+ X(13) = l;
+ R0(A, B, C, D, X(12), 3, 0);
+ (void)HOST_c2l(data, l);
+ X(14) = l;
+ R0(D, A, B, C, X(13), 7, 0);
+ (void)HOST_c2l(data, l);
+ X(15) = l;
+ R0(C, D, A, B, X(14), 11, 0);
+ R0(B, C, D, A, X(15), 19, 0);
+ /* Round 1 */
+ R1(A, B, C, D, X(0), 3, 0x5A827999L);
+ R1(D, A, B, C, X(4), 5, 0x5A827999L);
+ R1(C, D, A, B, X(8), 9, 0x5A827999L);
+ R1(B, C, D, A, X(12), 13, 0x5A827999L);
+ R1(A, B, C, D, X(1), 3, 0x5A827999L);
+ R1(D, A, B, C, X(5), 5, 0x5A827999L);
+ R1(C, D, A, B, X(9), 9, 0x5A827999L);
+ R1(B, C, D, A, X(13), 13, 0x5A827999L);
+ R1(A, B, C, D, X(2), 3, 0x5A827999L);
+ R1(D, A, B, C, X(6), 5, 0x5A827999L);
+ R1(C, D, A, B, X(10), 9, 0x5A827999L);
+ R1(B, C, D, A, X(14), 13, 0x5A827999L);
+ R1(A, B, C, D, X(3), 3, 0x5A827999L);
+ R1(D, A, B, C, X(7), 5, 0x5A827999L);
+ R1(C, D, A, B, X(11), 9, 0x5A827999L);
+ R1(B, C, D, A, X(15), 13, 0x5A827999L);
+ /* Round 2 */
+ R2(A, B, C, D, X(0), 3, 0x6ED9EBA1L);
+ R2(D, A, B, C, X(8), 9, 0x6ED9EBA1L);
+ R2(C, D, A, B, X(4), 11, 0x6ED9EBA1L);
+ R2(B, C, D, A, X(12), 15, 0x6ED9EBA1L);
+ R2(A, B, C, D, X(2), 3, 0x6ED9EBA1L);
+ R2(D, A, B, C, X(10), 9, 0x6ED9EBA1L);
+ R2(C, D, A, B, X(6), 11, 0x6ED9EBA1L);
+ R2(B, C, D, A, X(14), 15, 0x6ED9EBA1L);
+ R2(A, B, C, D, X(1), 3, 0x6ED9EBA1L);
+ R2(D, A, B, C, X(9), 9, 0x6ED9EBA1L);
+ R2(C, D, A, B, X(5), 11, 0x6ED9EBA1L);
+ R2(B, C, D, A, X(13), 15, 0x6ED9EBA1L);
+ R2(A, B, C, D, X(3), 3, 0x6ED9EBA1L);
+ R2(D, A, B, C, X(11), 9, 0x6ED9EBA1L);
+ R2(C, D, A, B, X(7), 11, 0x6ED9EBA1L);
+ R2(B, C, D, A, X(15), 15, 0x6ED9EBA1L);
+
+ A = c->A += A;
+ B = c->B += B;
+ C = c->C += C;
+ D = c->D += D;
+ }
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/md4/md4_locl.h b/Cryptlib/OpenSSL/crypto/md4/md4_locl.h
new file mode 100644
index 00000000..dc86a86c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md4/md4_locl.h
@@ -0,0 +1,113 @@
+/* crypto/md4/md4_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 <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/md4.h>
+
+#ifndef MD4_LONG_LOG2
+# define MD4_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+void md4_block_data_order(MD4_CTX *c, const void *p, size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG MD4_LONG
+#define HASH_CTX MD4_CTX
+#define HASH_CBLOCK MD4_CBLOCK
+#define HASH_UPDATE MD4_Update
+#define HASH_TRANSFORM MD4_Transform
+#define HASH_FINAL MD4_Final
+#define HASH_MAKE_STRING(c,s) do { \
+ unsigned long ll; \
+ ll=(c)->A; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->B; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->C; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->D; (void)HOST_l2c(ll,(s)); \
+ } while (0)
+#define HASH_BLOCK_DATA_ORDER md4_block_data_order
+
+#include "md32_common.h"
+
+/*-
+#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
+#define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z))))
+*/
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, the above can be simplified
+ * to the code below. Wei attributes these optimizations to Peter Gutmann's
+ * SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+#define H(b,c,d) ((b) ^ (c) ^ (d))
+
+#define R0(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+F((b),(c),(d))); \
+ a=ROTATE(a,s); };
+
+#define R1(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+G((b),(c),(d))); \
+ a=ROTATE(a,s); };\
+
+#define R2(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+H((b),(c),(d))); \
+ a=ROTATE(a,s); };
diff --git a/Cryptlib/OpenSSL/crypto/md4/md4_one.c b/Cryptlib/OpenSSL/crypto/md4/md4_one.c
new file mode 100644
index 00000000..32ebd5fa
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md4/md4_one.c
@@ -0,0 +1,96 @@
+/* crypto/md4/md4_one.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 <stdio.h>
+#include <string.h>
+#include <openssl/md4.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md)
+{
+ MD4_CTX c;
+ static unsigned char m[MD4_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ if (!MD4_Init(&c))
+ return NULL;
+#ifndef CHARSET_EBCDIC
+ MD4_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);
+ MD4_Update(&c, temp, chunk);
+ n -= chunk;
+ d += chunk;
+ }
+ }
+#endif
+ MD4_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+ return (md);
+}
diff --git a/Cryptlib/OpenSSL/crypto/md5/md5_dgst.c b/Cryptlib/OpenSSL/crypto/md5/md5_dgst.c
new file mode 100644
index 00000000..2b519467
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md5/md5_dgst.c
@@ -0,0 +1,216 @@
+/* crypto/md5/md5_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 <stdio.h>
+#include "md5_locl.h"
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+
+const char MD5_version[] = "MD5" OPENSSL_VERSION_PTEXT;
+
+/*
+ * Implemented from RFC1321 The MD5 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+fips_md_init(MD5)
+{
+ 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;
+ return 1;
+}
+
+#ifndef md5_block_data_order
+# ifdef X
+# undef X
+# endif
+void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num)
+{
+ const unsigned char *data = data_;
+ register unsigned MD32_REG_T A, B, C, D, l;
+# ifndef MD32_XARRAY
+ /* See comment in crypto/sha/sha_locl.h for details. */
+ unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+ XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+# define X(i) XX##i
+# else
+ MD5_LONG XX[MD5_LBLOCK];
+# define X(i) XX[i]
+# endif
+
+ A = c->A;
+ B = c->B;
+ C = c->C;
+ D = c->D;
+
+ for (; num--;) {
+ HOST_c2l(data, l);
+ X(0) = l;
+ HOST_c2l(data, l);
+ X(1) = l;
+ /* Round 0 */
+ R0(A, B, C, D, X(0), 7, 0xd76aa478L);
+ HOST_c2l(data, l);
+ X(2) = l;
+ R0(D, A, B, C, X(1), 12, 0xe8c7b756L);
+ HOST_c2l(data, l);
+ X(3) = l;
+ R0(C, D, A, B, X(2), 17, 0x242070dbL);
+ HOST_c2l(data, l);
+ X(4) = l;
+ R0(B, C, D, A, X(3), 22, 0xc1bdceeeL);
+ HOST_c2l(data, l);
+ X(5) = l;
+ R0(A, B, C, D, X(4), 7, 0xf57c0fafL);
+ HOST_c2l(data, l);
+ X(6) = l;
+ R0(D, A, B, C, X(5), 12, 0x4787c62aL);
+ HOST_c2l(data, l);
+ X(7) = l;
+ R0(C, D, A, B, X(6), 17, 0xa8304613L);
+ HOST_c2l(data, l);
+ X(8) = l;
+ R0(B, C, D, A, X(7), 22, 0xfd469501L);
+ HOST_c2l(data, l);
+ X(9) = l;
+ R0(A, B, C, D, X(8), 7, 0x698098d8L);
+ HOST_c2l(data, l);
+ X(10) = l;
+ R0(D, A, B, C, X(9), 12, 0x8b44f7afL);
+ HOST_c2l(data, l);
+ X(11) = l;
+ R0(C, D, A, B, X(10), 17, 0xffff5bb1L);
+ HOST_c2l(data, l);
+ X(12) = l;
+ R0(B, C, D, A, X(11), 22, 0x895cd7beL);
+ HOST_c2l(data, l);
+ X(13) = l;
+ R0(A, B, C, D, X(12), 7, 0x6b901122L);
+ HOST_c2l(data, l);
+ X(14) = l;
+ R0(D, A, B, C, X(13), 12, 0xfd987193L);
+ HOST_c2l(data, l);
+ X(15) = l;
+ R0(C, D, A, B, X(14), 17, 0xa679438eL);
+ R0(B, C, D, A, X(15), 22, 0x49b40821L);
+ /* Round 1 */
+ R1(A, B, C, D, X(1), 5, 0xf61e2562L);
+ R1(D, A, B, C, X(6), 9, 0xc040b340L);
+ R1(C, D, A, B, X(11), 14, 0x265e5a51L);
+ R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL);
+ R1(A, B, C, D, X(5), 5, 0xd62f105dL);
+ R1(D, A, B, C, X(10), 9, 0x02441453L);
+ R1(C, D, A, B, X(15), 14, 0xd8a1e681L);
+ R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L);
+ R1(A, B, C, D, X(9), 5, 0x21e1cde6L);
+ R1(D, A, B, C, X(14), 9, 0xc33707d6L);
+ R1(C, D, A, B, X(3), 14, 0xf4d50d87L);
+ R1(B, C, D, A, X(8), 20, 0x455a14edL);
+ R1(A, B, C, D, X(13), 5, 0xa9e3e905L);
+ R1(D, A, B, C, X(2), 9, 0xfcefa3f8L);
+ R1(C, D, A, B, X(7), 14, 0x676f02d9L);
+ R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL);
+ /* Round 2 */
+ R2(A, B, C, D, X(5), 4, 0xfffa3942L);
+ R2(D, A, B, C, X(8), 11, 0x8771f681L);
+ R2(C, D, A, B, X(11), 16, 0x6d9d6122L);
+ R2(B, C, D, A, X(14), 23, 0xfde5380cL);
+ R2(A, B, C, D, X(1), 4, 0xa4beea44L);
+ R2(D, A, B, C, X(4), 11, 0x4bdecfa9L);
+ R2(C, D, A, B, X(7), 16, 0xf6bb4b60L);
+ R2(B, C, D, A, X(10), 23, 0xbebfbc70L);
+ R2(A, B, C, D, X(13), 4, 0x289b7ec6L);
+ R2(D, A, B, C, X(0), 11, 0xeaa127faL);
+ R2(C, D, A, B, X(3), 16, 0xd4ef3085L);
+ R2(B, C, D, A, X(6), 23, 0x04881d05L);
+ R2(A, B, C, D, X(9), 4, 0xd9d4d039L);
+ R2(D, A, B, C, X(12), 11, 0xe6db99e5L);
+ R2(C, D, A, B, X(15), 16, 0x1fa27cf8L);
+ R2(B, C, D, A, X(2), 23, 0xc4ac5665L);
+ /* Round 3 */
+ R3(A, B, C, D, X(0), 6, 0xf4292244L);
+ R3(D, A, B, C, X(7), 10, 0x432aff97L);
+ R3(C, D, A, B, X(14), 15, 0xab9423a7L);
+ R3(B, C, D, A, X(5), 21, 0xfc93a039L);
+ R3(A, B, C, D, X(12), 6, 0x655b59c3L);
+ R3(D, A, B, C, X(3), 10, 0x8f0ccc92L);
+ R3(C, D, A, B, X(10), 15, 0xffeff47dL);
+ R3(B, C, D, A, X(1), 21, 0x85845dd1L);
+ R3(A, B, C, D, X(8), 6, 0x6fa87e4fL);
+ R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L);
+ R3(C, D, A, B, X(6), 15, 0xa3014314L);
+ R3(B, C, D, A, X(13), 21, 0x4e0811a1L);
+ R3(A, B, C, D, X(4), 6, 0xf7537e82L);
+ R3(D, A, B, C, X(11), 10, 0xbd3af235L);
+ R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL);
+ R3(B, C, D, A, X(9), 21, 0xeb86d391L);
+
+ A = c->A += A;
+ B = c->B += B;
+ C = c->C += C;
+ D = c->D += D;
+ }
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/md5/md5_locl.h b/Cryptlib/OpenSSL/crypto/md5/md5_locl.h
new file mode 100644
index 00000000..82e69218
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md5/md5_locl.h
@@ -0,0 +1,133 @@
+/* crypto/md5/md5_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 <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#include <openssl/md5.h>
+
+#ifndef MD5_LONG_LOG2
+# define MD5_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+#ifdef MD5_ASM
+# 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
+# elif defined(__sparc) || defined(__sparc__)
+# define md5_block_data_order md5_block_asm_data_order
+# endif
+#endif
+
+void md5_block_data_order(MD5_CTX *c, const void *p, size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG MD5_LONG
+#define HASH_CTX MD5_CTX
+#define HASH_CBLOCK MD5_CBLOCK
+#define HASH_UPDATE MD5_Update
+#define HASH_TRANSFORM MD5_Transform
+#define HASH_FINAL MD5_Final
+#define HASH_MAKE_STRING(c,s) do { \
+ unsigned long ll; \
+ ll=(c)->A; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->B; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->C; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->D; (void)HOST_l2c(ll,(s)); \
+ } while (0)
+#define HASH_BLOCK_DATA_ORDER md5_block_data_order
+
+#include "md32_common.h"
+
+/*-
+#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
+#define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
+*/
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, the above can be simplified
+ * to the code below. Wei attributes these optimizations to Peter Gutmann's
+ * SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
+#define H(b,c,d) ((b) ^ (c) ^ (d))
+#define I(b,c,d) (((~(d)) | (b)) ^ (c))
+
+#define R0(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+F((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };\
+
+#define R1(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+G((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };
+
+#define R2(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+H((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };
+
+#define R3(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+I((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };
diff --git a/Cryptlib/OpenSSL/crypto/md5/md5_one.c b/Cryptlib/OpenSSL/crypto/md5/md5_one.c
new file mode 100644
index 00000000..4ac882e7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/md5/md5_one.c
@@ -0,0 +1,96 @@
+/* crypto/md5/md5_one.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 <stdio.h>
+#include <string.h>
+#include <openssl/md5.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
+{
+ MD5_CTX c;
+ static unsigned char m[MD5_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ if (!MD5_Init(&c))
+ return NULL;
+#ifndef CHARSET_EBCDIC
+ MD5_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);
+ MD5_Update(&c, temp, chunk);
+ n -= chunk;
+ d += chunk;
+ }
+ }
+#endif
+ MD5_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+ return (md);
+}
diff --git a/Cryptlib/OpenSSL/crypto/mem.c b/Cryptlib/OpenSSL/crypto/mem.c
new file mode 100644
index 00000000..fdad49b7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/mem.c
@@ -0,0 +1,466 @@
+/* crypto/mem.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 <stdio.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+
+static int allow_customize = 1; /* we provide flexible functions for */
+static int allow_customize_debug = 1; /* exchanging memory-related functions
+ * at run-time, but this must be done
+ * before any blocks are actually
+ * allocated; or we'll run into huge
+ * problems when malloc/free pairs
+ * don't match etc. */
+
+/*
+ * the following pointers may be changed as long as 'allow_customize' is set
+ */
+
+static void *(*malloc_func) (size_t) = malloc;
+static void *default_malloc_ex(size_t num, const char *file, int line)
+{
+ return malloc_func(num);
+}
+
+static void *(*malloc_ex_func) (size_t, const char *file, int line)
+ = default_malloc_ex;
+
+static void *(*realloc_func) (void *, size_t) = realloc;
+static void *default_realloc_ex(void *str, size_t num,
+ const char *file, int line)
+{
+ return realloc_func(str, num);
+}
+
+static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
+ = default_realloc_ex;
+
+static void (*free_func) (void *) = free;
+
+static void *(*malloc_locked_func) (size_t) = malloc;
+static void *default_malloc_locked_ex(size_t num, const char *file, int line)
+{
+ return malloc_locked_func(num);
+}
+
+static void *(*malloc_locked_ex_func) (size_t, const char *file, int line)
+ = default_malloc_locked_ex;
+
+static void (*free_locked_func) (void *) = free;
+
+/* may be changed as long as 'allow_customize_debug' is set */
+/* XXX use correct function pointer types */
+#ifdef CRYPTO_MDEBUG
+/* use default functions from mem_dbg.c */
+static void (*malloc_debug_func) (void *, int, const char *, int, int)
+ = CRYPTO_dbg_malloc;
+static void (*realloc_debug_func) (void *, void *, int, const char *, int,
+ int)
+ = CRYPTO_dbg_realloc;
+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;
+#else
+/*
+ * applications can use CRYPTO_malloc_debug_init() to select above case at
+ * run-time
+ */
+static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL;
+static void (*realloc_debug_func) (void *, void *, int, const char *, int,
+ int)
+ = NULL;
+static void (*free_debug_func) (void *, int) = NULL;
+static void (*set_debug_options_func) (long) = NULL;
+static long (*get_debug_options_func) (void) = NULL;
+#endif
+
+int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
+ void (*f) (void *))
+{
+ /* Dummy call just to ensure OPENSSL_init() gets linked in */
+ OPENSSL_init();
+ if (!allow_customize)
+ return 0;
+ if ((m == 0) || (r == 0) || (f == 0))
+ return 0;
+ malloc_func = m;
+ malloc_ex_func = default_malloc_ex;
+ realloc_func = r;
+ realloc_ex_func = default_realloc_ex;
+ free_func = f;
+ malloc_locked_func = m;
+ malloc_locked_ex_func = default_malloc_locked_ex;
+ free_locked_func = f;
+ return 1;
+}
+
+int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
+ void *(*r) (void *, size_t, const char *,
+ int), void (*f) (void *))
+{
+ if (!allow_customize)
+ return 0;
+ if ((m == 0) || (r == 0) || (f == 0))
+ return 0;
+ malloc_func = 0;
+ malloc_ex_func = m;
+ realloc_func = 0;
+ realloc_ex_func = r;
+ free_func = f;
+ malloc_locked_func = 0;
+ malloc_locked_ex_func = m;
+ free_locked_func = f;
+ return 1;
+}
+
+int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *))
+{
+ if (!allow_customize)
+ return 0;
+ if ((m == NULL) || (f == NULL))
+ return 0;
+ malloc_locked_func = m;
+ malloc_locked_ex_func = default_malloc_locked_ex;
+ free_locked_func = f;
+ return 1;
+}
+
+int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
+ void (*f) (void *))
+{
+ if (!allow_customize)
+ return 0;
+ if ((m == NULL) || (f == NULL))
+ return 0;
+ malloc_locked_func = 0;
+ malloc_locked_ex_func = m;
+ free_func = f;
+ return 1;
+}
+
+int CRYPTO_set_mem_debug_functions(void (*m)
+ (void *, int, const char *, int, int),
+ void (*r) (void *, void *, int,
+ const char *, int, int),
+ void (*f) (void *, int), void (*so) (long),
+ long (*go) (void))
+{
+ if (!allow_customize_debug)
+ return 0;
+ OPENSSL_init();
+ malloc_debug_func = m;
+ realloc_debug_func = r;
+ free_debug_func = f;
+ set_debug_options_func = so;
+ get_debug_options_func = go;
+ return 1;
+}
+
+void CRYPTO_get_mem_functions(void *(**m) (size_t),
+ void *(**r) (void *, size_t),
+ void (**f) (void *))
+{
+ if (m != NULL)
+ *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0;
+ if (r != NULL)
+ *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0;
+ if (f != NULL)
+ *f = free_func;
+}
+
+void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
+ void *(**r) (void *, size_t, const char *,
+ int), void (**f) (void *))
+{
+ if (m != NULL)
+ *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0;
+ if (r != NULL)
+ *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0;
+ if (f != NULL)
+ *f = free_func;
+}
+
+void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
+ void (**f) (void *))
+{
+ if (m != NULL)
+ *m = (malloc_locked_ex_func == default_malloc_locked_ex) ?
+ malloc_locked_func : 0;
+ if (f != NULL)
+ *f = free_locked_func;
+}
+
+void CRYPTO_get_locked_mem_ex_functions(void
+ *(**m) (size_t, const char *, int),
+ void (**f) (void *))
+{
+ if (m != NULL)
+ *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
+ malloc_locked_ex_func : 0;
+ if (f != NULL)
+ *f = free_locked_func;
+}
+
+void CRYPTO_get_mem_debug_functions(void (**m)
+ (void *, int, const char *, int, int),
+ void (**r) (void *, void *, int,
+ const char *, int, int),
+ void (**f) (void *, int),
+ void (**so) (long), long (**go) (void))
+{
+ if (m != NULL)
+ *m = malloc_debug_func;
+ if (r != NULL)
+ *r = realloc_debug_func;
+ if (f != NULL)
+ *f = free_debug_func;
+ if (so != NULL)
+ *so = set_debug_options_func;
+ if (go != NULL)
+ *go = get_debug_options_func;
+}
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line)
+{
+ void *ret = NULL;
+
+ if (num <= 0)
+ return NULL;
+
+ if (allow_customize)
+ allow_customize = 0;
+ if (malloc_debug_func != NULL) {
+ if (allow_customize_debug)
+ allow_customize_debug = 0;
+ malloc_debug_func(NULL, num, file, line, 0);
+ }
+ ret = malloc_locked_ex_func(num, file, line);
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
+#endif
+ 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;
+}
+
+void CRYPTO_free_locked(void *str)
+{
+ if (free_debug_func != NULL)
+ free_debug_func(str, 0);
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
+#endif
+ free_locked_func(str);
+ if (free_debug_func != NULL)
+ free_debug_func(NULL, 1);
+}
+
+void *CRYPTO_malloc(int num, const char *file, int line)
+{
+ void *ret = NULL;
+
+ if (num <= 0)
+ return NULL;
+
+ if (allow_customize)
+ allow_customize = 0;
+ if (malloc_debug_func != NULL) {
+ if (allow_customize_debug)
+ allow_customize_debug = 0;
+ malloc_debug_func(NULL, num, file, line, 0);
+ }
+ ret = malloc_ex_func(num, file, line);
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
+#endif
+ 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);
+
+ if (ret == NULL)
+ return NULL;
+
+ strcpy(ret, str);
+ return ret;
+}
+
+void *CRYPTO_realloc(void *str, int num, const char *file, int line)
+{
+ void *ret = NULL;
+
+ if (str == NULL)
+ return CRYPTO_malloc(num, file, line);
+
+ if (num <= 0)
+ return NULL;
+
+ if (realloc_debug_func != NULL)
+ realloc_debug_func(str, NULL, num, file, line, 0);
+ ret = realloc_ex_func(str, num, file, line);
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str,
+ ret, num);
+#endif
+ if (realloc_debug_func != NULL)
+ realloc_debug_func(str, ret, num, file, line, 1);
+
+ return ret;
+}
+
+void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
+ int line)
+{
+ void *ret = NULL;
+
+ if (str == NULL)
+ return CRYPTO_malloc(num, file, line);
+
+ if (num <= 0)
+ return NULL;
+
+ /*
+ * We don't support shrinking the buffer. Note the memcpy that copies
+ * |old_len| bytes to the new buffer, below.
+ */
+ if (num < old_len)
+ return NULL;
+
+ if (realloc_debug_func != NULL)
+ realloc_debug_func(str, NULL, num, file, line, 0);
+ ret = malloc_ex_func(num, file, line);
+ if (ret) {
+ memcpy(ret, str, old_len);
+ OPENSSL_cleanse(str, old_len);
+ free_func(str);
+ }
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr,
+ "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n",
+ str, ret, num);
+#endif
+ if (realloc_debug_func != NULL)
+ realloc_debug_func(str, ret, num, file, line, 1);
+
+ return ret;
+}
+
+void CRYPTO_free(void *str)
+{
+ if (free_debug_func != NULL)
+ free_debug_func(str, 0);
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
+#endif
+ free_func(str);
+ if (free_debug_func != NULL)
+ free_debug_func(NULL, 1);
+}
+
+void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
+{
+ if (a != NULL)
+ OPENSSL_free(a);
+ a = (char *)OPENSSL_malloc(num);
+ return (a);
+}
+
+void CRYPTO_set_mem_debug_options(long bits)
+{
+ if (set_debug_options_func != NULL)
+ set_debug_options_func(bits);
+}
+
+long CRYPTO_get_mem_debug_options(void)
+{
+ if (get_debug_options_func != NULL)
+ return get_debug_options_func();
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/mem_clr.c b/Cryptlib/OpenSSL/crypto/mem_clr.c
new file mode 100644
index 00000000..ab85344e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/mem_clr.c
@@ -0,0 +1,81 @@
+/* crypto/mem_clr.c */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) 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
+ * 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 <string.h>
+#include <openssl/crypto.h>
+
+unsigned char cleanse_ctr = 0;
+
+void OPENSSL_cleanse(void *ptr, size_t len)
+{
+ unsigned char *p = ptr;
+ size_t loop = len, ctr = cleanse_ctr;
+
+ if (ptr == NULL)
+ return;
+
+ while (loop--) {
+ *(p++) = (unsigned char)ctr;
+ ctr += (17 + ((size_t)p & 0xF));
+ }
+ p = memchr(ptr, (unsigned char)ctr, len);
+ if (p)
+ ctr += (63 + (size_t)p);
+ cleanse_ctr = (unsigned char)ctr;
+}
diff --git a/Cryptlib/OpenSSL/crypto/mem_dbg.c b/Cryptlib/OpenSSL/crypto/mem_dbg.c
new file mode 100644
index 00000000..8525ded7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/mem_dbg.c
@@ -0,0 +1,830 @@
+/* crypto/mem_dbg.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-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 <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+
+static int mh_mode = CRYPTO_MEM_CHECK_OFF;
+/*
+ * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
+ * the application asks for it (usually after library initialisation for
+ * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
+ * temporarily when the library thinks that certain allocations should not be
+ * checked (e.g. the data structures used for memory checking). It is not
+ * suitable as an initial state: the library will unexpectedly enable memory
+ * checking when it executes one of those sections that want to disable
+ * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
+ * no sense whatsoever.
+ */
+
+static unsigned long order = 0; /* number of memory requests */
+
+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
+/*-
+ * For application-defined information (static C-string `info')
+ * to be displayed in memory leak list.
+ * Each thread has its own stack. For applications, there is
+ * CRYPTO_push_info("...") to push an entry,
+ * CRYPTO_pop_info() to pop an entry,
+ * CRYPTO_remove_all_info() to pop all entries.
+ */
+{
+ CRYPTO_THREADID threadid;
+ const char *file;
+ int line;
+ const char *info;
+ struct app_mem_info_st *next; /* tail of thread's stack */
+ int references;
+} APP_INFO;
+
+static void app_info_free(APP_INFO *);
+
+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 */
+{
+ void *addr;
+ int num;
+ const char *file;
+ int line;
+ CRYPTO_THREADID threadid;
+ unsigned long order;
+ time_t time;
+ APP_INFO *app_info;
+} MEM;
+
+static long options = /* extra information to be recorded */
+#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
+ V_CRYPTO_MDEBUG_TIME |
+#endif
+#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
+ V_CRYPTO_MDEBUG_THREAD |
+#endif
+ 0;
+
+static unsigned int num_disable = 0; /* num_disable > 0 iff mh_mode ==
+ * CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
+
+/*
+ * 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)
+{
+ if (--(inf->references) <= 0) {
+ if (inf->next != NULL) {
+ app_info_free(inf->next);
+ }
+ OPENSSL_free(inf);
+ }
+}
+
+int CRYPTO_mem_ctrl(int mode)
+{
+ int ret = mh_mode;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ switch (mode) {
+ /*
+ * for applications (not to be called while multiple threads use the
+ * library):
+ */
+ case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
+ mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
+ num_disable = 0;
+ break;
+ case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
+ mh_mode = 0;
+ num_disable = 0; /* should be true *before* MemCheck_stop is
+ * used, or there'll be a lot of confusion */
+ break;
+
+ /* switch off temporarily (for library-internal use): */
+ case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
+ if (mh_mode & CRYPTO_MEM_CHECK_ON) {
+ CRYPTO_THREADID cur;
+ CRYPTO_THREADID_current(&cur);
+ /* see if we don't have the MALLOC2 lock already */
+ if (!num_disable
+ || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) {
+ /*
+ * Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed
+ * while we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock
+ * if somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot
+ * release it because we block entry to this function). Give
+ * them a chance, first, and then claim the locks in
+ * appropriate order (long-time lock first).
+ */
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ /*
+ * Note that after we have waited for CRYPTO_LOCK_MALLOC2 and
+ * CRYPTO_LOCK_MALLOC, we'll still be in the right "case" and
+ * "if" branch because MemCheck_start and MemCheck_stop may
+ * never be used while there are multiple OpenSSL threads.
+ */
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
+ CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
+ }
+ num_disable++;
+ }
+ break;
+ case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
+ if (mh_mode & CRYPTO_MEM_CHECK_ON) {
+ if (num_disable) { /* always true, or something is going wrong */
+ num_disable--;
+ if (num_disable == 0) {
+ mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ return (ret);
+}
+
+int CRYPTO_is_mem_check_on(void)
+{
+ int ret = 0;
+
+ 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)
+ || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
+
+ CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
+ }
+ return (ret);
+}
+
+void CRYPTO_dbg_set_options(long bits)
+{
+ options = bits;
+}
+
+long CRYPTO_dbg_get_options(void)
+{
+ return options;
+}
+
+static int mem_cmp(const MEM *a, const MEM *b)
+{
+#ifdef _WIN64
+ 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 *)a->addr - (const char *)b->addr;
+#endif
+}
+
+static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
+
+static unsigned long mem_hash(const MEM *a)
+{
+ unsigned long ret;
+
+ 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 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(const APP_INFO *a)
+{
+ unsigned long ret;
+
+ 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)
+{
+ APP_INFO tmp;
+ APP_INFO *ret = NULL;
+
+ if (amih != 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++;
+ (void)lh_APP_INFO_insert(amih, next);
+ }
+#ifdef LEVITTE_DEBUG_MEM
+ 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",
+ CRYPTO_THREADID_hash(&ret->threadid),
+ CRYPTO_THREADID_hash(&tmp.threadid));
+ abort();
+ }
+#endif
+ if (--(ret->references) <= 0) {
+ ret->next = NULL;
+ if (next != NULL)
+ next->references--;
+ OPENSSL_free(ret);
+ }
+ }
+ }
+ return (ret);
+}
+
+int CRYPTO_push_info_(const char *info, const char *file, int line)
+{
+ APP_INFO *ami, *amim;
+ int ret = 0;
+
+ if (is_MemCheck_on()) {
+ MemCheck_off(); /* obtain MALLOC2 lock */
+
+ if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) {
+ ret = 0;
+ goto err;
+ }
+ if (amih == NULL) {
+ if ((amih = lh_APP_INFO_new()) == NULL) {
+ OPENSSL_free(ami);
+ ret = 0;
+ goto err;
+ }
+ }
+
+ CRYPTO_THREADID_current(&ami->threadid);
+ ami->file = file;
+ ami->line = line;
+ ami->info = info;
+ ami->references = 1;
+ ami->next = NULL;
+
+ if ((amim = lh_APP_INFO_insert(amih, ami)) != NULL) {
+#ifdef LEVITTE_DEBUG_MEM
+ 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",
+ CRYPTO_THREADID_hash(&amim->threadid),
+ CRYPTO_THREADID_hash(&ami->threadid));
+ abort();
+ }
+#endif
+ ami->next = amim;
+ }
+ err:
+ MemCheck_on(); /* release MALLOC2 lock */
+ }
+
+ return (ret);
+}
+
+int CRYPTO_pop_info(void)
+{
+ int ret = 0;
+
+ if (is_MemCheck_on()) { /* _must_ be true, or something went severely
+ * wrong */
+ MemCheck_off(); /* obtain MALLOC2 lock */
+
+ ret = (pop_info() != NULL);
+
+ MemCheck_on(); /* release MALLOC2 lock */
+ }
+ return (ret);
+}
+
+int CRYPTO_remove_all_info(void)
+{
+ int ret = 0;
+
+ if (is_MemCheck_on()) { /* _must_ be true */
+ MemCheck_off(); /* obtain MALLOC2 lock */
+
+ while (pop_info() != NULL)
+ ret++;
+
+ MemCheck_on(); /* release MALLOC2 lock */
+ }
+ return (ret);
+}
+
+static unsigned long break_order_num = 0;
+void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
+ int before_p)
+{
+ MEM *m, *mm;
+ APP_INFO tmp, *amim;
+
+ switch (before_p & 127) {
+ case 0:
+ break;
+ case 1:
+ if (addr == NULL)
+ break;
+
+ if (is_MemCheck_on()) {
+ MemCheck_off(); /* make sure we hold MALLOC2 lock */
+ if ((m = (MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) {
+ OPENSSL_free(addr);
+ MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
+ * to 0 */
+ return;
+ }
+ if (mh == NULL) {
+ if ((mh = lh_MEM_new()) == NULL) {
+ OPENSSL_free(addr);
+ OPENSSL_free(m);
+ addr = NULL;
+ goto err;
+ }
+ }
+
+ m->addr = addr;
+ m->file = file;
+ m->line = line;
+ m->num = num;
+ if (options & V_CRYPTO_MDEBUG_THREAD)
+ CRYPTO_THREADID_current(&m->threadid);
+ else
+ memset(&m->threadid, 0, sizeof(m->threadid));
+
+ if (order == break_order_num) {
+ /* BREAK HERE */
+ m->order = order;
+ }
+ m->order = order++;
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
+ m->order, (before_p & 128) ? '*' : '+', m->addr, m->num);
+#endif
+ if (options & V_CRYPTO_MDEBUG_TIME)
+ m->time = time(NULL);
+ else
+ m->time = 0;
+
+ CRYPTO_THREADID_current(&tmp.threadid);
+ m->app_info = NULL;
+ if (amih != NULL
+ && (amim = lh_APP_INFO_retrieve(amih, &tmp)) != NULL) {
+ m->app_info = amim;
+ amim->references++;
+ }
+
+ if ((mm = lh_MEM_insert(mh, m)) != NULL) {
+ /* Not good, but don't sweat it */
+ if (mm->app_info != NULL) {
+ mm->app_info->references--;
+ }
+ OPENSSL_free(mm);
+ }
+ err:
+ MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
+ * to 0 */
+ }
+ break;
+ }
+ return;
+}
+
+void CRYPTO_dbg_free(void *addr, int before_p)
+{
+ MEM m, *mp;
+
+ switch (before_p) {
+ case 0:
+ if (addr == NULL)
+ break;
+
+ if (is_MemCheck_on() && (mh != NULL)) {
+ MemCheck_off(); /* make sure we hold MALLOC2 lock */
+
+ m.addr = addr;
+ mp = lh_MEM_delete(mh, &m);
+ if (mp != NULL) {
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
+ mp->order, mp->addr, mp->num);
+#endif
+ if (mp->app_info != NULL)
+ app_info_free(mp->app_info);
+ OPENSSL_free(mp);
+ }
+
+ MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
+ * to 0 */
+ }
+ break;
+ case 1:
+ break;
+ }
+}
+
+void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
+ const char *file, int line, int before_p)
+{
+ MEM m, *mp;
+
+#ifdef LEVITTE_DEBUG_MEM
+ fprintf(stderr,
+ "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
+ addr1, addr2, num, file, line, before_p);
+#endif
+
+ switch (before_p) {
+ case 0:
+ break;
+ case 1:
+ if (addr2 == NULL)
+ break;
+
+ if (addr1 == NULL) {
+ CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
+ break;
+ }
+
+ if (is_MemCheck_on()) {
+ MemCheck_off(); /* make sure we hold MALLOC2 lock */
+
+ m.addr = addr1;
+ mp = lh_MEM_delete(mh, &m);
+ if (mp != NULL) {
+#ifdef LEVITTE_DEBUG_MEM
+ 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;
+ (void)lh_MEM_insert(mh, mp);
+ }
+
+ MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
+ * to 0 */
+ }
+ break;
+ }
+ return;
+}
+
+typedef struct mem_leak_st {
+ BIO *bio;
+ int chunks;
+ long bytes;
+} MEM_LEAK;
+
+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;
+ CRYPTO_THREADID ti;
+
+#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
+
+ if (m->addr == (char *)l->bio)
+ return;
+
+ if (options & V_CRYPTO_MDEBUG_TIME) {
+ lcl = localtime(&m->time);
+
+ BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
+ lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
+ bufp += strlen(bufp);
+ }
+
+ BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
+ m->order, m->file, m->line);
+ bufp += strlen(bufp);
+
+ if (options & V_CRYPTO_MDEBUG_THREAD) {
+ BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
+ CRYPTO_THREADID_hash(&m->threadid));
+ bufp += strlen(bufp);
+ }
+
+ BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
+ m->num, (unsigned long)m->addr);
+ bufp += strlen(bufp);
+
+ BIO_puts(l->bio, buf);
+
+ l->chunks++;
+ l->bytes += m->num;
+
+ amip = m->app_info;
+ ami_cnt = 0;
+ if (!amip)
+ return;
+ CRYPTO_THREADID_cpy(&ti, &amip->threadid);
+
+ do {
+ int buf_len;
+ int info_len;
+
+ ami_cnt++;
+ memset(buf, '>', ami_cnt);
+ BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
+ " thread=%lu, file=%s, line=%d, info=\"",
+ 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) {
+ memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
+ buf_len = 128 - 3;
+ } else {
+ BUF_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
+ buf_len = strlen(buf);
+ }
+ BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
+
+ BIO_puts(l->bio, buf);
+
+ amip = amip->next;
+ }
+ while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
+
+#ifdef LEVITTE_DEBUG_MEM
+ if (amip) {
+ fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
+ abort();
+ }
+#endif
+}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
+
+void CRYPTO_mem_leaks(BIO *b)
+{
+ MEM_LEAK ml;
+
+ if (mh == NULL && amih == NULL)
+ return;
+
+ MemCheck_off(); /* obtain MALLOC2 lock */
+
+ ml.bio = b;
+ ml.bytes = 0;
+ ml.chunks = 0;
+ if (mh != NULL)
+ 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 {
+ /*
+ * Make sure that, if we found no leaks, memory-leak debugging itself
+ * does not introduce memory leaks (which might irritate external
+ * debugging tools). (When someone enables leak checking, but does not
+ * call this function, we declare it to be their fault.) XXX This
+ * should be in CRYPTO_mem_leaks_cb, and CRYPTO_mem_leaks should be
+ * implemented by using CRYPTO_mem_leaks_cb. (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. Otherwise the code police will come
+ * and get us.)
+ */
+ int old_mh_mode;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+
+ /*
+ * avoid deadlock when lh_free() uses CRYPTO_dbg_free(), which uses
+ * CRYPTO_is_mem_check_on
+ */
+ old_mh_mode = mh_mode;
+ mh_mode = CRYPTO_MEM_CHECK_OFF;
+
+ if (mh != NULL) {
+ lh_MEM_free(mh);
+ mh = NULL;
+ }
+ if (amih != NULL) {
+ if (lh_APP_INFO_num_items(amih) == 0) {
+ lh_APP_INFO_free(amih);
+ amih = NULL;
+ }
+ }
+
+ mh_mode = old_mh_mode;
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ }
+ MemCheck_on(); /* release MALLOC2 lock */
+}
+
+#ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *fp)
+{
+ BIO *b;
+
+ if (mh == NULL)
+ return;
+ /*
+ * Need to turn off memory checking when allocated BIOs ... especially as
+ * we're creating them at a time when we're trying to check we've not
+ * left anything un-free()'d!!
+ */
+ MemCheck_off();
+ b = BIO_new(BIO_s_file());
+ MemCheck_on();
+ if (!b)
+ return;
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ CRYPTO_mem_leaks(b);
+ BIO_free(b);
+}
+#endif
+
+/*
+ * FIXME: We really don't allow much to the callback. For example, it has no
+ * chance of reaching the info stack for the item it processes. Should it
+ * really be this way? -- Richard Levitte
+ */
+/*
+ * 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
+ */
+
+/*
+ * 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);
+}
+
+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_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
+ &cb);
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/cbc128.c b/Cryptlib/OpenSSL/crypto/modes/cbc128.c
new file mode 100644
index 00000000..c13caea5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/cbc128.c
@@ -0,0 +1,207 @@
+/* ====================================================================
+ * 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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC)
+# 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 < len; ++n)
+ out[n] = in[n] ^ iv[n];
+ for (; n < 16; ++n)
+ out[n] = iv[n];
+ (*block) (out, out, key);
+ iv = out;
+ if (len <= 16)
+ break;
+ len -= 16;
+ in += 16;
+ out += 16;
+ }
+ memcpy(ivec, iv, 16);
+}
+
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block)
+{
+ size_t n;
+ union {
+ size_t t[16 / sizeof(size_t)];
+ unsigned char c[16];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (in != out) {
+ const unsigned char *iv = ivec;
+
+ if (STRICT_ALIGNMENT &&
+ ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ while (len >= 16) {
+ (*block) (in, out, key);
+ for (n = 0; n < 16; ++n)
+ out[n] ^= iv[n];
+ iv = in;
+ len -= 16;
+ in += 16;
+ out += 16;
+ }
+ } else if (16 % sizeof(size_t) == 0) { /* always true */
+ while (len >= 16) {
+ size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv;
+
+ (*block) (in, out, key);
+ for (n = 0; n < 16 / sizeof(size_t); n++)
+ out_t[n] ^= iv_t[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 if (16 % sizeof(size_t) == 0) { /* always true */
+ while (len >= 16) {
+ size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (in, tmp.c, key);
+ for (n = 0; n < 16 / sizeof(size_t); n++) {
+ c = in_t[n];
+ out_t[n] = tmp.t[n] ^ ivec_t[n];
+ ivec_t[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 < len; ++n) {
+ c = in[n];
+ out[n] = tmp.c[n] ^ ivec[n];
+ ivec[n] = c;
+ }
+ if (len <= 16) {
+ for (; n < 16; ++n)
+ ivec[n] = in[n];
+ break;
+ }
+ len -= 16;
+ in += 16;
+ out += 16;
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/ccm128.c b/Cryptlib/OpenSSL/crypto/modes/ccm128.c
new file mode 100644
index 00000000..c1ded0f9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/ccm128.c
@@ -0,0 +1,479 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/*
+ * First you setup M and L parameters and pass the key schedule. This is
+ * called once per session setup...
+ */
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+ unsigned int M, unsigned int L, void *key,
+ block128_f block)
+{
+ memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
+ ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
+ ctx->blocks = 0;
+ ctx->block = block;
+ ctx->key = key;
+}
+
+/* !!! Following interfaces are to be called *once* per packet !!! */
+
+/* Then you setup per-message nonce and pass the length of the message */
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
+ const unsigned char *nonce, size_t nlen, size_t mlen)
+{
+ unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
+
+ if (nlen < (14 - L))
+ return -1; /* nonce is too short */
+
+ if (sizeof(mlen) == 8 && L >= 3) {
+ ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
+ ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
+ ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
+ ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
+ } else
+ ctx->nonce.u[1] = 0;
+
+ ctx->nonce.c[12] = (u8)(mlen >> 24);
+ ctx->nonce.c[13] = (u8)(mlen >> 16);
+ ctx->nonce.c[14] = (u8)(mlen >> 8);
+ ctx->nonce.c[15] = (u8)mlen;
+
+ ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
+ memcpy(&ctx->nonce.c[1], nonce, 14 - L);
+
+ return 0;
+}
+
+/* Then you pass additional authentication data, this is optional */
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
+ const unsigned char *aad, size_t alen)
+{
+ unsigned int i;
+ block128_f block = ctx->block;
+
+ if (alen == 0)
+ return;
+
+ ctx->nonce.c[0] |= 0x40; /* set Adata flag */
+ (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
+
+ if (alen < (0x10000 - 0x100)) {
+ ctx->cmac.c[0] ^= (u8)(alen >> 8);
+ ctx->cmac.c[1] ^= (u8)alen;
+ i = 2;
+ } else if (sizeof(alen) == 8
+ && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
+ ctx->cmac.c[0] ^= 0xFF;
+ ctx->cmac.c[1] ^= 0xFF;
+ ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
+ ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
+ ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
+ ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
+ ctx->cmac.c[6] ^= (u8)(alen >> 24);
+ ctx->cmac.c[7] ^= (u8)(alen >> 16);
+ ctx->cmac.c[8] ^= (u8)(alen >> 8);
+ ctx->cmac.c[9] ^= (u8)alen;
+ i = 10;
+ } else {
+ ctx->cmac.c[0] ^= 0xFF;
+ ctx->cmac.c[1] ^= 0xFE;
+ ctx->cmac.c[2] ^= (u8)(alen >> 24);
+ ctx->cmac.c[3] ^= (u8)(alen >> 16);
+ ctx->cmac.c[4] ^= (u8)(alen >> 8);
+ ctx->cmac.c[5] ^= (u8)alen;
+ i = 6;
+ }
+
+ do {
+ for (; i < 16 && alen; ++i, ++aad, --alen)
+ ctx->cmac.c[i] ^= *aad;
+ (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
+ i = 0;
+ } while (alen);
+}
+
+/* Finally you encrypt or decrypt the message */
+
+/*
+ * counter part of nonce may not be larger than L*8 bits, L is not larger
+ * than 8, therefore 64-bit counter...
+ */
+static void ctr64_inc(unsigned char *counter)
+{
+ unsigned int n = 8;
+ u8 c;
+
+ counter += 8;
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c)
+ return;
+ } while (n);
+}
+
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len)
+{
+ size_t n;
+ unsigned int i, L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+ union {
+ u64 u[2];
+ u8 c[16];
+ } scratch;
+
+ if (!(flags0 & 0x40))
+ (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
+
+ ctx->nonce.c[0] = L = flags0 & 7;
+ for (n = 0, i = 15 - L; i < 15; ++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i] = 0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15] = 1;
+
+ if (n != len)
+ return -1; /* length mismatch */
+
+ ctx->blocks += ((len + 15) >> 3) | 1;
+ if (ctx->blocks > (U64(1) << 61))
+ return -2; /* too much data */
+
+ while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+ union {
+ u64 u[2];
+ u8 c[16];
+ } temp;
+
+ memcpy(temp.c, inp, 16);
+ ctx->cmac.u[0] ^= temp.u[0];
+ ctx->cmac.u[1] ^= temp.u[1];
+#else
+ ctx->cmac.u[0] ^= ((u64 *)inp)[0];
+ ctx->cmac.u[1] ^= ((u64 *)inp)[1];
+#endif
+ (*block) (ctx->cmac.c, ctx->cmac.c, key);
+ (*block) (ctx->nonce.c, scratch.c, key);
+ ctr64_inc(ctx->nonce.c);
+#if defined(STRICT_ALIGNMENT)
+ temp.u[0] ^= scratch.u[0];
+ temp.u[1] ^= scratch.u[1];
+ memcpy(out, temp.c, 16);
+#else
+ ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
+ ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
+#endif
+ inp += 16;
+ out += 16;
+ len -= 16;
+ }
+
+ if (len) {
+ for (i = 0; i < len; ++i)
+ ctx->cmac.c[i] ^= inp[i];
+ (*block) (ctx->cmac.c, ctx->cmac.c, key);
+ (*block) (ctx->nonce.c, scratch.c, key);
+ for (i = 0; i < len; ++i)
+ out[i] = scratch.c[i] ^ inp[i];
+ }
+
+ for (i = 15 - L; i < 16; ++i)
+ ctx->nonce.c[i] = 0;
+
+ (*block) (ctx->nonce.c, scratch.c, key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len)
+{
+ size_t n;
+ unsigned int i, L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+ union {
+ u64 u[2];
+ u8 c[16];
+ } scratch;
+
+ if (!(flags0 & 0x40))
+ (*block) (ctx->nonce.c, ctx->cmac.c, key);
+
+ ctx->nonce.c[0] = L = flags0 & 7;
+ for (n = 0, i = 15 - L; i < 15; ++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i] = 0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15] = 1;
+
+ if (n != len)
+ return -1;
+
+ while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+ union {
+ u64 u[2];
+ u8 c[16];
+ } temp;
+#endif
+ (*block) (ctx->nonce.c, scratch.c, key);
+ ctr64_inc(ctx->nonce.c);
+#if defined(STRICT_ALIGNMENT)
+ memcpy(temp.c, inp, 16);
+ ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
+ ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
+ memcpy(out, scratch.c, 16);
+#else
+ ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
+ ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
+#endif
+ (*block) (ctx->cmac.c, ctx->cmac.c, key);
+
+ inp += 16;
+ out += 16;
+ len -= 16;
+ }
+
+ if (len) {
+ (*block) (ctx->nonce.c, scratch.c, key);
+ for (i = 0; i < len; ++i)
+ ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
+ (*block) (ctx->cmac.c, ctx->cmac.c, key);
+ }
+
+ for (i = 15 - L; i < 16; ++i)
+ ctx->nonce.c[i] = 0;
+
+ (*block) (ctx->nonce.c, scratch.c, key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+static void ctr64_add(unsigned char *counter, size_t inc)
+{
+ size_t n = 8, val = 0;
+
+ counter += 8;
+ do {
+ --n;
+ val += counter[n] + (inc & 0xff);
+ counter[n] = (unsigned char)val;
+ val >>= 8; /* carry bit */
+ inc >>= 8;
+ } while (n && (inc || val));
+}
+
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len, ccm128_f stream)
+{
+ size_t n;
+ unsigned int i, L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+ union {
+ u64 u[2];
+ u8 c[16];
+ } scratch;
+
+ if (!(flags0 & 0x40))
+ (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
+
+ ctx->nonce.c[0] = L = flags0 & 7;
+ for (n = 0, i = 15 - L; i < 15; ++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i] = 0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15] = 1;
+
+ if (n != len)
+ return -1; /* length mismatch */
+
+ ctx->blocks += ((len + 15) >> 3) | 1;
+ if (ctx->blocks > (U64(1) << 61))
+ return -2; /* too much data */
+
+ if ((n = len / 16)) {
+ (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
+ n *= 16;
+ inp += n;
+ out += n;
+ len -= n;
+ if (len)
+ ctr64_add(ctx->nonce.c, n / 16);
+ }
+
+ if (len) {
+ for (i = 0; i < len; ++i)
+ ctx->cmac.c[i] ^= inp[i];
+ (*block) (ctx->cmac.c, ctx->cmac.c, key);
+ (*block) (ctx->nonce.c, scratch.c, key);
+ for (i = 0; i < len; ++i)
+ out[i] = scratch.c[i] ^ inp[i];
+ }
+
+ for (i = 15 - L; i < 16; ++i)
+ ctx->nonce.c[i] = 0;
+
+ (*block) (ctx->nonce.c, scratch.c, key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
+ const unsigned char *inp, unsigned char *out,
+ size_t len, ccm128_f stream)
+{
+ size_t n;
+ unsigned int i, L;
+ unsigned char flags0 = ctx->nonce.c[0];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+ union {
+ u64 u[2];
+ u8 c[16];
+ } scratch;
+
+ if (!(flags0 & 0x40))
+ (*block) (ctx->nonce.c, ctx->cmac.c, key);
+
+ ctx->nonce.c[0] = L = flags0 & 7;
+ for (n = 0, i = 15 - L; i < 15; ++i) {
+ n |= ctx->nonce.c[i];
+ ctx->nonce.c[i] = 0;
+ n <<= 8;
+ }
+ n |= ctx->nonce.c[15]; /* reconstructed length */
+ ctx->nonce.c[15] = 1;
+
+ if (n != len)
+ return -1;
+
+ if ((n = len / 16)) {
+ (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
+ n *= 16;
+ inp += n;
+ out += n;
+ len -= n;
+ if (len)
+ ctr64_add(ctx->nonce.c, n / 16);
+ }
+
+ if (len) {
+ (*block) (ctx->nonce.c, scratch.c, key);
+ for (i = 0; i < len; ++i)
+ ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
+ (*block) (ctx->cmac.c, ctx->cmac.c, key);
+ }
+
+ for (i = 15 - L; i < 16; ++i)
+ ctx->nonce.c[i] = 0;
+
+ (*block) (ctx->nonce.c, scratch.c, key);
+ ctx->cmac.u[0] ^= scratch.u[0];
+ ctx->cmac.u[1] ^= scratch.u[1];
+
+ ctx->nonce.c[0] = flags0;
+
+ return 0;
+}
+
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+ unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
+
+ M *= 2;
+ M += 2;
+ if (len < M)
+ return 0;
+ memcpy(tag, ctx->cmac.c, M);
+ return M;
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/cfb128.c b/Cryptlib/OpenSSL/crypto/modes/cfb128.c
new file mode 100644
index 00000000..d4ecbd08
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/cfb128.c
@@ -0,0 +1,254 @@
+/* ====================================================================
+ * 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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/*
+ * 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) { /* always true actually */
+ do {
+ 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 < len) {
+ if (n == 0) {
+ (*block) (ivec, ivec, key);
+ }
+ out[l] = ivec[n] ^= in[l];
+ ++l;
+ n = (n + 1) % 16;
+ }
+ *num = n;
+ } else {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (16 % sizeof(size_t) == 0) { /* always true actually */
+ do {
+ while (n && len) {
+ unsigned char c;
+ *(out++) = ivec[n] ^ (c = *(in++));
+ ivec[n] = c;
+ --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 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 (l < len) {
+ unsigned char c;
+ if (n == 0) {
+ (*block) (ivec, ivec, key);
+ }
+ out[l] = ivec[n] ^ (c = in[l]);
+ ivec[n] = c;
+ ++l;
+ n = (n + 1) % 16;
+ }
+ *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
+ */
+static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out,
+ int nbits, const void *key,
+ unsigned char ivec[16], int enc,
+ block128_f block)
+{
+ int n, rem, num;
+ unsigned char ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't
+ * use) one byte off the end */
+
+ if (nbits <= 0 || nbits > 128)
+ 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] << rem | ovec[n + num + 1] >> (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 < bits; ++n) {
+ c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+ cfbr_encrypt_block(c, d, 1, key, ivec, enc, block);
+ out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) |
+ ((d[0] & 0x80) >> (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 < length; ++n)
+ cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block);
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/ctr128.c b/Cryptlib/OpenSSL/crypto/modes/ctr128.c
new file mode 100644
index 00000000..bcafd6b6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/ctr128.c
@@ -0,0 +1,263 @@
+/* ====================================================================
+ * 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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/*
+ * NOTE: the IV/counter CTR mode is big-endian. The code itself is
+ * endian-neutral.
+ */
+
+/* increment counter (128-bit int) by 1 */
+static void ctr128_inc(unsigned char *counter)
+{
+ u32 n = 16, c = 1;
+
+ do {
+ --n;
+ c += counter[n];
+ counter[n] = (u8)c;
+ c >>= 8;
+ } while (n);
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+static void ctr128_inc_aligned(unsigned char *counter)
+{
+ size_t *data, c, d, n;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
+ ctr128_inc(counter);
+ return;
+ }
+
+ data = (size_t *)counter;
+ c = 1;
+ n = 16 / sizeof(size_t);
+ do {
+ --n;
+ d = data[n] += c;
+ /* did addition carry? */
+ c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1);
+ } 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 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 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 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;
+ size_t l = 0;
+
+ assert(in && out && key && ecount_buf && num);
+ assert(*num < 16);
+
+ n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (16 % sizeof(size_t) == 0) { /* always true actually */
+ do {
+ while (n && len) {
+ *(out++) = *(in++) ^ ecount_buf[n];
+ --len;
+ n = (n + 1) % 16;
+ }
+
+# if defined(STRICT_ALIGNMENT)
+ if (((size_t)in | (size_t)out | (size_t)ecount_buf)
+ % sizeof(size_t) != 0)
+ break;
+# endif
+ while (len >= 16) {
+ (*block) (ivec, ecount_buf, key);
+ ctr128_inc_aligned(ivec);
+ for (n = 0; 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 < len) {
+ if (n == 0) {
+ (*block) (ivec, ecount_buf, key);
+ ctr128_inc(ivec);
+ }
+ out[l] = in[l] ^ ecount_buf[n];
+ ++l;
+ n = (n + 1) % 16;
+ }
+
+ *num = n;
+}
+
+/* increment upper 96 bits of 128-bit counter by 1 */
+static void ctr96_inc(unsigned char *counter)
+{
+ u32 n = 12, c = 1;
+
+ do {
+ --n;
+ c += counter[n];
+ counter[n] = (u8)c;
+ c >>= 8;
+ } while (n);
+}
+
+void CRYPTO_ctr128_encrypt_ctr32(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, ctr128_f func)
+{
+ unsigned int n, ctr32;
+
+ assert(in && out && key && ecount_buf && num);
+ assert(*num < 16);
+
+ n = *num;
+
+ while (n && len) {
+ *(out++) = *(in++) ^ ecount_buf[n];
+ --len;
+ n = (n + 1) % 16;
+ }
+
+ ctr32 = GETU32(ivec + 12);
+ while (len >= 16) {
+ size_t blocks = len / 16;
+ /*
+ * 1<<28 is just a not-so-small yet not-so-large number...
+ * Below condition is practically never met, but it has to
+ * be checked for code correctness.
+ */
+ if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
+ blocks = (1U << 28);
+ /*
+ * As (*func) operates on 32-bit counter, caller
+ * has to handle overflow. 'if' below detects the
+ * overflow, which is then handled by limiting the
+ * amount of blocks to the exact overflow point...
+ */
+ ctr32 += (u32)blocks;
+ if (ctr32 < blocks) {
+ blocks -= ctr32;
+ ctr32 = 0;
+ }
+ (*func) (in, out, blocks, key, ivec);
+ /* (*ctr) does not update ivec, caller does: */
+ PUTU32(ivec + 12, ctr32);
+ /* ... overflow was detected, propogate carry. */
+ if (ctr32 == 0)
+ ctr96_inc(ivec);
+ blocks *= 16;
+ len -= blocks;
+ out += blocks;
+ in += blocks;
+ }
+ if (len) {
+ memset(ecount_buf, 0, 16);
+ (*func) (ecount_buf, ecount_buf, 1, key, ivec);
+ ++ctr32;
+ PUTU32(ivec + 12, ctr32);
+ if (ctr32 == 0)
+ ctr96_inc(ivec);
+ while (len--) {
+ out[n] = in[n] ^ ecount_buf[n];
+ ++n;
+ }
+ }
+
+ *num = n;
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/cts128.c b/Cryptlib/OpenSSL/crypto/modes/cts128.c
new file mode 100644
index 00000000..137be595
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/cts128.c
@@ -0,0 +1,544 @@
+/* ====================================================================
+ * 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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/*
+ * 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 provides
+ * two interfaces: one compliant with above mentioned RFCs and one
+ * compliant with the NIST proposal, both extending 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 < residue; ++n)
+ ivec[n] ^= in[n];
+ (*block) (ivec, ivec, key);
+ memcpy(out, out - 16, residue);
+ memcpy(out - 16, ivec, 16);
+
+ return len + residue;
+}
+
+size_t CRYPTO_nistcts128_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;
+
+ residue = len % 16;
+
+ len -= residue;
+
+ CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
+
+ if (residue == 0)
+ return len;
+
+ in += len;
+ out += len;
+
+ for (n = 0; n < residue; ++n)
+ ivec[n] ^= in[n];
+ (*block) (ivec, ivec, key);
+ memcpy(out - 16 + residue, ivec, 16);
+
+ return len + residue;
+}
+
+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 residue;
+ union {
+ size_t align;
+ unsigned char c[16];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+ if (len <= 16)
+ return 0;
+
+ if ((residue = len % 16) == 0)
+ residue = 16;
+
+ len -= residue;
+
+ (*cbc) (in, out, len, key, ivec, 1);
+
+ in += len;
+ out += len;
+
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+ memcpy(tmp.c, out - 16, 16);
+ (*cbc) (in, out - 16, residue, key, ivec, 1);
+ memcpy(out, tmp.c, residue);
+#else
+ memset(tmp.c, 0, sizeof(tmp));
+ memcpy(tmp.c, in, residue);
+ memcpy(out, out - 16, residue);
+ (*cbc) (tmp.c, out - 16, 16, key, ivec, 1);
+#endif
+ return len + residue;
+}
+
+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc)
+{
+ size_t residue;
+ union {
+ size_t align;
+ unsigned char c[16];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+ if (len < 16)
+ return 0;
+
+ residue = len % 16;
+
+ len -= residue;
+
+ (*cbc) (in, out, len, key, ivec, 1);
+
+ if (residue == 0)
+ return len;
+
+ in += len;
+ out += len;
+
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+ (*cbc) (in, out - 16 + residue, residue, key, ivec, 1);
+#else
+ memset(tmp.c, 0, sizeof(tmp));
+ memcpy(tmp.c, in, residue);
+ (*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1);
+#endif
+ return len + residue;
+}
+
+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 residue, n;
+ union {
+ size_t align;
+ unsigned char c[32];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+ if (len <= 16)
+ return 0;
+
+ if ((residue = len % 16) == 0)
+ residue = 16;
+
+ len -= 16 + residue;
+
+ if (len) {
+ CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
+ in += len;
+ out += len;
+ }
+
+ (*block) (in, tmp.c + 16, key);
+
+ memcpy(tmp.c, tmp.c + 16, 16);
+ memcpy(tmp.c, in + 16, residue);
+ (*block) (tmp.c, tmp.c, key);
+
+ for (n = 0; n < 16; ++n) {
+ unsigned char c = in[n];
+ out[n] = tmp.c[n] ^ ivec[n];
+ ivec[n] = c;
+ }
+ for (residue += 16; n < residue; ++n)
+ out[n] = tmp.c[n] ^ in[n];
+
+ return 16 + len + residue;
+}
+
+size_t CRYPTO_nistcts128_decrypt_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;
+ union {
+ size_t align;
+ unsigned char c[32];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+ if (len < 16)
+ return 0;
+
+ residue = len % 16;
+
+ if (residue == 0) {
+ CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
+ return len;
+ }
+
+ len -= 16 + residue;
+
+ if (len) {
+ CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
+ in += len;
+ out += len;
+ }
+
+ (*block) (in + residue, tmp.c + 16, key);
+
+ memcpy(tmp.c, tmp.c + 16, 16);
+ memcpy(tmp.c, in, residue);
+ (*block) (tmp.c, tmp.c, key);
+
+ for (n = 0; n < 16; ++n) {
+ unsigned char c = in[n];
+ out[n] = tmp.c[n] ^ ivec[n];
+ ivec[n] = in[n + residue];
+ tmp.c[n] = c;
+ }
+ for (residue += 16; n < residue; ++n)
+ out[n] = tmp.c[n] ^ tmp.c[n - 16];
+
+ return 16 + len + residue;
+}
+
+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)
+{
+ size_t residue;
+ union {
+ size_t align;
+ unsigned char c[32];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+ if (len <= 16)
+ return 0;
+
+ if ((residue = len % 16) == 0)
+ residue = 16;
+
+ len -= 16 + residue;
+
+ if (len) {
+ (*cbc) (in, out, len, key, ivec, 0);
+ in += len;
+ out += len;
+ }
+
+ memset(tmp.c, 0, sizeof(tmp));
+ /*
+ * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
+ */
+ (*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0);
+
+ memcpy(tmp.c, in + 16, residue);
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+ (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
+#else
+ (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
+ memcpy(out, tmp.c, 16 + residue);
+#endif
+ return 16 + len + residue;
+}
+
+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc)
+{
+ size_t residue;
+ union {
+ size_t align;
+ unsigned char c[32];
+ } tmp;
+
+ assert(in && out && key && ivec);
+
+ if (len < 16)
+ return 0;
+
+ residue = len % 16;
+
+ if (residue == 0) {
+ (*cbc) (in, out, len, key, ivec, 0);
+ return len;
+ }
+
+ len -= 16 + residue;
+
+ if (len) {
+ (*cbc) (in, out, len, key, ivec, 0);
+ in += len;
+ out += len;
+ }
+
+ memset(tmp.c, 0, sizeof(tmp));
+ /*
+ * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
+ */
+ (*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0);
+
+ memcpy(tmp.c, in, residue);
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+ (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
+#else
+ (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
+ memcpy(out, tmp.c, 16 + residue);
+#endif
+ return 16 + len + residue;
+}
+
+#if defined(SELFTEST)
+# include <stdio.h>
+# include <openssl/aes.h>
+
+/* 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 iv[sizeof(test_iv)];
+ unsigned char cleartext[64], 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);
+}
+
+void test_nistvector(const unsigned char *vector, size_t len)
+{
+ unsigned char iv[sizeof(test_iv)];
+ unsigned char cleartext[64], ciphertext[64], nistvector[64];
+ size_t tail;
+
+ printf("nistvector_%d\n", len);
+ fflush(stdout);
+
+ if ((tail = len % 16) == 0)
+ tail = 16;
+
+ len -= 16 + tail;
+ memcpy(nistvector, vector, len);
+ /* flip two last blocks */
+ memcpy(nistvector + len, vector + len + 16, tail);
+ memcpy(nistvector + len + tail, vector + len, 16);
+ len += 16 + tail;
+ tail = 16;
+
+ /* test block-based encryption */
+ memcpy(iv, test_iv, sizeof(test_iv));
+ CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
+ (block128_f) AES_encrypt);
+ if (memcmp(ciphertext, nistvector, len))
+ fprintf(stderr, "output_%d mismatch\n", len), exit(1);
+ if (memcmp(iv, nistvector + 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_nistcts128_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, nistvector + len - tail, sizeof(iv)))
+ fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
+
+ /* test streamed encryption */
+ memcpy(iv, test_iv, sizeof(test_iv));
+ CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv,
+ (cbc128_f) AES_cbc_encrypt);
+ if (memcmp(ciphertext, nistvector, len))
+ fprintf(stderr, "output_%d mismatch\n", len), exit(3);
+ if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
+ fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
+
+ /* test streamed decryption */
+ memcpy(iv, test_iv, sizeof(test_iv));
+ CRYPTO_nistcts128_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, nistvector + len - tail, sizeof(iv)))
+ fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
+}
+
+int 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));
+
+ test_nistvector(vector_17, sizeof(vector_17));
+ test_nistvector(vector_31, sizeof(vector_31));
+ test_nistvector(vector_32, sizeof(vector_32));
+ test_nistvector(vector_47, sizeof(vector_47));
+ test_nistvector(vector_48, sizeof(vector_48));
+ test_nistvector(vector_64, sizeof(vector_64));
+
+ return 0;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/modes/gcm128.c b/Cryptlib/OpenSSL/crypto/modes/gcm128.c
new file mode 100644
index 00000000..e299131c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/gcm128.c
@@ -0,0 +1,2371 @@
+/* ====================================================================
+ * Copyright (c) 2010 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.
+ * ====================================================================
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#if defined(BSWAP4) && defined(STRICT_ALIGNMENT)
+/* redefine, because alignment is ensured */
+# undef GETU32
+# define GETU32(p) BSWAP4(*(const u32 *)(p))
+# undef PUTU32
+# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v)
+#endif
+
+#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16))
+#define REDUCE1BIT(V) do { \
+ if (sizeof(size_t)==8) { \
+ u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
+ V.lo = (V.hi<<63)|(V.lo>>1); \
+ V.hi = (V.hi>>1 )^T; \
+ } \
+ else { \
+ u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
+ V.lo = (V.hi<<63)|(V.lo>>1); \
+ V.hi = (V.hi>>1 )^((u64)T<<32); \
+ } \
+} while(0)
+
+/*-
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8. 8 is effectively reserved for testing purposes.
+ * TABLE_BITS>1 are lookup-table-driven implementations referred to as
+ * "Shoup's" in GCM specification. In other words OpenSSL does not cover
+ * whole spectrum of possible table driven implementations. Why? In
+ * non-"Shoup's" case memory access pattern is segmented in such manner,
+ * that it's trivial to see that cache timing information can reveal
+ * fair portion of intermediate hash value. Given that ciphertext is
+ * always available to attacker, it's possible for him to attempt to
+ * deduce secret parameter H and if successful, tamper with messages
+ * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
+ * not as trivial, but there is no reason to believe that it's resistant
+ * to cache-timing attack. And the thing about "8-bit" implementation is
+ * that it consumes 16 (sixteen) times more memory, 4KB per individual
+ * key + 1KB shared. Well, on pros side it should be twice as fast as
+ * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
+ * was observed to run ~75% faster, closer to 100% for commercial
+ * compilers... Yet "4-bit" procedure is preferred, because it's
+ * believed to provide better security-performance balance and adequate
+ * all-round performance. "All-round" refers to things like:
+ *
+ * - shorter setup time effectively improves overall timing for
+ * handling short messages;
+ * - larger table allocation can become unbearable because of VM
+ * subsystem penalties (for example on Windows large enough free
+ * results in VM working set trimming, meaning that consequent
+ * malloc would immediately incur working set expansion);
+ * - larger table has larger cache footprint, which can affect
+ * performance of other code paths (not necessarily even from same
+ * thread in Hyper-Threading world);
+ *
+ * Value of 1 is not appropriate for performance reasons.
+ */
+#if TABLE_BITS==8
+
+static void gcm_init_8bit(u128 Htable[256], u64 H[2])
+{
+ int i, j;
+ u128 V;
+
+ Htable[0].hi = 0;
+ Htable[0].lo = 0;
+ V.hi = H[0];
+ V.lo = H[1];
+
+ for (Htable[128] = V, i = 64; i > 0; i >>= 1) {
+ REDUCE1BIT(V);
+ Htable[i] = V;
+ }
+
+ for (i = 2; i < 256; i <<= 1) {
+ u128 *Hi = Htable + i, H0 = *Hi;
+ for (j = 1; j < i; ++j) {
+ Hi[j].hi = H0.hi ^ Htable[j].hi;
+ Hi[j].lo = H0.lo ^ Htable[j].lo;
+ }
+ }
+}
+
+static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256])
+{
+ u128 Z = { 0, 0 };
+ const u8 *xi = (const u8 *)Xi + 15;
+ size_t rem, n = *xi;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ static const size_t rem_8bit[256] = {
+ PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
+ PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
+ PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
+ PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
+ PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
+ PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
+ PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
+ PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
+ PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
+ PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
+ PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
+ PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
+ PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
+ PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
+ PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
+ PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
+ PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
+ PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
+ PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
+ PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
+ PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
+ PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
+ PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
+ PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
+ PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
+ PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
+ PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
+ PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
+ PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
+ PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
+ PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
+ PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
+ PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
+ PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
+ PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
+ PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
+ PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
+ PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
+ PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
+ PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
+ PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
+ PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
+ PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
+ PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
+ PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
+ PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
+ PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
+ PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
+ PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
+ PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
+ PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
+ PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
+ PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
+ PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
+ PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
+ PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
+ PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
+ PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
+ PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
+ PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
+ PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
+ PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
+ PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
+ PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE)
+ };
+
+ while (1) {
+ Z.hi ^= Htable[n].hi;
+ Z.lo ^= Htable[n].lo;
+
+ if ((u8 *)Xi == xi)
+ break;
+
+ n = *(--xi);
+
+ rem = (size_t)Z.lo & 0xff;
+ Z.lo = (Z.hi << 56) | (Z.lo >> 8);
+ Z.hi = (Z.hi >> 8);
+ if (sizeof(size_t) == 8)
+ Z.hi ^= rem_8bit[rem];
+ else
+ Z.hi ^= (u64)rem_8bit[rem] << 32;
+ }
+
+ if (is_endian.little) {
+# ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+# else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi >> 32);
+ PUTU32(p, v);
+ v = (u32)(Z.hi);
+ PUTU32(p + 4, v);
+ v = (u32)(Z.lo >> 32);
+ PUTU32(p + 8, v);
+ v = (u32)(Z.lo);
+ PUTU32(p + 12, v);
+# endif
+ } else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+}
+
+# define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
+
+#elif TABLE_BITS==4
+
+static void gcm_init_4bit(u128 Htable[16], u64 H[2])
+{
+ u128 V;
+# if defined(OPENSSL_SMALL_FOOTPRINT)
+ int i;
+# endif
+
+ Htable[0].hi = 0;
+ Htable[0].lo = 0;
+ V.hi = H[0];
+ V.lo = H[1];
+
+# if defined(OPENSSL_SMALL_FOOTPRINT)
+ for (Htable[8] = V, i = 4; i > 0; i >>= 1) {
+ REDUCE1BIT(V);
+ Htable[i] = V;
+ }
+
+ for (i = 2; i < 16; i <<= 1) {
+ u128 *Hi = Htable + i;
+ int j;
+ for (V = *Hi, j = 1; j < i; ++j) {
+ Hi[j].hi = V.hi ^ Htable[j].hi;
+ Hi[j].lo = V.lo ^ Htable[j].lo;
+ }
+ }
+# else
+ Htable[8] = V;
+ REDUCE1BIT(V);
+ Htable[4] = V;
+ REDUCE1BIT(V);
+ Htable[2] = V;
+ REDUCE1BIT(V);
+ Htable[1] = V;
+ Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo;
+ V = Htable[4];
+ Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo;
+ Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo;
+ Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo;
+ V = Htable[8];
+ Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo;
+ Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo;
+ Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo;
+ Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo;
+ Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo;
+ Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo;
+ Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo;
+# endif
+# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
+ /*
+ * ARM assembler expects specific dword order in Htable.
+ */
+ {
+ int j;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ if (is_endian.little)
+ for (j = 0; j < 16; ++j) {
+ V = Htable[j];
+ Htable[j].hi = V.lo;
+ Htable[j].lo = V.hi;
+ } else
+ for (j = 0; j < 16; ++j) {
+ V = Htable[j];
+ Htable[j].hi = V.lo << 32 | V.lo >> 32;
+ Htable[j].lo = V.hi << 32 | V.hi >> 32;
+ }
+ }
+# endif
+}
+
+# ifndef GHASH_ASM
+static const size_t rem_4bit[16] = {
+ PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
+ PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
+ PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
+ PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0)
+};
+
+static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
+{
+ u128 Z;
+ int cnt = 15;
+ size_t rem, nlo, nhi;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ nlo = ((const u8 *)Xi)[15];
+ nhi = nlo >> 4;
+ nlo &= 0xf;
+
+ Z.hi = Htable[nlo].hi;
+ Z.lo = Htable[nlo].lo;
+
+ while (1) {
+ rem = (size_t)Z.lo & 0xf;
+ Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+ Z.hi = (Z.hi >> 4);
+ if (sizeof(size_t) == 8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+ Z.hi ^= Htable[nhi].hi;
+ Z.lo ^= Htable[nhi].lo;
+
+ if (--cnt < 0)
+ break;
+
+ nlo = ((const u8 *)Xi)[cnt];
+ nhi = nlo >> 4;
+ nlo &= 0xf;
+
+ rem = (size_t)Z.lo & 0xf;
+ Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+ Z.hi = (Z.hi >> 4);
+ if (sizeof(size_t) == 8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+ }
+
+ if (is_endian.little) {
+# ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+# else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi >> 32);
+ PUTU32(p, v);
+ v = (u32)(Z.hi);
+ PUTU32(p + 4, v);
+ v = (u32)(Z.lo >> 32);
+ PUTU32(p + 8, v);
+ v = (u32)(Z.lo);
+ PUTU32(p + 12, v);
+# endif
+ } else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+}
+
+# if !defined(OPENSSL_SMALL_FOOTPRINT)
+/*
+ * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
+ * details... Compiler-generated code doesn't seem to give any
+ * performance improvement, at least not on x86[_64]. It's here
+ * mostly as reference and a placeholder for possible future
+ * non-trivial optimization[s]...
+ */
+static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len)
+{
+ u128 Z;
+ int cnt;
+ size_t rem, nlo, nhi;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+# if 1
+ do {
+ cnt = 15;
+ nlo = ((const u8 *)Xi)[15];
+ nlo ^= inp[15];
+ nhi = nlo >> 4;
+ nlo &= 0xf;
+
+ Z.hi = Htable[nlo].hi;
+ Z.lo = Htable[nlo].lo;
+
+ while (1) {
+ rem = (size_t)Z.lo & 0xf;
+ Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+ Z.hi = (Z.hi >> 4);
+ if (sizeof(size_t) == 8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+ Z.hi ^= Htable[nhi].hi;
+ Z.lo ^= Htable[nhi].lo;
+
+ if (--cnt < 0)
+ break;
+
+ nlo = ((const u8 *)Xi)[cnt];
+ nlo ^= inp[cnt];
+ nhi = nlo >> 4;
+ nlo &= 0xf;
+
+ rem = (size_t)Z.lo & 0xf;
+ Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+ Z.hi = (Z.hi >> 4);
+ if (sizeof(size_t) == 8)
+ Z.hi ^= rem_4bit[rem];
+ else
+ Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+ }
+# else
+ /*
+ * Extra 256+16 bytes per-key plus 512 bytes shared tables
+ * [should] give ~50% improvement... One could have PACK()-ed
+ * the rem_8bit even here, but the priority is to minimize
+ * cache footprint...
+ */
+ u128 Hshr4[16]; /* Htable shifted right by 4 bits */
+ u8 Hshl4[16]; /* Htable shifted left by 4 bits */
+ static const unsigned short rem_8bit[256] = {
+ 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
+ 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
+ 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
+ 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
+ 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
+ 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
+ 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
+ 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
+ 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
+ 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
+ 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
+ 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
+ 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
+ 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
+ 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
+ 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
+ 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
+ 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
+ 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
+ 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
+ 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
+ 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
+ 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
+ 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
+ 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
+ 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
+ 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
+ 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
+ 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
+ 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
+ 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
+ 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE
+ };
+ /*
+ * This pre-processing phase slows down procedure by approximately
+ * same time as it makes each loop spin faster. In other words
+ * single block performance is approximately same as straightforward
+ * "4-bit" implementation, and then it goes only faster...
+ */
+ for (cnt = 0; cnt < 16; ++cnt) {
+ Z.hi = Htable[cnt].hi;
+ Z.lo = Htable[cnt].lo;
+ Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4);
+ Hshr4[cnt].hi = (Z.hi >> 4);
+ Hshl4[cnt] = (u8)(Z.lo << 4);
+ }
+
+ do {
+ for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) {
+ nlo = ((const u8 *)Xi)[cnt];
+ nlo ^= inp[cnt];
+ nhi = nlo >> 4;
+ nlo &= 0xf;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+
+ rem = (size_t)Z.lo & 0xff;
+
+ Z.lo = (Z.hi << 56) | (Z.lo >> 8);
+ Z.hi = (Z.hi >> 8);
+
+ Z.hi ^= Hshr4[nhi].hi;
+ Z.lo ^= Hshr4[nhi].lo;
+ Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48;
+ }
+
+ nlo = ((const u8 *)Xi)[0];
+ nlo ^= inp[0];
+ nhi = nlo >> 4;
+ nlo &= 0xf;
+
+ Z.hi ^= Htable[nlo].hi;
+ Z.lo ^= Htable[nlo].lo;
+
+ rem = (size_t)Z.lo & 0xf;
+
+ Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+ Z.hi = (Z.hi >> 4);
+
+ Z.hi ^= Htable[nhi].hi;
+ Z.lo ^= Htable[nhi].lo;
+ Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48;
+# endif
+
+ if (is_endian.little) {
+# ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+# else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi >> 32);
+ PUTU32(p, v);
+ v = (u32)(Z.hi);
+ PUTU32(p + 4, v);
+ v = (u32)(Z.lo >> 32);
+ PUTU32(p + 8, v);
+ v = (u32)(Z.lo);
+ PUTU32(p + 12, v);
+# endif
+ } else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+ } while (inp += 16, len -= 16);
+}
+# endif
+# else
+void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+# endif
+
+# define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
+# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
+# define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
+/*
+ * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing
+ * effect. In other words idea is to hash data while it's still in L1 cache
+ * after encryption pass...
+ */
+# define GHASH_CHUNK (3*1024)
+# endif
+
+#else /* TABLE_BITS */
+
+static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2])
+{
+ u128 V, Z = { 0, 0 };
+ long X;
+ int i, j;
+ const long *xi = (const long *)Xi;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ V.hi = H[0]; /* H is in host byte order, no byte swapping */
+ V.lo = H[1];
+
+ for (j = 0; j < 16 / sizeof(long); ++j) {
+ if (is_endian.little) {
+ if (sizeof(long) == 8) {
+# ifdef BSWAP8
+ X = (long)(BSWAP8(xi[j]));
+# else
+ const u8 *p = (const u8 *)(xi + j);
+ X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4));
+# endif
+ } else {
+ const u8 *p = (const u8 *)(xi + j);
+ X = (long)GETU32(p);
+ }
+ } else
+ X = xi[j];
+
+ for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) {
+ u64 M = (u64)(X >> (8 * sizeof(long) - 1));
+ Z.hi ^= V.hi & M;
+ Z.lo ^= V.lo & M;
+
+ REDUCE1BIT(V);
+ }
+ }
+
+ if (is_endian.little) {
+# ifdef BSWAP8
+ Xi[0] = BSWAP8(Z.hi);
+ Xi[1] = BSWAP8(Z.lo);
+# else
+ u8 *p = (u8 *)Xi;
+ u32 v;
+ v = (u32)(Z.hi >> 32);
+ PUTU32(p, v);
+ v = (u32)(Z.hi);
+ PUTU32(p + 4, v);
+ v = (u32)(Z.lo >> 32);
+ PUTU32(p + 8, v);
+ v = (u32)(Z.lo);
+ PUTU32(p + 12, v);
+# endif
+ } else {
+ Xi[0] = Z.hi;
+ Xi[1] = Z.lo;
+ }
+}
+
+# define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
+
+#endif
+
+#if TABLE_BITS==4 && (defined(GHASH_ASM) || defined(OPENSSL_CPUID_OBJ))
+# if !defined(I386_ONLY) && \
+ (defined(__i386) || defined(__i386__) || \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+# define GHASH_ASM_X86_OR_64
+# define GCM_FUNCREF_4BIT
+extern unsigned int OPENSSL_ia32cap_P[];
+
+void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+# define gcm_init_avx gcm_init_clmul
+# define gcm_gmult_avx gcm_gmult_clmul
+# define gcm_ghash_avx gcm_ghash_clmul
+# else
+void gcm_init_avx(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_avx(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+# endif
+
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+# define GHASH_ASM_X86
+void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+
+void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+# endif
+# elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
+# include "arm_arch.h"
+# if __ARM_MAX_ARCH__>=7
+# define GHASH_ASM_ARM
+# define GCM_FUNCREF_4BIT
+# define PMULL_CAPABLE (OPENSSL_armcap_P & ARMV8_PMULL)
+# if defined(__arm__) || defined(__arm)
+# define NEON_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
+# endif
+void gcm_init_neon(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+void gcm_init_v8(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_v8(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+# endif
+# elif defined(__sparc__) || defined(__sparc)
+# include "sparc_arch.h"
+# define GHASH_ASM_SPARC
+# define GCM_FUNCREF_4BIT
+extern unsigned int OPENSSL_sparcv9cap_P[];
+void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+# include "ppc_arch.h"
+# define GHASH_ASM_PPC
+# define GCM_FUNCREF_4BIT
+void gcm_init_p8(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_p8(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+# endif
+#endif
+
+#ifdef GCM_FUNCREF_4BIT
+# undef GCM_MUL
+# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
+# ifdef GHASH
+# undef GHASH
+# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
+# endif
+#endif
+
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->block = block;
+ ctx->key = key;
+
+ (*block) (ctx->H.c, ctx->H.c, key);
+
+ if (is_endian.little) {
+ /* H is stored in host byte order */
+#ifdef BSWAP8
+ ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
+ ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
+#else
+ u8 *p = ctx->H.c;
+ u64 hi, lo;
+ hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
+ lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
+ ctx->H.u[0] = hi;
+ ctx->H.u[1] = lo;
+#endif
+ }
+#if TABLE_BITS==8
+ gcm_init_8bit(ctx->Htable, ctx->H.u);
+#elif TABLE_BITS==4
+# if defined(GHASH_ASM_X86_OR_64)
+# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
+ if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */
+ OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */
+ if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */
+ gcm_init_avx(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_avx;
+ ctx->ghash = gcm_ghash_avx;
+ } else {
+ gcm_init_clmul(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_clmul;
+ ctx->ghash = gcm_ghash_clmul;
+ }
+ return;
+ }
+# endif
+ gcm_init_4bit(ctx->Htable, ctx->H.u);
+# if defined(GHASH_ASM_X86) /* x86 only */
+# if defined(OPENSSL_IA32_SSE2)
+ if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */
+# else
+ if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */
+# endif
+ ctx->gmult = gcm_gmult_4bit_mmx;
+ ctx->ghash = gcm_ghash_4bit_mmx;
+ } else {
+ ctx->gmult = gcm_gmult_4bit_x86;
+ ctx->ghash = gcm_ghash_4bit_x86;
+ }
+# else
+ ctx->gmult = gcm_gmult_4bit;
+ ctx->ghash = gcm_ghash_4bit;
+# endif
+# elif defined(GHASH_ASM_ARM)
+# ifdef PMULL_CAPABLE
+ if (PMULL_CAPABLE) {
+ gcm_init_v8(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_v8;
+ ctx->ghash = gcm_ghash_v8;
+ } else
+# endif
+# ifdef NEON_CAPABLE
+ if (NEON_CAPABLE) {
+ gcm_init_neon(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_neon;
+ ctx->ghash = gcm_ghash_neon;
+ } else
+# endif
+ {
+ gcm_init_4bit(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_4bit;
+# if defined(GHASH)
+ ctx->ghash = gcm_ghash_4bit;
+# else
+ ctx->ghash = NULL;
+# endif
+ }
+# elif defined(GHASH_ASM_SPARC)
+ if (OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) {
+ gcm_init_vis3(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_vis3;
+ ctx->ghash = gcm_ghash_vis3;
+ } else {
+ gcm_init_4bit(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_4bit;
+ ctx->ghash = gcm_ghash_4bit;
+ }
+# elif defined(GHASH_ASM_PPC)
+ if (OPENSSL_ppccap_P & PPC_CRYPTO207) {
+ gcm_init_p8(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_p8;
+ ctx->ghash = gcm_ghash_p8;
+ } else {
+ gcm_init_4bit(ctx->Htable, ctx->H.u);
+ ctx->gmult = gcm_gmult_4bit;
+# if defined(GHASH)
+ ctx->ghash = gcm_ghash_4bit;
+# else
+ ctx->ghash = NULL;
+# endif
+ }
+# else
+ gcm_init_4bit(ctx->Htable, ctx->H.u);
+# endif
+#endif
+}
+
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
+ size_t len)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ unsigned int ctr;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+#endif
+
+ ctx->Yi.u[0] = 0;
+ ctx->Yi.u[1] = 0;
+ ctx->Xi.u[0] = 0;
+ ctx->Xi.u[1] = 0;
+ ctx->len.u[0] = 0; /* AAD length */
+ ctx->len.u[1] = 0; /* message length */
+ ctx->ares = 0;
+ ctx->mres = 0;
+
+ if (len == 12) {
+ memcpy(ctx->Yi.c, iv, 12);
+ ctx->Yi.c[15] = 1;
+ ctr = 1;
+ } else {
+ size_t i;
+ u64 len0 = len;
+
+ while (len >= 16) {
+ for (i = 0; i < 16; ++i)
+ ctx->Yi.c[i] ^= iv[i];
+ GCM_MUL(ctx, Yi);
+ iv += 16;
+ len -= 16;
+ }
+ if (len) {
+ for (i = 0; i < len; ++i)
+ ctx->Yi.c[i] ^= iv[i];
+ GCM_MUL(ctx, Yi);
+ }
+ len0 <<= 3;
+ if (is_endian.little) {
+#ifdef BSWAP8
+ ctx->Yi.u[1] ^= BSWAP8(len0);
+#else
+ ctx->Yi.c[8] ^= (u8)(len0 >> 56);
+ ctx->Yi.c[9] ^= (u8)(len0 >> 48);
+ ctx->Yi.c[10] ^= (u8)(len0 >> 40);
+ ctx->Yi.c[11] ^= (u8)(len0 >> 32);
+ ctx->Yi.c[12] ^= (u8)(len0 >> 24);
+ ctx->Yi.c[13] ^= (u8)(len0 >> 16);
+ ctx->Yi.c[14] ^= (u8)(len0 >> 8);
+ ctx->Yi.c[15] ^= (u8)(len0);
+#endif
+ } else
+ ctx->Yi.u[1] ^= len0;
+
+ GCM_MUL(ctx, Yi);
+
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+ ctr = GETU32(ctx->Yi.c + 12);
+#endif
+ else
+ ctr = ctx->Yi.d[3];
+ }
+
+ (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key);
+ ++ctr;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+}
+
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
+ size_t len)
+{
+ size_t i;
+ unsigned int n;
+ u64 alen = ctx->len.u[0];
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+ if (ctx->len.u[1])
+ return -2;
+
+ alen += len;
+ if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len))
+ return -1;
+ ctx->len.u[0] = alen;
+
+ n = ctx->ares;
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(aad++);
+ --len;
+ n = (n + 1) % 16;
+ }
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ else {
+ ctx->ares = n;
+ return 0;
+ }
+ }
+#ifdef GHASH
+ if ((i = (len & (size_t)-16))) {
+ GHASH(ctx, aad, i);
+ aad += i;
+ len -= i;
+ }
+#else
+ while (len >= 16) {
+ for (i = 0; i < 16; ++i)
+ ctx->Xi.c[i] ^= aad[i];
+ GCM_MUL(ctx, Xi);
+ aad += 16;
+ len -= 16;
+ }
+#endif
+ if (len) {
+ n = (unsigned int)len;
+ for (i = 0; i < len; ++i)
+ ctx->Xi.c[i] ^= aad[i];
+ }
+
+ ctx->ares = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+#if 0
+ n = (unsigned int)mlen % 16; /* alternative to ctx->mres */
+#endif
+ mlen += len;
+ if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to encrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx, Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+ ctr = GETU32(ctx->Yi.c + 12);
+#endif
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (16 % sizeof(size_t) == 0) { /* always true actually */
+ do {
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
+ --len;
+ n = (n + 1) % 16;
+ }
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+# if defined(STRICT_ALIGNMENT)
+ if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
+ break;
+# endif
+# if defined(GHASH) && defined(GHASH_CHUNK)
+ while (len >= GHASH_CHUNK) {
+ size_t j = GHASH_CHUNK;
+
+ while (j) {
+ size_t *out_t = (size_t *)out;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i = 0; i < 16 / sizeof(size_t); ++i)
+ out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ out += 16;
+ in += 16;
+ j -= 16;
+ }
+ GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK);
+ len -= GHASH_CHUNK;
+ }
+ if ((i = (len & (size_t)-16))) {
+ size_t j = i;
+
+ while (len >= 16) {
+ size_t *out_t = (size_t *)out;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i = 0; i < 16 / sizeof(size_t); ++i)
+ out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+ GHASH(ctx, out - j, j);
+ }
+# else
+ while (len >= 16) {
+ size_t *out_t = (size_t *)out;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i = 0; i < 16 / sizeof(size_t); ++i)
+ ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ GCM_MUL(ctx, Xi);
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+# endif
+ if (len) {
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+ } while (0);
+ }
+#endif
+ for (i = 0; i < len; ++i) {
+ if (n == 0) {
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+ }
+ ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n];
+ n = (n + 1) % 16;
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ block128_f block = ctx->block;
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+ mlen += len;
+ if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to decrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx, Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+ ctr = GETU32(ctx->Yi.c + 12);
+#endif
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (16 % sizeof(size_t) == 0) { /* always true actually */
+ do {
+ if (n) {
+ while (n && len) {
+ u8 c = *(in++);
+ *(out++) = c ^ ctx->EKi.c[n];
+ ctx->Xi.c[n] ^= c;
+ --len;
+ n = (n + 1) % 16;
+ }
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+# if defined(STRICT_ALIGNMENT)
+ if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
+ break;
+# endif
+# if defined(GHASH) && defined(GHASH_CHUNK)
+ while (len >= GHASH_CHUNK) {
+ size_t j = GHASH_CHUNK;
+
+ GHASH(ctx, in, GHASH_CHUNK);
+ while (j) {
+ size_t *out_t = (size_t *)out;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i = 0; i < 16 / sizeof(size_t); ++i)
+ out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ out += 16;
+ in += 16;
+ j -= 16;
+ }
+ len -= GHASH_CHUNK;
+ }
+ if ((i = (len & (size_t)-16))) {
+ GHASH(ctx, in, i);
+ while (len >= 16) {
+ size_t *out_t = (size_t *)out;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i = 0; i < 16 / sizeof(size_t); ++i)
+ out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+ }
+# else
+ while (len >= 16) {
+ size_t *out_t = (size_t *)out;
+ const size_t *in_t = (const size_t *)in;
+
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ for (i = 0; i < 16 / sizeof(size_t); ++i) {
+ size_t c = in[i];
+ out[i] = c ^ ctx->EKi.t[i];
+ ctx->Xi.t[i] ^= c;
+ }
+ GCM_MUL(ctx, Xi);
+ out += 16;
+ in += 16;
+ len -= 16;
+ }
+# endif
+ if (len) {
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ u8 c = in[n];
+ ctx->Xi.c[n] ^= c;
+ out[n] = c ^ ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+ } while (0);
+ }
+#endif
+ for (i = 0; i < len; ++i) {
+ u8 c;
+ if (n == 0) {
+ (*block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+ }
+ c = in[i];
+ out[i] = c ^ ctx->EKi.c[n];
+ ctx->Xi.c[n] ^= c;
+ n = (n + 1) % 16;
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+ mlen += len;
+ if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to encrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx, Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+ ctr = GETU32(ctx->Yi.c + 12);
+#endif
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
+ --len;
+ n = (n + 1) % 16;
+ }
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+ while (len >= GHASH_CHUNK) {
+ (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
+ ctr += GHASH_CHUNK / 16;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ GHASH(ctx, out, GHASH_CHUNK);
+ out += GHASH_CHUNK;
+ in += GHASH_CHUNK;
+ len -= GHASH_CHUNK;
+ }
+#endif
+ if ((i = (len & (size_t)-16))) {
+ size_t j = i / 16;
+
+ (*stream) (in, out, j, key, ctx->Yi.c);
+ ctr += (unsigned int)j;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+ in += i;
+ len -= i;
+#if defined(GHASH)
+ GHASH(ctx, out, i);
+ out += i;
+#else
+ while (j--) {
+ for (i = 0; i < 16; ++i)
+ ctx->Xi.c[i] ^= out[i];
+ GCM_MUL(ctx, Xi);
+ out += 16;
+ }
+#endif
+ }
+ if (len) {
+ (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ unsigned int n, ctr;
+ size_t i;
+ u64 mlen = ctx->len.u[1];
+ void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+ void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+ mlen += len;
+ if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+ return -1;
+ ctx->len.u[1] = mlen;
+
+ if (ctx->ares) {
+ /* First call to decrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx, Xi);
+ ctx->ares = 0;
+ }
+
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+ ctr = GETU32(ctx->Yi.c + 12);
+#endif
+ else
+ ctr = ctx->Yi.d[3];
+
+ n = ctx->mres;
+ if (n) {
+ while (n && len) {
+ u8 c = *(in++);
+ *(out++) = c ^ ctx->EKi.c[n];
+ ctx->Xi.c[n] ^= c;
+ --len;
+ n = (n + 1) % 16;
+ }
+ if (n == 0)
+ GCM_MUL(ctx, Xi);
+ else {
+ ctx->mres = n;
+ return 0;
+ }
+ }
+#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+ while (len >= GHASH_CHUNK) {
+ GHASH(ctx, in, GHASH_CHUNK);
+ (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
+ ctr += GHASH_CHUNK / 16;
+ if (is_endian.little)
+# ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+ PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+ else
+ ctx->Yi.d[3] = ctr;
+ out += GHASH_CHUNK;
+ in += GHASH_CHUNK;
+ len -= GHASH_CHUNK;
+ }
+#endif
+ if ((i = (len & (size_t)-16))) {
+ size_t j = i / 16;
+
+#if defined(GHASH)
+ GHASH(ctx, in, i);
+#else
+ while (j--) {
+ size_t k;
+ for (k = 0; k < 16; ++k)
+ ctx->Xi.c[k] ^= in[k];
+ GCM_MUL(ctx, Xi);
+ in += 16;
+ }
+ j = i / 16;
+ in -= i;
+#endif
+ (*stream) (in, out, j, key, ctx->Yi.c);
+ ctr += (unsigned int)j;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+ out += i;
+ in += i;
+ len -= i;
+ }
+ if (len) {
+ (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
+ ++ctr;
+ if (is_endian.little)
+#ifdef BSWAP4
+ ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+ PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+ else
+ ctx->Yi.d[3] = ctr;
+ while (len--) {
+ u8 c = in[n];
+ ctx->Xi.c[n] ^= c;
+ out[n] = c ^ ctx->EKi.c[n];
+ ++n;
+ }
+ }
+
+ ctx->mres = n;
+ return 0;
+}
+
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
+ size_t len)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ u64 alen = ctx->len.u[0] << 3;
+ u64 clen = ctx->len.u[1] << 3;
+#ifdef GCM_FUNCREF_4BIT
+ void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+#endif
+
+ if (ctx->mres || ctx->ares)
+ GCM_MUL(ctx, Xi);
+
+ if (is_endian.little) {
+#ifdef BSWAP8
+ alen = BSWAP8(alen);
+ clen = BSWAP8(clen);
+#else
+ u8 *p = ctx->len.c;
+
+ ctx->len.u[0] = alen;
+ ctx->len.u[1] = clen;
+
+ alen = (u64)GETU32(p) << 32 | GETU32(p + 4);
+ clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
+#endif
+ }
+
+ ctx->Xi.u[0] ^= alen;
+ ctx->Xi.u[1] ^= clen;
+ GCM_MUL(ctx, Xi);
+
+ ctx->Xi.u[0] ^= ctx->EK0.u[0];
+ ctx->Xi.u[1] ^= ctx->EK0.u[1];
+
+ if (tag && len <= sizeof(ctx->Xi))
+ return CRYPTO_memcmp(ctx->Xi.c, tag, len);
+ else
+ return -1;
+}
+
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+ CRYPTO_gcm128_finish(ctx, NULL, 0);
+ memcpy(tag, ctx->Xi.c,
+ len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c));
+}
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
+{
+ GCM128_CONTEXT *ret;
+
+ if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT))))
+ CRYPTO_gcm128_init(ret, key, block);
+
+ return ret;
+}
+
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
+{
+ if (ctx) {
+ OPENSSL_cleanse(ctx, sizeof(*ctx));
+ OPENSSL_free(ctx);
+ }
+}
+
+#if defined(SELFTEST)
+# include <stdio.h>
+# include <openssl/aes.h>
+
+/* Test Case 1 */
+static const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL;
+static const u8 T1[] = {
+ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
+ 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a
+};
+
+/* Test Case 2 */
+# define K2 K1
+# define A2 A1
+# define IV2 IV1
+static const u8 P2[16];
+static const u8 C2[] = {
+ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
+ 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78
+};
+
+static const u8 T2[] = {
+ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
+ 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf
+};
+
+/* Test Case 3 */
+# define A3 A2
+static const u8 K3[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
+};
+
+static const u8 P3[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
+};
+
+static const u8 IV3[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88
+};
+
+static const u8 C3[] = {
+ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
+};
+
+static const u8 T3[] = {
+ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+ 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4
+};
+
+/* Test Case 4 */
+# define K4 K3
+# define IV4 IV3
+static const u8 P4[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39
+};
+
+static const u8 A4[] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2
+};
+
+static const u8 C4[] = {
+ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91
+};
+
+static const u8 T4[] = {
+ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+ 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47
+};
+
+/* Test Case 5 */
+# define K5 K4
+# define P5 P4
+# define A5 A4
+static const u8 IV5[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad
+};
+
+static const u8 C5[] = {
+ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
+ 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
+ 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
+ 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
+ 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
+ 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
+ 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
+ 0xc2, 0x3f, 0x45, 0x98
+};
+
+static const u8 T5[] = {
+ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
+ 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb
+};
+
+/* Test Case 6 */
+# define K6 K5
+# define P6 P5
+# define A6 A5
+static const u8 IV6[] = {
+ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+ 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+ 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+ 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+ 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+ 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+ 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+ 0xa6, 0x37, 0xb3, 0x9b
+};
+
+static const u8 C6[] = {
+ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
+ 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
+ 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
+ 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
+ 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
+ 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
+ 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
+ 0x4c, 0x34, 0xae, 0xe5
+};
+
+static const u8 T6[] = {
+ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
+ 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50
+};
+
+/* Test Case 7 */
+static const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL;
+static const u8 T7[] = {
+ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
+ 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35
+};
+
+/* Test Case 8 */
+# define K8 K7
+# define IV8 IV7
+# define A8 A7
+static const u8 P8[16];
+static const u8 C8[] = {
+ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+ 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00
+};
+
+static const u8 T8[] = {
+ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+ 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb
+};
+
+/* Test Case 9 */
+# define A9 A8
+static const u8 K9[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c
+};
+
+static const u8 P9[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
+};
+
+static const u8 IV9[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88
+};
+
+static const u8 C9[] = {
+ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56
+};
+
+static const u8 T9[] = {
+ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+ 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14
+};
+
+/* Test Case 10 */
+# define K10 K9
+# define IV10 IV9
+static const u8 P10[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39
+};
+
+static const u8 A10[] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2
+};
+
+static const u8 C10[] = {
+ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10
+};
+
+static const u8 T10[] = {
+ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+ 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c
+};
+
+/* Test Case 11 */
+# define K11 K10
+# define P11 P10
+# define A11 A10
+static const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+
+static const u8 C11[] = {
+ 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
+ 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
+ 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
+ 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
+ 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
+ 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
+ 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
+ 0xa0, 0xf0, 0x62, 0xf7
+};
+
+static const u8 T11[] = {
+ 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
+ 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8
+};
+
+/* Test Case 12 */
+# define K12 K11
+# define P12 P11
+# define A12 A11
+static const u8 IV12[] = {
+ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+ 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+ 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+ 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+ 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+ 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+ 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+ 0xa6, 0x37, 0xb3, 0x9b
+};
+
+static const u8 C12[] = {
+ 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
+ 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
+ 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
+ 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
+ 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
+ 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
+ 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
+ 0xe9, 0xb7, 0x37, 0x3b
+};
+
+static const u8 T12[] = {
+ 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
+ 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9
+};
+
+/* Test Case 13 */
+static const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL;
+static const u8 T13[] = {
+ 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
+ 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b
+};
+
+/* Test Case 14 */
+# define K14 K13
+# define A14 A13
+static const u8 P14[16], IV14[12];
+static const u8 C14[] = {
+ 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
+ 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18
+};
+
+static const u8 T14[] = {
+ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
+ 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19
+};
+
+/* Test Case 15 */
+# define A15 A14
+static const u8 K15[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
+};
+
+static const u8 P15[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
+};
+
+static const u8 IV15[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88
+};
+
+static const u8 C15[] = {
+ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
+};
+
+static const u8 T15[] = {
+ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+ 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c
+};
+
+/* Test Case 16 */
+# define K16 K15
+# define IV16 IV15
+static const u8 P16[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39
+};
+
+static const u8 A16[] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2
+};
+
+static const u8 C16[] = {
+ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62
+};
+
+static const u8 T16[] = {
+ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
+ 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
+};
+
+/* Test Case 17 */
+# define K17 K16
+# define P17 P16
+# define A17 A16
+static const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+
+static const u8 C17[] = {
+ 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
+ 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
+ 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
+ 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
+ 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
+ 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
+ 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
+ 0xf4, 0x7c, 0x9b, 0x1f
+};
+
+static const u8 T17[] = {
+ 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
+ 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2
+};
+
+/* Test Case 18 */
+# define K18 K17
+# define P18 P17
+# define A18 A17
+static const u8 IV18[] = {
+ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+ 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+ 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+ 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+ 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+ 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+ 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+ 0xa6, 0x37, 0xb3, 0x9b
+};
+
+static const u8 C18[] = {
+ 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
+ 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
+ 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
+ 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
+ 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
+ 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
+ 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
+ 0x44, 0xae, 0x7e, 0x3f
+};
+
+static const u8 T18[] = {
+ 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
+ 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a
+};
+
+/* Test Case 19 */
+# define K19 K1
+# define P19 P1
+# define IV19 IV1
+# define C19 C1
+static const u8 A19[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
+ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
+};
+
+static const u8 T19[] = {
+ 0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d,
+ 0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92
+};
+
+/* Test Case 20 */
+# define K20 K1
+# define A20 A1
+/* this results in 0xff in counter LSB */
+static const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff };
+
+static const u8 P20[288];
+static const u8 C20[] = {
+ 0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a,
+ 0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14,
+ 0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce,
+ 0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f,
+ 0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70,
+ 0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18,
+ 0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf,
+ 0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49,
+ 0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab,
+ 0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c,
+ 0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c,
+ 0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29,
+ 0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1,
+ 0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76,
+ 0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2,
+ 0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce,
+ 0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f,
+ 0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86,
+ 0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb,
+ 0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18,
+ 0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65,
+ 0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42,
+ 0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b,
+ 0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06,
+ 0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24,
+ 0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c,
+ 0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4,
+ 0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64,
+ 0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03,
+ 0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6,
+ 0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90,
+ 0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74,
+ 0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67,
+ 0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46,
+ 0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78,
+ 0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c
+};
+
+static const u8 T20[] = {
+ 0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a,
+ 0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f
+};
+
+# define TEST_CASE(n) do { \
+ u8 out[sizeof(P##n)]; \
+ AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key); \
+ CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt); \
+ CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \
+ memset(out,0,sizeof(out)); \
+ if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \
+ if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out)); \
+ if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \
+ (C##n && memcmp(out,C##n,sizeof(out)))) \
+ ret++, printf ("encrypt test#%d failed.\n",n); \
+ CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \
+ memset(out,0,sizeof(out)); \
+ if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \
+ if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out)); \
+ if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \
+ (P##n && memcmp(out,P##n,sizeof(out)))) \
+ ret++, printf ("decrypt test#%d failed.\n",n); \
+ } while(0)
+
+int main()
+{
+ GCM128_CONTEXT ctx;
+ AES_KEY key;
+ int ret = 0;
+
+ TEST_CASE(1);
+ TEST_CASE(2);
+ TEST_CASE(3);
+ TEST_CASE(4);
+ TEST_CASE(5);
+ TEST_CASE(6);
+ TEST_CASE(7);
+ TEST_CASE(8);
+ TEST_CASE(9);
+ TEST_CASE(10);
+ TEST_CASE(11);
+ TEST_CASE(12);
+ TEST_CASE(13);
+ TEST_CASE(14);
+ TEST_CASE(15);
+ TEST_CASE(16);
+ TEST_CASE(17);
+ TEST_CASE(18);
+ TEST_CASE(19);
+ TEST_CASE(20);
+
+# ifdef OPENSSL_CPUID_OBJ
+ {
+ size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc();
+ union {
+ u64 u;
+ u8 c[1024];
+ } buf;
+ int i;
+
+ AES_set_encrypt_key(K1, sizeof(K1) * 8, &key);
+ CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt);
+ CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1));
+
+ CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
+ start = OPENSSL_rdtsc();
+ CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
+ gcm_t = OPENSSL_rdtsc() - start;
+
+ CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
+ &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
+ (block128_f) AES_encrypt);
+ start = OPENSSL_rdtsc();
+ CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
+ &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
+ (block128_f) AES_encrypt);
+ ctr_t = OPENSSL_rdtsc() - start;
+
+ printf("%.2f-%.2f=%.2f\n",
+ gcm_t / (double)sizeof(buf),
+ ctr_t / (double)sizeof(buf),
+ (gcm_t - ctr_t) / (double)sizeof(buf));
+# ifdef GHASH
+ {
+ void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+ const u8 *inp, size_t len) = ctx.ghash;
+
+ GHASH((&ctx), buf.c, sizeof(buf));
+ start = OPENSSL_rdtsc();
+ for (i = 0; i < 100; ++i)
+ GHASH((&ctx), buf.c, sizeof(buf));
+ gcm_t = OPENSSL_rdtsc() - start;
+ printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i);
+ }
+# endif
+ }
+# endif
+
+ return ret;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h b/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h
new file mode 100644
index 00000000..fe14ec70
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h
@@ -0,0 +1,143 @@
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use is governed by OpenSSL license.
+ * ====================================================================
+ */
+
+#include <openssl/modes.h>
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef __int64 i64;
+typedef unsigned __int64 u64;
+# define U64(C) C##UI64
+#elif defined(__arch64__)
+typedef long i64;
+typedef unsigned long u64;
+# define U64(C) C##UL
+#else
+typedef long long i64;
+typedef unsigned long long u64;
+# define U64(C) C##ULL
+#endif
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+#define STRICT_ALIGNMENT 1
+#ifndef PEDANTIC
+# if defined(__i386) || defined(__i386__) || \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__aarch64__) || \
+ defined(__s390__) || defined(__s390x__)
+# undef STRICT_ALIGNMENT
+# endif
+#endif
+
+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(__GNUC__) && __GNUC__>=2
+# if defined(__x86_64) || defined(__x86_64__)
+# define BSWAP8(x) ({ u64 ret_=(x); \
+ asm ("bswapq %0" \
+ : "+r"(ret_)); ret_; })
+# define BSWAP4(x) ({ u32 ret_=(x); \
+ asm ("bswapl %0" \
+ : "+r"(ret_)); ret_; })
+# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
+# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \
+ asm ("bswapl %0; bswapl %1" \
+ : "+r"(hi_),"+r"(lo_)); \
+ (u64)hi_<<32|lo_; })
+# define BSWAP4(x) ({ u32 ret_=(x); \
+ asm ("bswapl %0" \
+ : "+r"(ret_)); ret_; })
+# elif defined(__aarch64__)
+# define BSWAP8(x) ({ u64 ret_; \
+ asm ("rev %0,%1" \
+ : "=r"(ret_) : "r"(x)); ret_; })
+# define BSWAP4(x) ({ u32 ret_; \
+ asm ("rev %w0,%w1" \
+ : "=r"(ret_) : "r"(x)); ret_; })
+# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
+# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \
+ asm ("rev %0,%0; rev %1,%1" \
+ : "+r"(hi_),"+r"(lo_)); \
+ (u64)hi_<<32|lo_; })
+# define BSWAP4(x) ({ u32 ret_; \
+ asm ("rev %0,%1" \
+ : "=r"(ret_) : "r"((u32)(x))); \
+ ret_; })
+# endif
+# elif defined(_MSC_VER)
+# if _MSC_VER>=1300
+# pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
+# define BSWAP8(x) _byteswap_uint64((u64)(x))
+# define BSWAP4(x) _byteswap_ulong((u32)(x))
+# elif defined(_M_IX86)
+__inline u32 _bswap4(u32 val)
+{
+_asm mov eax, val _asm bswap eax}
+# define BSWAP4(x) _bswap4(x)
+# endif
+# endif
+#endif
+#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
+# define GETU32(p) BSWAP4(*(const u32 *)(p))
+# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v)
+#else
+# 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
+/*- GCM definitions */ typedef struct {
+ u64 hi, lo;
+} u128;
+
+#ifdef TABLE_BITS
+# undef TABLE_BITS
+#endif
+/*
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8 [or 1]. For further information see gcm128.c.
+ */
+#define TABLE_BITS 4
+
+struct gcm128_context {
+ /* Following 6 names follow names in GCM specification */
+ union {
+ u64 u[2];
+ u32 d[4];
+ u8 c[16];
+ size_t t[16 / sizeof(size_t)];
+ } Yi, EKi, EK0, len, Xi, H;
+ /*
+ * Relative position of Xi, H and pre-computed Htable is used in some
+ * assembler modules, i.e. don't change the order!
+ */
+#if TABLE_BITS==8
+ u128 Htable[256];
+#else
+ u128 Htable[16];
+ void (*gmult) (u64 Xi[2], const u128 Htable[16]);
+ void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp,
+ size_t len);
+#endif
+ unsigned int mres, ares;
+ block128_f block;
+ void *key;
+};
+
+struct xts128_context {
+ void *key1, *key2;
+ block128_f block1, block2;
+};
+
+struct ccm128_context {
+ union {
+ u64 u[2];
+ u8 c[16];
+ } nonce, cmac;
+ u64 blocks;
+ block128_f block;
+ void *key;
+};
diff --git a/Cryptlib/OpenSSL/crypto/modes/ofb128.c b/Cryptlib/OpenSSL/crypto/modes/ofb128.c
new file mode 100644
index 00000000..4dbaccd7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/ofb128.c
@@ -0,0 +1,124 @@
+/* ====================================================================
+ * 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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.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 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) { /* always true actually */
+ do {
+ 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
+ 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 (l < len) {
+ if (n == 0) {
+ (*block) (ivec, ivec, key);
+ }
+ out[l] = in[l] ^ ivec[n];
+ ++l;
+ n = (n + 1) % 16;
+ }
+
+ *num = n;
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/wrap128.c b/Cryptlib/OpenSSL/crypto/modes/wrap128.c
new file mode 100644
index 00000000..38497837
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/wrap128.c
@@ -0,0 +1,138 @@
+/* crypto/modes/wrap128.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2013 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 "cryptlib.h"
+#include <openssl/modes.h>
+
+static const unsigned char default_iv[] = {
+ 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
+};
+
+/*
+ * Input size limit: lower than maximum of standards but far larger than
+ * anything that will be used in practice.
+ */
+#define CRYPTO128_WRAP_MAX (1UL << 31)
+
+size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
+ unsigned char *out,
+ const unsigned char *in, size_t inlen,
+ block128_f block)
+{
+ unsigned char *A, B[16], *R;
+ size_t i, j, t;
+ if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX))
+ return 0;
+ A = B;
+ t = 1;
+ memmove(out + 8, in, inlen);
+ if (!iv)
+ iv = default_iv;
+
+ memcpy(A, iv, 8);
+
+ for (j = 0; j < 6; j++) {
+ R = out + 8;
+ for (i = 0; i < inlen; i += 8, t++, R += 8) {
+ memcpy(B + 8, R, 8);
+ block(B, B, key);
+ A[7] ^= (unsigned char)(t & 0xff);
+ if (t > 0xff) {
+ A[6] ^= (unsigned char)((t >> 8) & 0xff);
+ A[5] ^= (unsigned char)((t >> 16) & 0xff);
+ A[4] ^= (unsigned char)((t >> 24) & 0xff);
+ }
+ memcpy(R, B + 8, 8);
+ }
+ }
+ memcpy(out, A, 8);
+ return inlen + 8;
+}
+
+size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
+ unsigned char *out,
+ const unsigned char *in, size_t inlen,
+ block128_f block)
+{
+ unsigned char *A, B[16], *R;
+ size_t i, j, t;
+ inlen -= 8;
+ if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
+ return 0;
+ A = B;
+ t = 6 * (inlen >> 3);
+ memcpy(A, in, 8);
+ memmove(out, in + 8, inlen);
+ for (j = 0; j < 6; j++) {
+ R = out + inlen - 8;
+ for (i = 0; i < inlen; i += 8, t--, R -= 8) {
+ A[7] ^= (unsigned char)(t & 0xff);
+ if (t > 0xff) {
+ A[6] ^= (unsigned char)((t >> 8) & 0xff);
+ A[5] ^= (unsigned char)((t >> 16) & 0xff);
+ A[4] ^= (unsigned char)((t >> 24) & 0xff);
+ }
+ memcpy(B + 8, R, 8);
+ block(B, B, key);
+ memcpy(R, B + 8, 8);
+ }
+ }
+ if (!iv)
+ iv = default_iv;
+ if (memcmp(A, iv, 8)) {
+ OPENSSL_cleanse(out, inlen);
+ return 0;
+ }
+ return inlen;
+}
diff --git a/Cryptlib/OpenSSL/crypto/modes/xts128.c b/Cryptlib/OpenSSL/crypto/modes/xts128.c
new file mode 100644
index 00000000..8f2af588
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/modes/xts128.c
@@ -0,0 +1,204 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
+ const unsigned char iv[16],
+ const unsigned char *inp, unsigned char *out,
+ size_t len, int enc)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+ union {
+ u64 u[2];
+ u32 d[4];
+ u8 c[16];
+ } tweak, scratch;
+ unsigned int i;
+
+ if (len < 16)
+ return -1;
+
+ memcpy(tweak.c, iv, 16);
+
+ (*ctx->block2) (tweak.c, tweak.c, ctx->key2);
+
+ if (!enc && (len % 16))
+ len -= 16;
+
+ while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+ memcpy(scratch.c, inp, 16);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+#else
+ scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0];
+ scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1];
+#endif
+ (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out, scratch.c, 16);
+#else
+ ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0];
+ ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1];
+#endif
+ inp += 16;
+ out += 16;
+ len -= 16;
+
+ if (len == 0)
+ return 0;
+
+ if (is_endian.little) {
+ unsigned int carry, res;
+
+ res = 0x87 & (((int)tweak.d[3]) >> 31);
+ carry = (unsigned int)(tweak.u[0] >> 63);
+ tweak.u[0] = (tweak.u[0] << 1) ^ res;
+ tweak.u[1] = (tweak.u[1] << 1) | carry;
+ } else {
+ size_t c;
+
+ for (c = 0, i = 0; i < 16; ++i) {
+ /*
+ * + substitutes for |, because c is 1 bit
+ */
+ c += ((size_t)tweak.c[i]) << 1;
+ tweak.c[i] = (u8)c;
+ c = c >> 8;
+ }
+ tweak.c[0] ^= (u8)(0x87 & (0 - c));
+ }
+ }
+ if (enc) {
+ for (i = 0; i < len; ++i) {
+ u8 c = inp[i];
+ out[i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out - 16, scratch.c, 16);
+ } else {
+ union {
+ u64 u[2];
+ u8 c[16];
+ } tweak1;
+
+ if (is_endian.little) {
+ unsigned int carry, res;
+
+ res = 0x87 & (((int)tweak.d[3]) >> 31);
+ carry = (unsigned int)(tweak.u[0] >> 63);
+ tweak1.u[0] = (tweak.u[0] << 1) ^ res;
+ tweak1.u[1] = (tweak.u[1] << 1) | carry;
+ } else {
+ size_t c;
+
+ for (c = 0, i = 0; i < 16; ++i) {
+ /*
+ * + substitutes for |, because c is 1 bit
+ */
+ c += ((size_t)tweak.c[i]) << 1;
+ tweak1.c[i] = (u8)c;
+ c = c >> 8;
+ }
+ tweak1.c[0] ^= (u8)(0x87 & (0 - c));
+ }
+#if defined(STRICT_ALIGNMENT)
+ memcpy(scratch.c, inp, 16);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+#else
+ scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0];
+ scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1];
+#endif
+ (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+
+ for (i = 0; i < len; ++i) {
+ u8 c = inp[16 + i];
+ out[16 + i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out, scratch.c, 16);
+#else
+ ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0];
+ ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1];
+#endif
+ }
+
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/o_dir.c b/Cryptlib/OpenSSL/crypto/o_dir.c
new file mode 100644
index 00000000..f9dbed87
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_dir.c
@@ -0,0 +1,86 @@
+/* crypto/o_dir.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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 <errno.h>
+#include <e_os.h>
+
+/*
+ * The routines really come from the Levitte Programming, so to make life
+ * simple, let's just use the raw files and hack the symbols to fit our
+ * namespace.
+ */
+#define LP_DIR_CTX OPENSSL_DIR_CTX
+#define LP_dir_context_st OPENSSL_dir_context_st
+#define LP_find_file OPENSSL_DIR_read
+#define LP_find_file_end OPENSSL_DIR_end
+
+#include "o_dir.h"
+
+#define LPDIR_H
+#if defined OPENSSL_SYS_UNIX || defined DJGPP
+# include "LPdir_unix.c"
+#elif defined OPENSSL_SYS_VMS
+# include "LPdir_vms.c"
+#elif defined OPENSSL_SYS_WIN32
+# include "LPdir_win32.c"
+#elif defined OPENSSL_SYS_WINCE
+# include "LPdir_wince.c"
+#else
+# include "LPdir_nyi.c"
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/o_dir.h b/Cryptlib/OpenSSL/crypto/o_dir.h
new file mode 100644
index 00000000..bf45a14d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_dir.h
@@ -0,0 +1,55 @@
+/* crypto/o_dir.h */
+/*
+ * Copied from Richard Levitte's (richard@levitte.org) LP library. All
+ * symbol names have been changed, with permission from the author.
+ */
+
+/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 THE REGENTS 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 O_DIR_H
+# define O_DIR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
+
+ /*
+ * returns NULL on error or end-of-directory. If it is end-of-directory,
+ * errno will be zero
+ */
+const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory);
+ /* returns 1 on success, 0 on error */
+int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPDIR_H */
diff --git a/Cryptlib/OpenSSL/crypto/o_fips.c b/Cryptlib/OpenSSL/crypto/o_fips.c
new file mode 100644
index 00000000..f56d5bb7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_fips.c
@@ -0,0 +1,96 @@
+/*
+ * Written by Stephen henson (steve@openssl.org) for the OpenSSL project
+ * 2011.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * 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"
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include <openssl/fips_rand.h>
+# include <openssl/rand.h>
+#endif
+
+int FIPS_mode(void)
+{
+ OPENSSL_init();
+#ifdef OPENSSL_FIPS
+ return FIPS_module_mode();
+#else
+ return 0;
+#endif
+}
+
+int FIPS_mode_set(int r)
+{
+ OPENSSL_init();
+#ifdef OPENSSL_FIPS
+# ifndef FIPS_AUTH_USER_PASS
+# define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password"
+# endif
+ if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
+ return 0;
+ if (r)
+ RAND_set_rand_method(FIPS_rand_get_method());
+ else
+ RAND_set_rand_method(NULL);
+ return 1;
+#else
+ if (r == 0)
+ return 1;
+ CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
+ return 0;
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/o_init.c b/Cryptlib/OpenSSL/crypto/o_init.c
new file mode 100644
index 00000000..20883881
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_init.c
@@ -0,0 +1,83 @@
+/* o_init.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <e_os.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include <openssl/rand.h>
+#endif
+
+/*
+ * Perform any essential OpenSSL initialization operations. Currently only
+ * sets FIPS callbacks
+ */
+
+void OPENSSL_init(void)
+{
+ static int done = 0;
+ if (done)
+ return;
+ done = 1;
+#ifdef OPENSSL_FIPS
+ FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
+ FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
+ FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
+ RAND_init_fips();
+#endif
+#if 0
+ fprintf(stderr, "Called OPENSSL_init\n");
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/o_str.c b/Cryptlib/OpenSSL/crypto/o_str.c
new file mode 100644
index 00000000..7e61cde8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_str.c
@@ -0,0 +1,116 @@
+/* crypto/o_str.c */
+/*
+ * 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 <ctype.h>
+#include <e_os.h>
+#include "o_str.h"
+
+#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
+ !defined(OPENSSL_SYSNAME_WIN32) && !defined(OPENSSL_SYSNAME_WINCE) && \
+ !defined(NETWARE_CLIB)
+# include <strings.h>
+#endif
+
+int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n)
+{
+#if defined(OPENSSL_IMPLEMENTS_strncasecmp)
+ while (*str1 && *str2 && n) {
+ int res = toupper(*str1) - toupper(*str2);
+ if (res)
+ return res < 0 ? -1 : 1;
+ str1++;
+ str2++;
+ n--;
+ }
+ if (n == 0)
+ return 0;
+ if (*str1)
+ return 1;
+ if (*str2)
+ return -1;
+ return 0;
+#else
+ /*
+ * Recursion hazard warning! Whenever strncasecmp is #defined as
+ * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be defined as
+ * well.
+ */
+ return strncasecmp(str1, str2, n);
+#endif
+}
+
+int OPENSSL_strcasecmp(const char *str1, const char *str2)
+{
+#if defined(OPENSSL_IMPLEMENTS_strncasecmp)
+ return OPENSSL_strncasecmp(str1, str2, (size_t)-1);
+#else
+ return strcasecmp(str1, str2);
+#endif
+}
+
+int OPENSSL_memcmp(const void *v1, const void *v2, size_t n)
+{
+ const unsigned char *c1 = v1, *c2 = v2;
+ int ret = 0;
+
+ while (n && (ret = *c1 - *c2) == 0)
+ n--, c1++, c2++;
+
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/o_str.h b/Cryptlib/OpenSSL/crypto/o_str.h
new file mode 100644
index 00000000..fa512eb3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_str.h
@@ -0,0 +1,69 @@
+/* crypto/o_str.h */
+/*
+ * 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
+ * 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_O_STR_H
+# define HEADER_O_STR_H
+
+# include <stddef.h> /* to get size_t */
+
+int OPENSSL_strcasecmp(const char *str1, const char *str2);
+int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n);
+int OPENSSL_memcmp(const void *p1, const void *p2, size_t n);
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/o_time.c b/Cryptlib/OpenSSL/crypto/o_time.c
new file mode 100644
index 00000000..635dae18
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_time.c
@@ -0,0 +1,440 @@
+/* crypto/o_time.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2008.
+ */
+/* ====================================================================
+ * 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 <openssl/e_os2.h>
+#include <string.h>
+#include "o_time.h"
+
+#ifdef OPENSSL_SYS_VMS
+# if __CRTL_VER >= 70000000 && \
+ (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE)
+# define VMS_GMTIME_OK
+# endif
+# ifndef VMS_GMTIME_OK
+# include <libdtdef.h>
+# include <lib$routines.h>
+# include <lnmdef.h>
+# include <starlet.h>
+# include <descrip.h>
+# include <stdlib.h>
+# endif /* ndef VMS_GMTIME_OK */
+#endif
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
+{
+ struct tm *ts = NULL;
+
+#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
+ /*
+ * should return &data, but doesn't on some systems, so we don't even
+ * look at the return value
+ */
+ gmtime_r(timer, result);
+ ts = result;
+#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
+ ts = gmtime(timer);
+ if (ts == NULL)
+ return NULL;
+
+ memcpy(result, ts, sizeof(struct tm));
+ ts = result;
+#endif
+#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK)
+ if (ts == NULL) {
+ static $DESCRIPTOR(tabnam, "LNM$DCL_LOGICAL");
+ static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL");
+ char logvalue[256];
+ unsigned int reslen = 0;
+ struct {
+ short buflen;
+ short code;
+ void *bufaddr;
+ unsigned int *reslen;
+ } itemlist[] = {
+ {
+ 0, LNM$_STRING, 0, 0
+ },
+ {
+ 0, 0, 0, 0
+ },
+ };
+ int status;
+ time_t t;
+
+ /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
+ itemlist[0].buflen = sizeof(logvalue);
+ itemlist[0].bufaddr = logvalue;
+ itemlist[0].reslen = &reslen;
+ status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
+ if (!(status & 1))
+ return NULL;
+ logvalue[reslen] = '\0';
+
+ t = *timer;
+
+/* The following is extracted from the DEC C header time.h */
+ /*
+ ** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
+ ** have two implementations. One implementation is provided
+ ** for compatibility and deals with time in terms of local time,
+ ** the other __utc_* deals with time in terms of UTC.
+ */
+ /*
+ * We use the same conditions as in said time.h to check if we should
+ * assume that t contains local time (and should therefore be
+ * adjusted) or UTC (and should therefore be left untouched).
+ */
+# if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE
+ /* Get the numerical value of the equivalence string */
+ status = atoi(logvalue);
+
+ /* and use it to move time to GMT */
+ t -= status;
+# endif
+
+ /* then convert the result to the time structure */
+
+ /*
+ * Since there was no gmtime_r() to do this stuff for us, we have to
+ * do it the hard way.
+ */
+ {
+ /*-
+ * The VMS epoch is the astronomical Smithsonian date,
+ if I remember correctly, which is November 17, 1858.
+ Furthermore, time is measure in thenths of microseconds
+ and stored in quadwords (64 bit integers). unix_epoch
+ below is January 1st 1970 expressed as a VMS time. The
+ following code was used to get this number:
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <lib$routines.h>
+ #include <starlet.h>
+
+ main()
+ {
+ unsigned long systime[2];
+ unsigned short epoch_values[7] =
+ { 1970, 1, 1, 0, 0, 0, 0 };
+
+ lib$cvt_vectim(epoch_values, systime);
+
+ printf("%u %u", systime[0], systime[1]);
+ }
+ */
+ unsigned long unix_epoch[2] = { 1273708544, 8164711 };
+ unsigned long deltatime[2];
+ unsigned long systime[2];
+ struct vms_vectime {
+ short year, month, day, hour, minute, second, centi_second;
+ } time_values;
+ long operation;
+
+ /*
+ * Turn the number of seconds since January 1st 1970 to an
+ * internal delta time. Note that lib$cvt_to_internal_time() will
+ * assume that t is signed, and will therefore break on 32-bit
+ * systems some time in 2038.
+ */
+ operation = LIB$K_DELTA_SECONDS;
+ status = lib$cvt_to_internal_time(&operation, &t, deltatime);
+
+ /*
+ * Add the delta time with the Unix epoch and we have the current
+ * UTC time in internal format
+ */
+ status = lib$add_times(unix_epoch, deltatime, systime);
+
+ /* Turn the internal time into a time vector */
+ status = sys$numtim(&time_values, systime);
+
+ /* Fill in the struct tm with the result */
+ result->tm_sec = time_values.second;
+ result->tm_min = time_values.minute;
+ result->tm_hour = time_values.hour;
+ result->tm_mday = time_values.day;
+ result->tm_mon = time_values.month - 1;
+ result->tm_year = time_values.year - 1900;
+
+ operation = LIB$K_DAY_OF_WEEK;
+ status = lib$cvt_from_internal_time(&operation,
+ &result->tm_wday, systime);
+ result->tm_wday %= 7;
+
+ operation = LIB$K_DAY_OF_YEAR;
+ status = lib$cvt_from_internal_time(&operation,
+ &result->tm_yday, systime);
+ result->tm_yday--;
+
+ result->tm_isdst = 0; /* There's no way to know... */
+
+ ts = result;
+ }
+ }
+#endif
+ return ts;
+}
+
+/*
+ * Take a tm structure and add an offset to it. This avoids any OS issues
+ * with restricted date types and overflows which cause the year 2038
+ * problem.
+ */
+
+#define SECS_PER_DAY (24 * 60 * 60)
+
+static long date_to_julian(int y, int m, int d);
+static void julian_to_date(long jd, int *y, int *m, int *d);
+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
+ long *pday, int *psec);
+
+int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
+{
+ int time_sec, time_year, time_month, time_day;
+ long time_jd;
+
+ /* Convert time and offset into julian day and seconds */
+ if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec))
+ 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 = time_sec / 3600;
+ tm->tm_min = (time_sec / 60) % 60;
+ tm->tm_sec = time_sec % 60;
+
+ return 1;
+
+}
+
+int OPENSSL_gmtime_diff(int *pday, int *psec,
+ const struct tm *from, const struct tm *to)
+{
+ int from_sec, to_sec, diff_sec;
+ long from_jd, to_jd, diff_day;
+ if (!julian_adj(from, 0, 0, &from_jd, &from_sec))
+ return 0;
+ if (!julian_adj(to, 0, 0, &to_jd, &to_sec))
+ return 0;
+ diff_day = to_jd - from_jd;
+ diff_sec = to_sec - from_sec;
+ /* Adjust differences so both positive or both negative */
+ if (diff_day > 0 && diff_sec < 0) {
+ diff_day--;
+ diff_sec += SECS_PER_DAY;
+ }
+ if (diff_day < 0 && diff_sec > 0) {
+ diff_day++;
+ diff_sec -= SECS_PER_DAY;
+ }
+
+ if (pday)
+ *pday = (int)diff_day;
+ if (psec)
+ *psec = diff_sec;
+
+ return 1;
+
+}
+
+/* Convert tm structure and offset into julian day and seconds */
+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
+ long *pday, int *psec)
+{
+ int offset_hms, offset_day;
+ long time_jd;
+ int time_year, time_month, time_day;
+ /* split offset into days and day seconds */
+ offset_day = offset_sec / SECS_PER_DAY;
+ /* Avoid sign issues with % operator */
+ offset_hms = offset_sec - (offset_day * SECS_PER_DAY);
+ offset_day += off_day;
+ /* Add current time seconds to offset */
+ offset_hms += tm->tm_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;
+
+ *pday = time_jd;
+ *psec = offset_hms;
+ 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 <stdio.h>
+
+/*
+ * 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, o1;
+ int off_day, off_sec;
+ long toffset;
+ time_t t1, t2;
+ time(&t1);
+ t2 = t1 + offset;
+ OPENSSL_gmtime(&t2, &tm2);
+ OPENSSL_gmtime(&t1, &tm1);
+ o1 = 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)) {
+ 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;
+ }
+ OPENSSL_gmtime_diff(&o1, &tm1, &off_day, &off_sec);
+ toffset = (long)off_day *SECS_PER_DAY + off_sec;
+ if (offset != toffset) {
+ fprintf(stderr, "TIME OFFSET ERROR!!\n");
+ fprintf(stderr, "Expected %ld, Got %ld (%d:%d)\n",
+ offset, toffset, off_day, off_sec);
+ return 0;
+ }
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/o_time.h b/Cryptlib/OpenSSL/crypto/o_time.h
new file mode 100644
index 00000000..f192c6dc
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/o_time.h
@@ -0,0 +1,70 @@
+/* crypto/o_time.h */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#ifndef HEADER_O_TIME_H
+# define HEADER_O_TIME_H
+
+# include <time.h>
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
+int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
+int OPENSSL_gmtime_diff(int *pday, int *psec,
+ const struct tm *from, const struct tm *to);
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/objects/o_names.c b/Cryptlib/OpenSSL/crypto/objects/o_names.c
new file mode 100644
index 00000000..24859926
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/o_names.c
@@ -0,0 +1,366 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/safestack.h>
+#include <openssl/e_os2.h>
+
+/*
+ * Later versions of DEC C has started to add lnkage information to certain
+ * functions, which makes it tricky to use them as values to regular function
+ * pointers. One way is to define a macro that takes care of casting them
+ * correctly.
+ */
+#ifdef OPENSSL_SYS_VMS_DECC
+# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
+#else
+# define OPENSSL_strcmp strcmp
+#endif
+
+/*
+ * 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.
+ */
+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 {
+ unsigned long (*hash_func) (const char *name);
+ int (*cmp_func) (const char *a, const char *b);
+ void (*free_func) (const char *, int, const char *);
+} NAME_FUNCS;
+
+DECLARE_STACK_OF(NAME_FUNCS)
+IMPLEMENT_STACK_OF(NAME_FUNCS)
+
+static STACK_OF(NAME_FUNCS) *name_funcs_stack;
+
+/*
+ * The LHASH callbacks now use the raw "void *" prototypes and do
+ * per-variable casting in the functions. This prevents function pointer
+ * casting without the need for macro-generated wrapper functions.
+ */
+
+/* static unsigned long obj_name_hash(OBJ_NAME *a); */
+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_OBJ_NAME_new();
+ MemCheck_on();
+ return (names_lh != NULL);
+}
+
+int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
+ int (*cmp_func) (const char *, const char *),
+ void (*free_func) (const char *, int, const char *))
+{
+ int ret;
+ int i;
+ NAME_FUNCS *name_funcs;
+
+ if (name_funcs_stack == NULL) {
+ MemCheck_off();
+ name_funcs_stack = sk_NAME_FUNCS_new_null();
+ MemCheck_on();
+ }
+ if (name_funcs_stack == NULL) {
+ /* ERROR */
+ return (0);
+ }
+ ret = names_type_num;
+ names_type_num++;
+ for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) {
+ MemCheck_off();
+ name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
+ MemCheck_on();
+ if (!name_funcs) {
+ OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ name_funcs->hash_func = lh_strhash;
+ name_funcs->cmp_func = OPENSSL_strcmp;
+ name_funcs->free_func = 0; /* NULL is often declared to * ((void
+ * *)0), which according * to Compaq C is
+ * not really * compatible with a function
+ * * pointer. -- Richard Levitte */
+ MemCheck_off();
+ sk_NAME_FUNCS_push(name_funcs_stack, name_funcs);
+ MemCheck_on();
+ }
+ name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
+ if (hash_func != NULL)
+ name_funcs->hash_func = hash_func;
+ if (cmp_func != NULL)
+ name_funcs->cmp_func = cmp_func;
+ if (free_func != NULL)
+ name_funcs->free_func = free_func;
+ return (ret);
+}
+
+/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
+static int obj_name_cmp(const void *a_void, const void *b_void)
+{
+ int ret;
+ const OBJ_NAME *a = (const OBJ_NAME *)a_void;
+ const OBJ_NAME *b = (const OBJ_NAME *)b_void;
+
+ ret = a->type - b->type;
+ if (ret == 0) {
+ if ((name_funcs_stack != NULL)
+ && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
+ ret = sk_NAME_FUNCS_value(name_funcs_stack,
+ a->type)->cmp_func(a->name, b->name);
+ } else
+ ret = strcmp(a->name, b->name);
+ }
+ return (ret);
+}
+
+/* static unsigned long obj_name_hash(OBJ_NAME *a) */
+static unsigned long obj_name_hash(const void *a_void)
+{
+ unsigned long ret;
+ const OBJ_NAME *a = (const OBJ_NAME *)a_void;
+
+ if ((name_funcs_stack != NULL)
+ && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
+ ret =
+ sk_NAME_FUNCS_value(name_funcs_stack,
+ a->type)->hash_func(a->name);
+ } else {
+ ret = lh_strhash(a->name);
+ }
+ ret ^= a->type;
+ return (ret);
+}
+
+const char *OBJ_NAME_get(const char *name, int type)
+{
+ OBJ_NAME on, *ret;
+ int num = 0, alias;
+
+ if (name == NULL)
+ return (NULL);
+ if ((names_lh == NULL) && !OBJ_NAME_init())
+ return (NULL);
+
+ alias = type & OBJ_NAME_ALIAS;
+ type &= ~OBJ_NAME_ALIAS;
+
+ on.name = name;
+ on.type = type;
+
+ for (;;) {
+ ret = lh_OBJ_NAME_retrieve(names_lh, &on);
+ if (ret == NULL)
+ return (NULL);
+ if ((ret->alias) && !alias) {
+ if (++num > 10)
+ return (NULL);
+ on.name = ret->data;
+ } else {
+ return (ret->data);
+ }
+ }
+}
+
+int OBJ_NAME_add(const char *name, int type, const char *data)
+{
+ OBJ_NAME *onp, *ret;
+ int alias;
+
+ if ((names_lh == NULL) && !OBJ_NAME_init())
+ return (0);
+
+ alias = type & OBJ_NAME_ALIAS;
+ type &= ~OBJ_NAME_ALIAS;
+
+ onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
+ if (onp == NULL) {
+ /* ERROR */
+ return (0);
+ }
+
+ onp->name = name;
+ onp->alias = alias;
+ onp->type = type;
+ onp->data = data;
+
+ ret = lh_OBJ_NAME_insert(names_lh, onp);
+ if (ret != NULL) {
+ /* free things */
+ if ((name_funcs_stack != NULL)
+ && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
+ /*
+ * XXX: I'm not sure I understand why the free function should
+ * get three arguments... -- Richard Levitte
+ */
+ sk_NAME_FUNCS_value(name_funcs_stack,
+ ret->type)->free_func(ret->name, ret->type,
+ ret->data);
+ }
+ OPENSSL_free(ret);
+ } else {
+ if (lh_OBJ_NAME_error(names_lh)) {
+ /* ERROR */
+ return (0);
+ }
+ }
+ return (1);
+}
+
+int OBJ_NAME_remove(const char *name, int type)
+{
+ OBJ_NAME on, *ret;
+
+ if (names_lh == NULL)
+ return (0);
+
+ type &= ~OBJ_NAME_ALIAS;
+ on.name = name;
+ on.type = type;
+ ret = lh_OBJ_NAME_delete(names_lh, &on);
+ if (ret != NULL) {
+ /* free things */
+ if ((name_funcs_stack != NULL)
+ && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
+ /*
+ * XXX: I'm not sure I understand why the free function should
+ * get three arguments... -- Richard Levitte
+ */
+ sk_NAME_FUNCS_value(name_funcs_stack,
+ ret->type)->free_func(ret->name, ret->type,
+ ret->data);
+ }
+ OPENSSL_free(ret);
+ return (1);
+ } else
+ return (0);
+}
+
+struct doall {
+ int type;
+ void (*fn) (const OBJ_NAME *, void *arg);
+ void *arg;
+};
+
+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)
+
+void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
+ void *arg)
+{
+ struct doall d;
+
+ d.type = type;
+ d.fn = fn;
+ d.arg = arg;
+
+ lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
+ struct doall, &d);
+}
+
+struct doall_sorted {
+ int type;
+ int n;
+ const OBJ_NAME **names;
+};
+
+static void do_all_sorted_fn(const OBJ_NAME *name, void *d_)
+{
+ struct doall_sorted *d = d_;
+
+ if (name->type != d->type)
+ return;
+
+ d->names[d->n++] = name;
+}
+
+static int do_all_sorted_cmp(const void *n1_, const void *n2_)
+{
+ const OBJ_NAME *const *n1 = n1_;
+ const OBJ_NAME *const *n2 = n2_;
+
+ return strcmp((*n1)->name, (*n2)->name);
+}
+
+void OBJ_NAME_do_all_sorted(int type,
+ void (*fn) (const OBJ_NAME *, void *arg),
+ void *arg)
+{
+ struct doall_sorted d;
+ int n;
+
+ d.type = type;
+ d.names =
+ OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh) * sizeof *d.names);
+ /* Really should return an error if !d.names...but its a void function! */
+ if (d.names) {
+ d.n = 0;
+ OBJ_NAME_do_all(type, do_all_sorted_fn, &d);
+
+ qsort((void *)d.names, d.n, sizeof *d.names, do_all_sorted_cmp);
+
+ for (n = 0; n < d.n; ++n)
+ fn(d.names[n], arg);
+
+ OPENSSL_free((void *)d.names);
+ }
+}
+
+static int free_type;
+
+static void names_lh_free_doall(OBJ_NAME *onp)
+{
+ if (onp == NULL)
+ return;
+
+ 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 void name_funcs_free(NAME_FUNCS *ptr)
+{
+ OPENSSL_free(ptr);
+}
+
+void OBJ_NAME_cleanup(int type)
+{
+ unsigned long down_load;
+
+ if (names_lh == NULL)
+ return;
+
+ free_type = type;
+ down_load = lh_OBJ_NAME_down_load(names_lh);
+ lh_OBJ_NAME_down_load(names_lh) = 0;
+
+ lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free));
+ if (type < 0) {
+ 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
+ lh_OBJ_NAME_down_load(names_lh) = down_load;
+}
diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_dat.c b/Cryptlib/OpenSSL/crypto/objects/obj_dat.c
new file mode 100644
index 00000000..aca382a6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_dat.c
@@ -0,0 +1,801 @@
+/* crypto/objects/obj_dat.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 <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+
+/* obj_dat.h is generated from objects.h by obj_dat.pl */
+#ifndef OPENSSL_NO_OBJECT
+# include "obj_dat.h"
+#else
+/* You will have to load all the objects needed manually in the application */
+# define NUM_NID 0
+# define NUM_SN 0
+# define NUM_LN 0
+# define NUM_OBJ 0
+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
+
+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
+#define ADDED_NID 3
+
+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_OF(ADDED_OBJ) *added = NULL;
+
+static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
+{
+ return (strcmp((*a)->sn, nid_objs[*b].sn));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+
+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;
+
+ a = ca->obj;
+ switch (ca->type) {
+ case ADDED_DATA:
+ ret = a->length << 20L;
+ p = (unsigned char *)a->data;
+ for (i = 0; i < a->length; i++)
+ ret ^= p[i] << ((i * 3) % 24);
+ break;
+ case ADDED_SNAME:
+ ret = lh_strhash(a->sn);
+ break;
+ case ADDED_LNAME:
+ ret = lh_strhash(a->ln);
+ break;
+ case ADDED_NID:
+ ret = a->nid;
+ break;
+ default:
+ /* abort(); */
+ return 0;
+ }
+ ret &= 0x3fffffffL;
+ ret |= ((unsigned long)ca->type) << 30L;
+ return (ret);
+}
+
+static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
+
+static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
+{
+ ASN1_OBJECT *a, *b;
+ int i;
+
+ i = ca->type - cb->type;
+ if (i)
+ return (i);
+ a = ca->obj;
+ b = cb->obj;
+ switch (ca->type) {
+ case ADDED_DATA:
+ i = (a->length - b->length);
+ if (i)
+ return (i);
+ return (memcmp(a->data, b->data, (size_t)a->length));
+ case ADDED_SNAME:
+ if (a->sn == NULL)
+ return (-1);
+ else if (b->sn == NULL)
+ return (1);
+ else
+ return (strcmp(a->sn, b->sn));
+ case ADDED_LNAME:
+ if (a->ln == NULL)
+ return (-1);
+ else if (b->ln == NULL)
+ return (1);
+ else
+ return (strcmp(a->ln, b->ln));
+ case ADDED_NID:
+ return (a->nid - b->nid);
+ default:
+ /* abort(); */
+ return 0;
+ }
+}
+
+static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
+
+static int init_added(void)
+{
+ if (added != NULL)
+ return (1);
+ added = lh_ADDED_OBJ_new();
+ return (added != NULL);
+}
+
+static void cleanup1_doall(ADDED_OBJ *a)
+{
+ a->obj->nid = 0;
+ a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
+ ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+}
+
+static void cleanup2_doall(ADDED_OBJ *a)
+{
+ a->obj->nid++;
+}
+
+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)
+
+/*
+ * 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;
+ 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;
+}
+
+int OBJ_new_nid(int num)
+{
+ int i;
+
+ i = new_nid;
+ new_nid += num;
+ return (i);
+}
+
+int OBJ_add_object(const ASN1_OBJECT *obj)
+{
+ ASN1_OBJECT *o;
+ ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
+ int i;
+
+ if (added == NULL)
+ if (!init_added())
+ return (0);
+ if ((o = OBJ_dup(obj)) == NULL)
+ goto err;
+ if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
+ goto err2;
+ if ((o->length != 0) && (obj->data != NULL))
+ if (!
+ (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
+ goto err2;
+ if (o->sn != NULL)
+ if (!
+ (ao[ADDED_SNAME] =
+ (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
+ goto err2;
+ if (o->ln != NULL)
+ if (!
+ (ao[ADDED_LNAME] =
+ (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
+ goto err2;
+
+ for (i = ADDED_DATA; i <= ADDED_NID; i++) {
+ if (ao[i] != NULL) {
+ ao[i]->type = i;
+ ao[i]->obj = o;
+ aop = lh_ADDED_OBJ_insert(added, ao[i]);
+ /* memory leak, buit should not normally matter */
+ if (aop != NULL)
+ OPENSSL_free(aop);
+ }
+ }
+ o->flags &=
+ ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+ ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+
+ return (o->nid);
+ err2:
+ OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
+ err:
+ for (i = ADDED_DATA; i <= ADDED_NID; i++)
+ if (ao[i] != NULL)
+ OPENSSL_free(ao[i]);
+ if (o != NULL)
+ OPENSSL_free(o);
+ return (NID_undef);
+}
+
+ASN1_OBJECT *OBJ_nid2obj(int n)
+{
+ ADDED_OBJ ad, *adp;
+ ASN1_OBJECT ob;
+
+ if ((n >= 0) && (n < NUM_NID)) {
+ if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+ OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ return ((ASN1_OBJECT *)&(nid_objs[n]));
+ } else if (added == NULL)
+ return (NULL);
+ else {
+ ad.type = ADDED_NID;
+ ad.obj = &ob;
+ ob.nid = n;
+ adp = lh_ADDED_OBJ_retrieve(added, &ad);
+ if (adp != NULL)
+ return (adp->obj);
+ else {
+ OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ }
+}
+
+const char *OBJ_nid2sn(int n)
+{
+ ADDED_OBJ ad, *adp;
+ ASN1_OBJECT ob;
+
+ if ((n >= 0) && (n < NUM_NID)) {
+ if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+ OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ return (nid_objs[n].sn);
+ } else if (added == NULL)
+ return (NULL);
+ else {
+ ad.type = ADDED_NID;
+ ad.obj = &ob;
+ ob.nid = n;
+ adp = lh_ADDED_OBJ_retrieve(added, &ad);
+ if (adp != NULL)
+ return (adp->obj->sn);
+ else {
+ OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ }
+}
+
+const char *OBJ_nid2ln(int n)
+{
+ ADDED_OBJ ad, *adp;
+ ASN1_OBJECT ob;
+
+ if ((n >= 0) && (n < NUM_NID)) {
+ if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+ OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ return (nid_objs[n].ln);
+ } else if (added == NULL)
+ return (NULL);
+ else {
+ ad.type = ADDED_NID;
+ ad.obj = &ob;
+ ob.nid = n;
+ adp = lh_ADDED_OBJ_retrieve(added, &ad);
+ if (adp != NULL)
+ return (adp->obj->ln);
+ else {
+ OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ }
+}
+
+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);
+ if (a->length == 0)
+ return 0;
+ 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)
+{
+ const unsigned int *op;
+ ADDED_OBJ ad, *adp;
+
+ if (a == NULL)
+ return (NID_undef);
+ if (a->nid != 0)
+ return (a->nid);
+
+ if (a->length == 0)
+ return NID_undef;
+
+ if (added != NULL) {
+ ad.type = ADDED_DATA;
+ ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
+ adp = lh_ADDED_OBJ_retrieve(added, &ad);
+ if (adp != NULL)
+ return (adp->obj->nid);
+ }
+ op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
+ if (op == NULL)
+ return (NID_undef);
+ return (nid_objs[*op].nid);
+}
+
+/*
+ * Convert an object name into an ASN1_OBJECT if "noname" is not set then
+ * search for short and long names first. This will convert the "dotted" form
+ * into an object: unlike OBJ_txt2nid it can be used with any objects, not
+ * just registered ones.
+ */
+
+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
+{
+ int nid = NID_undef;
+ ASN1_OBJECT *op = NULL;
+ unsigned char *buf;
+ unsigned char *p;
+ const unsigned char *cp;
+ int i, j;
+
+ if (!no_name) {
+ if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
+ ((nid = OBJ_ln2nid(s)) != NID_undef))
+ return OBJ_nid2obj(nid);
+ }
+
+ /* Work out size of content octets */
+ i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
+ if (i <= 0) {
+ /* Don't clear the error */
+ /*
+ * ERR_clear_error();
+ */
+ return NULL;
+ }
+ /* Work out total size */
+ j = ASN1_object_size(0, i, V_ASN1_OBJECT);
+
+ if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL)
+ return NULL;
+
+ p = buf;
+ /* Write out tag+length */
+ ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+ /* Write out contents */
+ a2d_ASN1_OBJECT(p, i, s, -1);
+
+ cp = buf;
+ op = d2i_ASN1_OBJECT(NULL, &cp, j);
+ OPENSSL_free(buf);
+ return op;
+}
+
+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;
+ const unsigned char *p;
+ char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
+
+ /* Ensure that, at every state, |buf| is NUL-terminated. */
+ if (buf && buf_len > 0)
+ buf[0] = '\0';
+
+ if ((a == NULL) || (a->data == NULL))
+ return (0);
+
+ if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
+ const char *s;
+ s = OBJ_nid2ln(nid);
+ if (s == NULL)
+ s = OBJ_nid2sn(nid);
+ if (s) {
+ if (buf)
+ BUF_strlcpy(buf, s, buf_len);
+ n = strlen(s);
+ return n;
+ }
+ }
+
+ len = a->length;
+ p = a->data;
+
+ first = 1;
+ bl = NULL;
+
+ while (len > 0) {
+ l = 0;
+ use_bn = 0;
+ for (;;) {
+ unsigned char c = *p++;
+ len--;
+ if ((len == 0) && (c & 0x80))
+ goto err;
+ if (use_bn) {
+ if (!BN_add_word(bl, c & 0x7f))
+ goto err;
+ } else
+ l |= c & 0x7f;
+ if (!(c & 0x80))
+ break;
+ if (!use_bn && (l > (ULONG_MAX >> 7L))) {
+ if (!bl && !(bl = BN_new()))
+ goto err;
+ if (!BN_set_word(bl, l))
+ goto err;
+ use_bn = 1;
+ }
+ if (use_bn) {
+ if (!BN_lshift(bl, bl, 7))
+ goto err;
+ } else
+ l <<= 7L;
+ }
+
+ if (first) {
+ first = 0;
+ if (l >= 80) {
+ i = 2;
+ if (use_bn) {
+ if (!BN_sub_word(bl, 80))
+ goto err;
+ } else
+ l -= 80;
+ } else {
+ i = (int)(l / 40);
+ l -= (long)(i * 40);
+ }
+ if (buf && (buf_len > 1)) {
+ *buf++ = i + '0';
+ *buf = '\0';
+ buf_len--;
+ }
+ n++;
+ }
+
+ if (use_bn) {
+ char *bndec;
+ bndec = BN_bn2dec(bl);
+ if (!bndec)
+ goto err;
+ i = strlen(bndec);
+ if (buf) {
+ if (buf_len > 1) {
+ *buf++ = '.';
+ *buf = '\0';
+ buf_len--;
+ }
+ BUF_strlcpy(buf, bndec, buf_len);
+ if (i > buf_len) {
+ buf += buf_len;
+ buf_len = 0;
+ } else {
+ buf += i;
+ buf_len -= i;
+ }
+ }
+ n++;
+ n += i;
+ OPENSSL_free(bndec);
+ } else {
+ BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
+ i = strlen(tbuf);
+ if (buf && (buf_len > 0)) {
+ BUF_strlcpy(buf, tbuf, buf_len);
+ if (i > buf_len) {
+ buf += buf_len;
+ buf_len = 0;
+ } else {
+ buf += i;
+ buf_len -= i;
+ }
+ }
+ n += i;
+ l = 0;
+ }
+ }
+
+ if (bl)
+ BN_free(bl);
+ return n;
+
+ err:
+ if (bl)
+ BN_free(bl);
+ return -1;
+}
+
+int OBJ_txt2nid(const char *s)
+{
+ ASN1_OBJECT *obj;
+ int nid;
+ obj = OBJ_txt2obj(s, 0);
+ nid = OBJ_obj2nid(obj);
+ ASN1_OBJECT_free(obj);
+ return nid;
+}
+
+int OBJ_ln2nid(const char *s)
+{
+ 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 = lh_ADDED_OBJ_retrieve(added, &ad);
+ if (adp != NULL)
+ return (adp->obj->nid);
+ }
+ op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
+ if (op == NULL)
+ return (NID_undef);
+ return (nid_objs[*op].nid);
+}
+
+int OBJ_sn2nid(const char *s)
+{
+ 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 = lh_ADDED_OBJ_retrieve(added, &ad);
+ if (adp != NULL)
+ return (adp->obj->nid);
+ }
+ op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
+ if (op == NULL)
+ return (NID_undef);
+ return (nid_objs[*op].nid);
+}
+
+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);
+}
+
+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;
+
+ if (num == 0)
+ return (NULL);
+ l = 0;
+ h = num;
+ while (l < h) {
+ i = (l + h) / 2;
+ p = &(base[i * size]);
+ c = (*cmp) (key, p);
+ if (c < 0)
+ h = i;
+ else if (c > 0)
+ l = i + 1;
+ else
+ break;
+ }
+#ifdef CHARSET_EBCDIC
+ /*
+ * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
+ * don't have perl (yet), we revert to a *LINEAR* search when the object
+ * wasn't found in the binary search.
+ */
+ if (c != 0) {
+ for (i = 0; i < num; ++i) {
+ p = &(base[i * size]);
+ c = (*cmp) (key, p);
+ if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
+ return p;
+ }
+ }
+#endif
+ if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
+ p = NULL;
+ else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
+ while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
+ i--;
+ p = &(base[i * size]);
+ }
+ return (p);
+}
+
+int OBJ_create_objects(BIO *in)
+{
+ MS_STATIC char buf[512];
+ int i, num = 0;
+ char *o, *s, *l = NULL;
+
+ for (;;) {
+ s = o = NULL;
+ i = BIO_gets(in, buf, 512);
+ if (i <= 0)
+ return (num);
+ buf[i - 1] = '\0';
+ if (!isalnum((unsigned char)buf[0]))
+ return (num);
+ o = s = buf;
+ while (isdigit((unsigned char)*s) || (*s == '.'))
+ s++;
+ if (*s != '\0') {
+ *(s++) = '\0';
+ while (isspace((unsigned char)*s))
+ s++;
+ if (*s == '\0')
+ s = NULL;
+ else {
+ l = s;
+ while ((*l != '\0') && !isspace((unsigned char)*l))
+ l++;
+ if (*l != '\0') {
+ *(l++) = '\0';
+ while (isspace((unsigned char)*l))
+ l++;
+ if (*l == '\0')
+ l = NULL;
+ } else
+ l = NULL;
+ }
+ } else
+ s = NULL;
+ if ((o == NULL) || (*o == '\0'))
+ return (num);
+ if (!OBJ_create(o, s, l))
+ return (num);
+ num++;
+ }
+ /* return(num); */
+}
+
+int OBJ_create(const char *oid, const char *sn, const char *ln)
+{
+ int ok = 0;
+ ASN1_OBJECT *op = NULL;
+ unsigned char *buf;
+ int i;
+
+ i = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
+ if (i <= 0)
+ return (0);
+
+ if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
+ OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ i = a2d_ASN1_OBJECT(buf, i, oid, -1);
+ if (i == 0)
+ goto err;
+ op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln);
+ if (op == NULL)
+ goto err;
+ ok = OBJ_add_object(op);
+ err:
+ ASN1_OBJECT_free(op);
+ OPENSSL_free(buf);
+ return (ok);
+}
diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_dat.h b/Cryptlib/OpenSSL/crypto/objects/obj_dat.h
new file mode 100644
index 00000000..b7e3cf28
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_dat.h
@@ -0,0 +1,5319 @@
+/* crypto/objects/obj_dat.h */
+
+/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
+ * following command:
+ * perl obj_dat.pl obj_mac.h obj_dat.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.]
+ */
+
+#define NUM_NID 958
+#define NUM_SN 951
+#define NUM_LN 951
+#define NUM_OBJ 890
+
+static const unsigned char lvalues[6255]={
+0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05, /* [ 21] OBJ_md5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04, /* [ 29] OBJ_rc4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 37] OBJ_rsaEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 46] OBJ_md2WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 55] OBJ_md5WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 64] OBJ_pbeWithMD2AndDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 73] OBJ_pbeWithMD5AndDES_CBC */
+0x55, /* [ 82] OBJ_X500 */
+0x55,0x04, /* [ 83] OBJ_X509 */
+0x55,0x04,0x03, /* [ 85] OBJ_commonName */
+0x55,0x04,0x06, /* [ 88] OBJ_countryName */
+0x55,0x04,0x07, /* [ 91] OBJ_localityName */
+0x55,0x04,0x08, /* [ 94] OBJ_stateOrProvinceName */
+0x55,0x04,0x0A, /* [ 97] OBJ_organizationName */
+0x55,0x04,0x0B, /* [100] OBJ_organizationalUnitName */
+0x55,0x08,0x01,0x01, /* [103] OBJ_rsa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07, /* [107] OBJ_pkcs7 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [115] OBJ_pkcs7_data */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [124] OBJ_pkcs7_signed */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [133] OBJ_pkcs7_enveloped */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [142] OBJ_pkcs7_signedAndEnveloped */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [151] OBJ_pkcs7_digest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [160] OBJ_pkcs7_encrypted */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03, /* [169] OBJ_pkcs3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [177] OBJ_dhKeyAgreement */
+0x2B,0x0E,0x03,0x02,0x06, /* [186] OBJ_des_ecb */
+0x2B,0x0E,0x03,0x02,0x09, /* [191] OBJ_des_cfb64 */
+0x2B,0x0E,0x03,0x02,0x07, /* [196] OBJ_des_cbc */
+0x2B,0x0E,0x03,0x02,0x11, /* [201] OBJ_des_ede_ecb */
+0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [206] OBJ_idea_cbc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02, /* [217] OBJ_rc2_cbc */
+0x2B,0x0E,0x03,0x02,0x12, /* [225] OBJ_sha */
+0x2B,0x0E,0x03,0x02,0x0F, /* [230] OBJ_shaWithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07, /* [235] OBJ_des_ede3_cbc */
+0x2B,0x0E,0x03,0x02,0x08, /* [243] OBJ_des_ofb64 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09, /* [248] OBJ_pkcs9 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [256] OBJ_pkcs9_emailAddress */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [265] OBJ_pkcs9_unstructuredName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [274] OBJ_pkcs9_contentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [283] OBJ_pkcs9_messageDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [292] OBJ_pkcs9_signingTime */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [301] OBJ_pkcs9_countersignature */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [310] OBJ_pkcs9_challengePassword */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [319] OBJ_pkcs9_unstructuredAddress */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [328] OBJ_pkcs9_extCertAttributes */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42, /* [337] OBJ_netscape */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01, /* [344] OBJ_netscape_cert_extension */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02, /* [352] OBJ_netscape_data_type */
+0x2B,0x0E,0x03,0x02,0x1A, /* [360] OBJ_sha1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [365] OBJ_sha1WithRSAEncryption */
+0x2B,0x0E,0x03,0x02,0x0D, /* [374] OBJ_dsaWithSHA */
+0x2B,0x0E,0x03,0x02,0x0C, /* [379] OBJ_dsa_2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [384] OBJ_pbeWithSHA1AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [393] OBJ_id_pbkdf2 */
+0x2B,0x0E,0x03,0x02,0x1B, /* [402] OBJ_dsaWithSHA1_2 */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [407] OBJ_netscape_cert_type */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [416] OBJ_netscape_base_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [425] OBJ_netscape_revocation_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [434] OBJ_netscape_ca_revocation_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [443] OBJ_netscape_renewal_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [452] OBJ_netscape_ca_policy_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [461] OBJ_netscape_ssl_server_name */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [470] OBJ_netscape_comment */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [479] OBJ_netscape_cert_sequence */
+0x55,0x1D, /* [488] OBJ_id_ce */
+0x55,0x1D,0x0E, /* [490] OBJ_subject_key_identifier */
+0x55,0x1D,0x0F, /* [493] OBJ_key_usage */
+0x55,0x1D,0x10, /* [496] OBJ_private_key_usage_period */
+0x55,0x1D,0x11, /* [499] OBJ_subject_alt_name */
+0x55,0x1D,0x12, /* [502] OBJ_issuer_alt_name */
+0x55,0x1D,0x13, /* [505] OBJ_basic_constraints */
+0x55,0x1D,0x14, /* [508] OBJ_crl_number */
+0x55,0x1D,0x20, /* [511] OBJ_certificate_policies */
+0x55,0x1D,0x23, /* [514] OBJ_authority_key_identifier */
+0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [517] OBJ_bf_cbc */
+0x55,0x08,0x03,0x65, /* [526] OBJ_mdc2 */
+0x55,0x08,0x03,0x64, /* [530] OBJ_mdc2WithRSA */
+0x55,0x04,0x2A, /* [534] OBJ_givenName */
+0x55,0x04,0x04, /* [537] OBJ_surname */
+0x55,0x04,0x2B, /* [540] OBJ_initials */
+0x55,0x1D,0x1F, /* [543] OBJ_crl_distribution_points */
+0x2B,0x0E,0x03,0x02,0x03, /* [546] OBJ_md5WithRSA */
+0x55,0x04,0x05, /* [551] OBJ_serialNumber */
+0x55,0x04,0x0C, /* [554] OBJ_title */
+0x55,0x04,0x0D, /* [557] OBJ_description */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [560] OBJ_cast5_cbc */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [569] OBJ_pbeWithMD5AndCast5_CBC */
+0x2A,0x86,0x48,0xCE,0x38,0x04,0x03, /* [578] OBJ_dsaWithSHA1 */
+0x2B,0x0E,0x03,0x02,0x1D, /* [585] OBJ_sha1WithRSA */
+0x2A,0x86,0x48,0xCE,0x38,0x04,0x01, /* [590] OBJ_dsa */
+0x2B,0x24,0x03,0x02,0x01, /* [597] OBJ_ripemd160 */
+0x2B,0x24,0x03,0x03,0x01,0x02, /* [602] OBJ_ripemd160WithRSA */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08, /* [608] OBJ_rc5_cbc */
+0x29,0x01,0x01,0x85,0x1A,0x01, /* [616] OBJ_rle_compression */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */
+0x55,0x1D,0x25, /* [633] OBJ_ext_key_usage */
+0x2B,0x06,0x01,0x05,0x05,0x07, /* [636] OBJ_id_pkix */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03, /* [642] OBJ_id_kp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, /* [649] OBJ_server_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02, /* [657] OBJ_client_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03, /* [665] OBJ_code_sign */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04, /* [673] OBJ_email_protect */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08, /* [681] OBJ_time_stamp */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */
+0x55,0x1D,0x1B, /* [748] OBJ_delta_crl */
+0x55,0x1D,0x15, /* [751] OBJ_crl_reason */
+0x55,0x1D,0x18, /* [754] OBJ_invalidity_date */
+0x2B,0x65,0x01,0x04,0x01, /* [757] OBJ_sxnet */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07, /* [954] OBJ_hmacWithSHA1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, /* [962] OBJ_id_qt_cps */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, /* [970] OBJ_id_qt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */
+0x55,0x04,0x29, /* [1033] OBJ_name */
+0x55,0x04,0x2E, /* [1036] OBJ_dnQualifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01, /* [1039] OBJ_id_pe */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30, /* [1046] OBJ_id_ad */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [1053] OBJ_info_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [1061] OBJ_ad_OCSP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [1069] OBJ_ad_ca_issuers */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [1077] OBJ_OCSP_sign */
+0x2A, /* [1085] OBJ_member_body */
+0x2A,0x86,0x48, /* [1086] OBJ_ISO_US */
+0x2A,0x86,0x48,0xCE,0x38, /* [1089] OBJ_X9_57 */
+0x2A,0x86,0x48,0xCE,0x38,0x04, /* [1094] OBJ_X9cm */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, /* [1100] OBJ_pkcs1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05, /* [1108] OBJ_pkcs5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04, /* [1866] OBJ_md4 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00, /* [1874] OBJ_id_pkix_mod */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02, /* [1881] OBJ_id_qt */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04, /* [1888] OBJ_id_it */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05, /* [1895] OBJ_id_pkip */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06, /* [1902] OBJ_id_alg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07, /* [1909] OBJ_id_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08, /* [1916] OBJ_id_on */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09, /* [1923] OBJ_id_pda */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A, /* [1930] OBJ_id_aca */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B, /* [1937] OBJ_id_qcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C, /* [1944] OBJ_id_cct */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01, /* [1951] OBJ_id_pkix1_explicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02, /* [1959] OBJ_id_pkix1_implicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03, /* [1967] OBJ_id_pkix1_explicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04, /* [1975] OBJ_id_pkix1_implicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05, /* [1983] OBJ_id_mod_crmf */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06, /* [1991] OBJ_id_mod_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07, /* [1999] OBJ_id_mod_kea_profile_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08, /* [2007] OBJ_id_mod_kea_profile_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09, /* [2015] OBJ_id_mod_cmp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A, /* [2023] OBJ_id_mod_qualified_cert_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B, /* [2031] OBJ_id_mod_qualified_cert_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C, /* [2039] OBJ_id_mod_attribute_cert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D, /* [2047] OBJ_id_mod_timestamp_protocol */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E, /* [2055] OBJ_id_mod_ocsp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F, /* [2063] OBJ_id_mod_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10, /* [2071] OBJ_id_mod_cmp2000 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02, /* [2079] OBJ_biometricInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03, /* [2087] OBJ_qcStatements */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04, /* [2095] OBJ_ac_auditEntity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05, /* [2103] OBJ_ac_targeting */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06, /* [2111] OBJ_aaControls */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07, /* [2119] OBJ_sbgp_ipAddrBlock */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08, /* [2127] OBJ_sbgp_autonomousSysNum */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09, /* [2135] OBJ_sbgp_routerIdentifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03, /* [2143] OBJ_textNotice */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, /* [2151] OBJ_ipsecEndSystem */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06, /* [2159] OBJ_ipsecTunnel */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07, /* [2167] OBJ_ipsecUser */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A, /* [2175] OBJ_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01, /* [2183] OBJ_id_it_caProtEncCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02, /* [2191] OBJ_id_it_signKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03, /* [2199] OBJ_id_it_encKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04, /* [2207] OBJ_id_it_preferredSymmAlg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05, /* [2215] OBJ_id_it_caKeyUpdateInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06, /* [2223] OBJ_id_it_currentCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07, /* [2231] OBJ_id_it_unsupportedOIDs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08, /* [2239] OBJ_id_it_subscriptionRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09, /* [2247] OBJ_id_it_subscriptionResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A, /* [2255] OBJ_id_it_keyPairParamReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B, /* [2263] OBJ_id_it_keyPairParamRep */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C, /* [2271] OBJ_id_it_revPassphrase */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D, /* [2279] OBJ_id_it_implicitConfirm */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E, /* [2287] OBJ_id_it_confirmWaitTime */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F, /* [2295] OBJ_id_it_origPKIMessage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01, /* [2303] OBJ_id_regCtrl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02, /* [2311] OBJ_id_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01, /* [2391] OBJ_id_alg_des40 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02, /* [2399] OBJ_id_alg_noSignature */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03, /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04, /* [2415] OBJ_id_alg_dh_pop */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01, /* [2423] OBJ_id_cmc_statusInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02, /* [2431] OBJ_id_cmc_identification */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03, /* [2439] OBJ_id_cmc_identityProof */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04, /* [2447] OBJ_id_cmc_dataReturn */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05, /* [2455] OBJ_id_cmc_transactionId */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06, /* [2463] OBJ_id_cmc_senderNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07, /* [2471] OBJ_id_cmc_recipientNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08, /* [2479] OBJ_id_cmc_addExtensions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09, /* [2487] OBJ_id_cmc_encryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A, /* [2495] OBJ_id_cmc_decryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B, /* [2503] OBJ_id_cmc_lraPOPWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F, /* [2511] OBJ_id_cmc_getCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10, /* [2519] OBJ_id_cmc_getCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11, /* [2527] OBJ_id_cmc_revokeRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12, /* [2535] OBJ_id_cmc_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13, /* [2543] OBJ_id_cmc_responseInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15, /* [2551] OBJ_id_cmc_queryPending */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16, /* [2559] OBJ_id_cmc_popLinkRandom */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17, /* [2567] OBJ_id_cmc_popLinkWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18, /* [2575] OBJ_id_cmc_confirmCertAcceptance */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01, /* [2583] OBJ_id_on_personalData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01, /* [2591] OBJ_id_pda_dateOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02, /* [2599] OBJ_id_pda_placeOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03, /* [2607] OBJ_id_pda_gender */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04, /* [2615] OBJ_id_pda_countryOfCitizenship */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05, /* [2623] OBJ_id_pda_countryOfResidence */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01, /* [2631] OBJ_id_aca_authenticationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02, /* [2639] OBJ_id_aca_accessIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03, /* [2647] OBJ_id_aca_chargingIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04, /* [2655] OBJ_id_aca_group */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05, /* [2663] OBJ_id_aca_role */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01, /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01, /* [2679] OBJ_id_cct_crs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02, /* [2687] OBJ_id_cct_PKIData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03, /* [2695] OBJ_id_cct_PKIResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03, /* [2703] OBJ_ad_timeStamping */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04, /* [2711] OBJ_ad_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */
+0x2B,0x0E,0x03,0x02, /* [2818] OBJ_algorithm */
+0x2B,0x0E,0x03,0x02,0x0B, /* [2822] OBJ_rsaSignature */
+0x55,0x08, /* [2827] OBJ_X500algorithms */
+0x2B, /* [2829] OBJ_org */
+0x2B,0x06, /* [2830] OBJ_dod */
+0x2B,0x06,0x01, /* [2832] OBJ_iana */
+0x2B,0x06,0x01,0x01, /* [2835] OBJ_Directory */
+0x2B,0x06,0x01,0x02, /* [2839] OBJ_Management */
+0x2B,0x06,0x01,0x03, /* [2843] OBJ_Experimental */
+0x2B,0x06,0x01,0x04, /* [2847] OBJ_Private */
+0x2B,0x06,0x01,0x05, /* [2851] OBJ_Security */
+0x2B,0x06,0x01,0x06, /* [2855] OBJ_SNMPv2 */
+0x2B,0x06,0x01,0x07, /* [2859] OBJ_Mail */
+0x2B,0x06,0x01,0x04,0x01, /* [2863] OBJ_Enterprises */
+0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */
+0x55,0x01,0x05, /* [2897] OBJ_selected_attribute_types */
+0x55,0x01,0x05,0x37, /* [2900] OBJ_clearance */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A, /* [2913] OBJ_ac_proxying */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B, /* [2921] OBJ_sinfo_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06, /* [2929] OBJ_id_aca_encAttrs */
+0x55,0x04,0x48, /* [2937] OBJ_role */
+0x55,0x1D,0x24, /* [2940] OBJ_policy_constraints */
+0x55,0x1D,0x37, /* [2943] OBJ_target_information */
+0x55,0x1D,0x38, /* [2946] OBJ_no_rev_avail */
+0x2A,0x86,0x48,0xCE,0x3D, /* [2949] OBJ_ansi_X9_62 */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01, /* [2954] OBJ_X9_62_prime_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02, /* [2961] OBJ_X9_62_characteristic_two_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, /* [2968] OBJ_X9_62_id_ecPublicKey */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01, /* [2975] OBJ_X9_62_prime192v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02, /* [2983] OBJ_X9_62_prime192v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03, /* [2991] OBJ_X9_62_prime192v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04, /* [2999] OBJ_X9_62_prime239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05, /* [3007] OBJ_X9_62_prime239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06, /* [3015] OBJ_X9_62_prime239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07, /* [3023] OBJ_X9_62_prime256v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, /* [3031] OBJ_ecdsa_with_SHA1 */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */
+0x55,0x1D,0x17, /* [3155] OBJ_hold_instruction_code */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [3158] OBJ_hold_instruction_none */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [3165] OBJ_hold_instruction_call_issuer */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [3172] OBJ_hold_instruction_reject */
+0x09, /* [3179] OBJ_data */
+0x09,0x92,0x26, /* [3180] OBJ_pss */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C, /* [3183] OBJ_ucl */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64, /* [3190] OBJ_pilot */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */
+0x55,0x04,0x2D, /* [3844] OBJ_x500UniqueIdentifier */
+0x2B,0x06,0x01,0x07,0x01, /* [3847] OBJ_mime_mhs */
+0x2B,0x06,0x01,0x07,0x01,0x01, /* [3852] OBJ_mime_mhs_headings */
+0x2B,0x06,0x01,0x07,0x01,0x02, /* [3858] OBJ_mime_mhs_bodies */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x01, /* [3864] OBJ_id_hex_partial_message */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x02, /* [3871] OBJ_id_hex_multipart_message */
+0x55,0x04,0x2C, /* [3878] OBJ_generationQualifier */
+0x55,0x04,0x41, /* [3881] OBJ_pseudonym */
+0x67,0x2A, /* [3884] OBJ_id_set */
+0x67,0x2A,0x00, /* [3886] OBJ_set_ctype */
+0x67,0x2A,0x01, /* [3889] OBJ_set_msgExt */
+0x67,0x2A,0x03, /* [3892] OBJ_set_attr */
+0x67,0x2A,0x05, /* [3895] OBJ_set_policy */
+0x67,0x2A,0x07, /* [3898] OBJ_set_certExt */
+0x67,0x2A,0x08, /* [3901] OBJ_set_brand */
+0x67,0x2A,0x00,0x00, /* [3904] OBJ_setct_PANData */
+0x67,0x2A,0x00,0x01, /* [3908] OBJ_setct_PANToken */
+0x67,0x2A,0x00,0x02, /* [3912] OBJ_setct_PANOnly */
+0x67,0x2A,0x00,0x03, /* [3916] OBJ_setct_OIData */
+0x67,0x2A,0x00,0x04, /* [3920] OBJ_setct_PI */
+0x67,0x2A,0x00,0x05, /* [3924] OBJ_setct_PIData */
+0x67,0x2A,0x00,0x06, /* [3928] OBJ_setct_PIDataUnsigned */
+0x67,0x2A,0x00,0x07, /* [3932] OBJ_setct_HODInput */
+0x67,0x2A,0x00,0x08, /* [3936] OBJ_setct_AuthResBaggage */
+0x67,0x2A,0x00,0x09, /* [3940] OBJ_setct_AuthRevReqBaggage */
+0x67,0x2A,0x00,0x0A, /* [3944] OBJ_setct_AuthRevResBaggage */
+0x67,0x2A,0x00,0x0B, /* [3948] OBJ_setct_CapTokenSeq */
+0x67,0x2A,0x00,0x0C, /* [3952] OBJ_setct_PInitResData */
+0x67,0x2A,0x00,0x0D, /* [3956] OBJ_setct_PI_TBS */
+0x67,0x2A,0x00,0x0E, /* [3960] OBJ_setct_PResData */
+0x67,0x2A,0x00,0x10, /* [3964] OBJ_setct_AuthReqTBS */
+0x67,0x2A,0x00,0x11, /* [3968] OBJ_setct_AuthResTBS */
+0x67,0x2A,0x00,0x12, /* [3972] OBJ_setct_AuthResTBSX */
+0x67,0x2A,0x00,0x13, /* [3976] OBJ_setct_AuthTokenTBS */
+0x67,0x2A,0x00,0x14, /* [3980] OBJ_setct_CapTokenData */
+0x67,0x2A,0x00,0x15, /* [3984] OBJ_setct_CapTokenTBS */
+0x67,0x2A,0x00,0x16, /* [3988] OBJ_setct_AcqCardCodeMsg */
+0x67,0x2A,0x00,0x17, /* [3992] OBJ_setct_AuthRevReqTBS */
+0x67,0x2A,0x00,0x18, /* [3996] OBJ_setct_AuthRevResData */
+0x67,0x2A,0x00,0x19, /* [4000] OBJ_setct_AuthRevResTBS */
+0x67,0x2A,0x00,0x1A, /* [4004] OBJ_setct_CapReqTBS */
+0x67,0x2A,0x00,0x1B, /* [4008] OBJ_setct_CapReqTBSX */
+0x67,0x2A,0x00,0x1C, /* [4012] OBJ_setct_CapResData */
+0x67,0x2A,0x00,0x1D, /* [4016] OBJ_setct_CapRevReqTBS */
+0x67,0x2A,0x00,0x1E, /* [4020] OBJ_setct_CapRevReqTBSX */
+0x67,0x2A,0x00,0x1F, /* [4024] OBJ_setct_CapRevResData */
+0x67,0x2A,0x00,0x20, /* [4028] OBJ_setct_CredReqTBS */
+0x67,0x2A,0x00,0x21, /* [4032] OBJ_setct_CredReqTBSX */
+0x67,0x2A,0x00,0x22, /* [4036] OBJ_setct_CredResData */
+0x67,0x2A,0x00,0x23, /* [4040] OBJ_setct_CredRevReqTBS */
+0x67,0x2A,0x00,0x24, /* [4044] OBJ_setct_CredRevReqTBSX */
+0x67,0x2A,0x00,0x25, /* [4048] OBJ_setct_CredRevResData */
+0x67,0x2A,0x00,0x26, /* [4052] OBJ_setct_PCertReqData */
+0x67,0x2A,0x00,0x27, /* [4056] OBJ_setct_PCertResTBS */
+0x67,0x2A,0x00,0x28, /* [4060] OBJ_setct_BatchAdminReqData */
+0x67,0x2A,0x00,0x29, /* [4064] OBJ_setct_BatchAdminResData */
+0x67,0x2A,0x00,0x2A, /* [4068] OBJ_setct_CardCInitResTBS */
+0x67,0x2A,0x00,0x2B, /* [4072] OBJ_setct_MeAqCInitResTBS */
+0x67,0x2A,0x00,0x2C, /* [4076] OBJ_setct_RegFormResTBS */
+0x67,0x2A,0x00,0x2D, /* [4080] OBJ_setct_CertReqData */
+0x67,0x2A,0x00,0x2E, /* [4084] OBJ_setct_CertReqTBS */
+0x67,0x2A,0x00,0x2F, /* [4088] OBJ_setct_CertResData */
+0x67,0x2A,0x00,0x30, /* [4092] OBJ_setct_CertInqReqTBS */
+0x67,0x2A,0x00,0x31, /* [4096] OBJ_setct_ErrorTBS */
+0x67,0x2A,0x00,0x32, /* [4100] OBJ_setct_PIDualSignedTBE */
+0x67,0x2A,0x00,0x33, /* [4104] OBJ_setct_PIUnsignedTBE */
+0x67,0x2A,0x00,0x34, /* [4108] OBJ_setct_AuthReqTBE */
+0x67,0x2A,0x00,0x35, /* [4112] OBJ_setct_AuthResTBE */
+0x67,0x2A,0x00,0x36, /* [4116] OBJ_setct_AuthResTBEX */
+0x67,0x2A,0x00,0x37, /* [4120] OBJ_setct_AuthTokenTBE */
+0x67,0x2A,0x00,0x38, /* [4124] OBJ_setct_CapTokenTBE */
+0x67,0x2A,0x00,0x39, /* [4128] OBJ_setct_CapTokenTBEX */
+0x67,0x2A,0x00,0x3A, /* [4132] OBJ_setct_AcqCardCodeMsgTBE */
+0x67,0x2A,0x00,0x3B, /* [4136] OBJ_setct_AuthRevReqTBE */
+0x67,0x2A,0x00,0x3C, /* [4140] OBJ_setct_AuthRevResTBE */
+0x67,0x2A,0x00,0x3D, /* [4144] OBJ_setct_AuthRevResTBEB */
+0x67,0x2A,0x00,0x3E, /* [4148] OBJ_setct_CapReqTBE */
+0x67,0x2A,0x00,0x3F, /* [4152] OBJ_setct_CapReqTBEX */
+0x67,0x2A,0x00,0x40, /* [4156] OBJ_setct_CapResTBE */
+0x67,0x2A,0x00,0x41, /* [4160] OBJ_setct_CapRevReqTBE */
+0x67,0x2A,0x00,0x42, /* [4164] OBJ_setct_CapRevReqTBEX */
+0x67,0x2A,0x00,0x43, /* [4168] OBJ_setct_CapRevResTBE */
+0x67,0x2A,0x00,0x44, /* [4172] OBJ_setct_CredReqTBE */
+0x67,0x2A,0x00,0x45, /* [4176] OBJ_setct_CredReqTBEX */
+0x67,0x2A,0x00,0x46, /* [4180] OBJ_setct_CredResTBE */
+0x67,0x2A,0x00,0x47, /* [4184] OBJ_setct_CredRevReqTBE */
+0x67,0x2A,0x00,0x48, /* [4188] OBJ_setct_CredRevReqTBEX */
+0x67,0x2A,0x00,0x49, /* [4192] OBJ_setct_CredRevResTBE */
+0x67,0x2A,0x00,0x4A, /* [4196] OBJ_setct_BatchAdminReqTBE */
+0x67,0x2A,0x00,0x4B, /* [4200] OBJ_setct_BatchAdminResTBE */
+0x67,0x2A,0x00,0x4C, /* [4204] OBJ_setct_RegFormReqTBE */
+0x67,0x2A,0x00,0x4D, /* [4208] OBJ_setct_CertReqTBE */
+0x67,0x2A,0x00,0x4E, /* [4212] OBJ_setct_CertReqTBEX */
+0x67,0x2A,0x00,0x4F, /* [4216] OBJ_setct_CertResTBE */
+0x67,0x2A,0x00,0x50, /* [4220] OBJ_setct_CRLNotificationTBS */
+0x67,0x2A,0x00,0x51, /* [4224] OBJ_setct_CRLNotificationResTBS */
+0x67,0x2A,0x00,0x52, /* [4228] OBJ_setct_BCIDistributionTBS */
+0x67,0x2A,0x01,0x01, /* [4232] OBJ_setext_genCrypt */
+0x67,0x2A,0x01,0x03, /* [4236] OBJ_setext_miAuth */
+0x67,0x2A,0x01,0x04, /* [4240] OBJ_setext_pinSecure */
+0x67,0x2A,0x01,0x05, /* [4244] OBJ_setext_pinAny */
+0x67,0x2A,0x01,0x07, /* [4248] OBJ_setext_track2 */
+0x67,0x2A,0x01,0x08, /* [4252] OBJ_setext_cv */
+0x67,0x2A,0x05,0x00, /* [4256] OBJ_set_policy_root */
+0x67,0x2A,0x07,0x00, /* [4260] OBJ_setCext_hashedRoot */
+0x67,0x2A,0x07,0x01, /* [4264] OBJ_setCext_certType */
+0x67,0x2A,0x07,0x02, /* [4268] OBJ_setCext_merchData */
+0x67,0x2A,0x07,0x03, /* [4272] OBJ_setCext_cCertRequired */
+0x67,0x2A,0x07,0x04, /* [4276] OBJ_setCext_tunneling */
+0x67,0x2A,0x07,0x05, /* [4280] OBJ_setCext_setExt */
+0x67,0x2A,0x07,0x06, /* [4284] OBJ_setCext_setQualf */
+0x67,0x2A,0x07,0x07, /* [4288] OBJ_setCext_PGWYcapabilities */
+0x67,0x2A,0x07,0x08, /* [4292] OBJ_setCext_TokenIdentifier */
+0x67,0x2A,0x07,0x09, /* [4296] OBJ_setCext_Track2Data */
+0x67,0x2A,0x07,0x0A, /* [4300] OBJ_setCext_TokenType */
+0x67,0x2A,0x07,0x0B, /* [4304] OBJ_setCext_IssuerCapabilities */
+0x67,0x2A,0x03,0x00, /* [4308] OBJ_setAttr_Cert */
+0x67,0x2A,0x03,0x01, /* [4312] OBJ_setAttr_PGWYcap */
+0x67,0x2A,0x03,0x02, /* [4316] OBJ_setAttr_TokenType */
+0x67,0x2A,0x03,0x03, /* [4320] OBJ_setAttr_IssCap */
+0x67,0x2A,0x03,0x00,0x00, /* [4324] OBJ_set_rootKeyThumb */
+0x67,0x2A,0x03,0x00,0x01, /* [4329] OBJ_set_addPolicy */
+0x67,0x2A,0x03,0x02,0x01, /* [4334] OBJ_setAttr_Token_EMV */
+0x67,0x2A,0x03,0x02,0x02, /* [4339] OBJ_setAttr_Token_B0Prime */
+0x67,0x2A,0x03,0x03,0x03, /* [4344] OBJ_setAttr_IssCap_CVM */
+0x67,0x2A,0x03,0x03,0x04, /* [4349] OBJ_setAttr_IssCap_T2 */
+0x67,0x2A,0x03,0x03,0x05, /* [4354] OBJ_setAttr_IssCap_Sig */
+0x67,0x2A,0x03,0x03,0x03,0x01, /* [4359] OBJ_setAttr_GenCryptgrm */
+0x67,0x2A,0x03,0x03,0x04,0x01, /* [4365] OBJ_setAttr_T2Enc */
+0x67,0x2A,0x03,0x03,0x04,0x02, /* [4371] OBJ_setAttr_T2cleartxt */
+0x67,0x2A,0x03,0x03,0x05,0x01, /* [4377] OBJ_setAttr_TokICCsig */
+0x67,0x2A,0x03,0x03,0x05,0x02, /* [4383] OBJ_setAttr_SecDevSig */
+0x67,0x2A,0x08,0x01, /* [4389] OBJ_set_brand_IATA_ATA */
+0x67,0x2A,0x08,0x1E, /* [4393] OBJ_set_brand_Diners */
+0x67,0x2A,0x08,0x22, /* [4397] OBJ_set_brand_AmericanExpress */
+0x67,0x2A,0x08,0x23, /* [4401] OBJ_set_brand_JCB */
+0x67,0x2A,0x08,0x04, /* [4405] OBJ_set_brand_Visa */
+0x67,0x2A,0x08,0x05, /* [4409] OBJ_set_brand_MasterCard */
+0x67,0x2A,0x08,0xAE,0x7B, /* [4413] OBJ_set_brand_Novus */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A, /* [4418] OBJ_des_cdmf */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */
+0x67, /* [4435] OBJ_international_organizations */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */
+0x55,0x04,0x09, /* [4456] OBJ_streetAddress */
+0x55,0x04,0x11, /* [4459] OBJ_postalCode */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15, /* [4462] OBJ_id_ppl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E, /* [4469] OBJ_proxyCertInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00, /* [4477] OBJ_id_ppl_anyLanguage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01, /* [4485] OBJ_id_ppl_inheritAll */
+0x55,0x1D,0x1E, /* [4493] OBJ_name_constraints */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02, /* [4496] OBJ_Independent */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */
+0x2B, /* [4576] OBJ_identified_organization */
+0x2B,0x81,0x04, /* [4577] OBJ_certicom_arc */
+0x67,0x2B, /* [4580] OBJ_wap */
+0x67,0x2B,0x01, /* [4582] OBJ_wap_wsg */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [4585] OBJ_X9_62_id_characteristic_two_basis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01, /* [4620] OBJ_X9_62_c2pnb163v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02, /* [4628] OBJ_X9_62_c2pnb163v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03, /* [4636] OBJ_X9_62_c2pnb163v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04, /* [4644] OBJ_X9_62_c2pnb176v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05, /* [4652] OBJ_X9_62_c2tnb191v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06, /* [4660] OBJ_X9_62_c2tnb191v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07, /* [4668] OBJ_X9_62_c2tnb191v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08, /* [4676] OBJ_X9_62_c2onb191v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09, /* [4684] OBJ_X9_62_c2onb191v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A, /* [4692] OBJ_X9_62_c2pnb208w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B, /* [4700] OBJ_X9_62_c2tnb239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C, /* [4708] OBJ_X9_62_c2tnb239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D, /* [4716] OBJ_X9_62_c2tnb239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E, /* [4724] OBJ_X9_62_c2onb239v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F, /* [4732] OBJ_X9_62_c2onb239v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10, /* [4740] OBJ_X9_62_c2pnb272w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11, /* [4748] OBJ_X9_62_c2pnb304w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12, /* [4756] OBJ_X9_62_c2tnb359v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13, /* [4764] OBJ_X9_62_c2pnb368w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14, /* [4772] OBJ_X9_62_c2tnb431r1 */
+0x2B,0x81,0x04,0x00,0x06, /* [4780] OBJ_secp112r1 */
+0x2B,0x81,0x04,0x00,0x07, /* [4785] OBJ_secp112r2 */
+0x2B,0x81,0x04,0x00,0x1C, /* [4790] OBJ_secp128r1 */
+0x2B,0x81,0x04,0x00,0x1D, /* [4795] OBJ_secp128r2 */
+0x2B,0x81,0x04,0x00,0x09, /* [4800] OBJ_secp160k1 */
+0x2B,0x81,0x04,0x00,0x08, /* [4805] OBJ_secp160r1 */
+0x2B,0x81,0x04,0x00,0x1E, /* [4810] OBJ_secp160r2 */
+0x2B,0x81,0x04,0x00,0x1F, /* [4815] OBJ_secp192k1 */
+0x2B,0x81,0x04,0x00,0x20, /* [4820] OBJ_secp224k1 */
+0x2B,0x81,0x04,0x00,0x21, /* [4825] OBJ_secp224r1 */
+0x2B,0x81,0x04,0x00,0x0A, /* [4830] OBJ_secp256k1 */
+0x2B,0x81,0x04,0x00,0x22, /* [4835] OBJ_secp384r1 */
+0x2B,0x81,0x04,0x00,0x23, /* [4840] OBJ_secp521r1 */
+0x2B,0x81,0x04,0x00,0x04, /* [4845] OBJ_sect113r1 */
+0x2B,0x81,0x04,0x00,0x05, /* [4850] OBJ_sect113r2 */
+0x2B,0x81,0x04,0x00,0x16, /* [4855] OBJ_sect131r1 */
+0x2B,0x81,0x04,0x00,0x17, /* [4860] OBJ_sect131r2 */
+0x2B,0x81,0x04,0x00,0x01, /* [4865] OBJ_sect163k1 */
+0x2B,0x81,0x04,0x00,0x02, /* [4870] OBJ_sect163r1 */
+0x2B,0x81,0x04,0x00,0x0F, /* [4875] OBJ_sect163r2 */
+0x2B,0x81,0x04,0x00,0x18, /* [4880] OBJ_sect193r1 */
+0x2B,0x81,0x04,0x00,0x19, /* [4885] OBJ_sect193r2 */
+0x2B,0x81,0x04,0x00,0x1A, /* [4890] OBJ_sect233k1 */
+0x2B,0x81,0x04,0x00,0x1B, /* [4895] OBJ_sect233r1 */
+0x2B,0x81,0x04,0x00,0x03, /* [4900] OBJ_sect239k1 */
+0x2B,0x81,0x04,0x00,0x10, /* [4905] OBJ_sect283k1 */
+0x2B,0x81,0x04,0x00,0x11, /* [4910] OBJ_sect283r1 */
+0x2B,0x81,0x04,0x00,0x24, /* [4915] OBJ_sect409k1 */
+0x2B,0x81,0x04,0x00,0x25, /* [4920] OBJ_sect409r1 */
+0x2B,0x81,0x04,0x00,0x26, /* [4925] OBJ_sect571k1 */
+0x2B,0x81,0x04,0x00,0x27, /* [4930] OBJ_sect571r1 */
+0x67,0x2B,0x01,0x04,0x01, /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */
+0x67,0x2B,0x01,0x04,0x03, /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */
+0x67,0x2B,0x01,0x04,0x04, /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */
+0x67,0x2B,0x01,0x04,0x05, /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */
+0x67,0x2B,0x01,0x04,0x06, /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */
+0x67,0x2B,0x01,0x04,0x07, /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */
+0x67,0x2B,0x01,0x04,0x08, /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */
+0x67,0x2B,0x01,0x04,0x09, /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */
+0x67,0x2B,0x01,0x04,0x0A, /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */
+0x67,0x2B,0x01,0x04,0x0B, /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */
+0x67,0x2B,0x01,0x04,0x0C, /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */
+0x55,0x1D,0x20,0x00, /* [4990] OBJ_any_policy */
+0x55,0x1D,0x21, /* [4994] OBJ_policy_mappings */
+0x55,0x1D,0x36, /* [4997] OBJ_inhibit_any_policy */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01, /* [5033] OBJ_camellia_128_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15, /* [5041] OBJ_camellia_192_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29, /* [5049] OBJ_camellia_256_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04, /* [5057] OBJ_camellia_128_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18, /* [5065] OBJ_camellia_192_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C, /* [5073] OBJ_camellia_256_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03, /* [5081] OBJ_camellia_128_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17, /* [5089] OBJ_camellia_192_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B, /* [5097] OBJ_camellia_256_ofb128 */
+0x55,0x1D,0x09, /* [5105] OBJ_subject_directory_attributes */
+0x55,0x1D,0x1C, /* [5108] OBJ_issuing_distribution_point */
+0x55,0x1D,0x1D, /* [5111] OBJ_certificate_issuer */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [5114] OBJ_kisa */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [5120] OBJ_seed_ecb */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [5128] OBJ_seed_cbc */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [5136] OBJ_seed_ofb128 */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [5144] OBJ_seed_cfb128 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01, /* [5152] OBJ_hmac_md5 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02, /* [5160] OBJ_hmac_sha1 */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10, /* [5186] OBJ_id_it_suppLangTags */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05, /* [5194] OBJ_caRepository */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02, /* [5251] OBJ_ecdsa_with_Recommended */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, /* [5258] OBJ_ecdsa_with_Specified */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01, /* [5265] OBJ_ecdsa_with_SHA224 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, /* [5273] OBJ_ecdsa_with_SHA256 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03, /* [5281] OBJ_ecdsa_with_SHA384 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04, /* [5289] OBJ_ecdsa_with_SHA512 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [5297] OBJ_hmacWithMD5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08, /* [5305] OBJ_hmacWithSHA224 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09, /* [5313] OBJ_hmacWithSHA256 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A, /* [5321] OBJ_hmacWithSHA384 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B, /* [5329] OBJ_hmacWithSHA512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */
+0x28,0xCF,0x06,0x03,0x00,0x37, /* [5355] OBJ_whirlpool */
+0x2A,0x85,0x03,0x02,0x02, /* [5361] OBJ_cryptopro */
+0x2A,0x85,0x03,0x02,0x09, /* [5366] OBJ_cryptocom */
+0x2A,0x85,0x03,0x02,0x02,0x03, /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x04, /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x09, /* [5383] OBJ_id_GostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x0A, /* [5389] OBJ_id_HMACGostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x13, /* [5395] OBJ_id_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x14, /* [5401] OBJ_id_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x15, /* [5407] OBJ_id_Gost28147_89 */
+0x2A,0x85,0x03,0x02,0x02,0x16, /* [5413] OBJ_id_Gost28147_89_MAC */
+0x2A,0x85,0x03,0x02,0x02,0x17, /* [5419] OBJ_id_GostR3411_94_prf */
+0x2A,0x85,0x03,0x02,0x02,0x62, /* [5425] OBJ_id_GostR3410_2001DH */
+0x2A,0x85,0x03,0x02,0x02,0x63, /* [5431] OBJ_id_GostR3410_94DH */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x01, /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x00, /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x00, /* [5451] OBJ_id_GostR3411_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x01, /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x00, /* [5465] OBJ_id_Gost28147_89_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x01, /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x02, /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x03, /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x04, /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x05, /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x06, /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x07, /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x00, /* [5521] OBJ_id_GostR3410_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x02, /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x03, /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x04, /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x05, /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x01, /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x02, /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x03, /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x00, /* [5577] OBJ_id_GostR3410_2001_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x01, /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x02, /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x03, /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x00, /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x01, /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x01, /* [5619] OBJ_id_GostR3410_94_a */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x02, /* [5626] OBJ_id_GostR3410_94_aBis */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x03, /* [5633] OBJ_id_GostR3410_94_b */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x04, /* [5640] OBJ_id_GostR3410_94_bBis */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01, /* [5647] OBJ_id_Gost28147_89_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03, /* [5655] OBJ_id_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04, /* [5663] OBJ_id_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */
+0x55,0x1D,0x2E, /* [5704] OBJ_freshest_crl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [5707] OBJ_id_on_permanentIdentifier */
+0x55,0x04,0x0E, /* [5715] OBJ_searchGuide */
+0x55,0x04,0x0F, /* [5718] OBJ_businessCategory */
+0x55,0x04,0x10, /* [5721] OBJ_postalAddress */
+0x55,0x04,0x12, /* [5724] OBJ_postOfficeBox */
+0x55,0x04,0x13, /* [5727] OBJ_physicalDeliveryOfficeName */
+0x55,0x04,0x14, /* [5730] OBJ_telephoneNumber */
+0x55,0x04,0x15, /* [5733] OBJ_telexNumber */
+0x55,0x04,0x16, /* [5736] OBJ_teletexTerminalIdentifier */
+0x55,0x04,0x17, /* [5739] OBJ_facsimileTelephoneNumber */
+0x55,0x04,0x18, /* [5742] OBJ_x121Address */
+0x55,0x04,0x19, /* [5745] OBJ_internationaliSDNNumber */
+0x55,0x04,0x1A, /* [5748] OBJ_registeredAddress */
+0x55,0x04,0x1B, /* [5751] OBJ_destinationIndicator */
+0x55,0x04,0x1C, /* [5754] OBJ_preferredDeliveryMethod */
+0x55,0x04,0x1D, /* [5757] OBJ_presentationAddress */
+0x55,0x04,0x1E, /* [5760] OBJ_supportedApplicationContext */
+0x55,0x04,0x1F, /* [5763] OBJ_member */
+0x55,0x04,0x20, /* [5766] OBJ_owner */
+0x55,0x04,0x21, /* [5769] OBJ_roleOccupant */
+0x55,0x04,0x22, /* [5772] OBJ_seeAlso */
+0x55,0x04,0x23, /* [5775] OBJ_userPassword */
+0x55,0x04,0x24, /* [5778] OBJ_userCertificate */
+0x55,0x04,0x25, /* [5781] OBJ_cACertificate */
+0x55,0x04,0x26, /* [5784] OBJ_authorityRevocationList */
+0x55,0x04,0x27, /* [5787] OBJ_certificateRevocationList */
+0x55,0x04,0x28, /* [5790] OBJ_crossCertificatePair */
+0x55,0x04,0x2F, /* [5793] OBJ_enhancedSearchGuide */
+0x55,0x04,0x30, /* [5796] OBJ_protocolInformation */
+0x55,0x04,0x31, /* [5799] OBJ_distinguishedName */
+0x55,0x04,0x32, /* [5802] OBJ_uniqueMember */
+0x55,0x04,0x33, /* [5805] OBJ_houseIdentifier */
+0x55,0x04,0x34, /* [5808] OBJ_supportedAlgorithms */
+0x55,0x04,0x35, /* [5811] OBJ_deltaRevocationList */
+0x55,0x04,0x36, /* [5814] OBJ_dmdName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */
+0x55,0x1D,0x25,0x00, /* [5942] OBJ_anyExtendedKeyUsage */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */
+0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01, /* [5973] OBJ_dhpublicnumber */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5980] OBJ_brainpoolP160r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5989] OBJ_brainpoolP160t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [5998] OBJ_brainpoolP192r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6007] OBJ_brainpoolP192t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6016] OBJ_brainpoolP224r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6025] OBJ_brainpoolP224t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6034] OBJ_brainpoolP256r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6043] OBJ_brainpoolP256t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6052] OBJ_brainpoolP320r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6061] OBJ_brainpoolP320t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6070] OBJ_brainpoolP384r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6079] OBJ_brainpoolP384t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6088] OBJ_brainpoolP512r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6097] OBJ_brainpoolP512t1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,/* [6106] OBJ_pSpecified */
+0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,/* [6115] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x00, /* [6124] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x01, /* [6130] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x02, /* [6136] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x03, /* [6142] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */
+0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,/* [6148] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x00, /* [6157] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x01, /* [6163] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x02, /* [6169] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x03, /* [6175] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */
+0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,/* [6181] OBJ_ct_precert_scts */
+0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03,/* [6191] OBJ_ct_precert_poison */
+0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04,/* [6201] OBJ_ct_precert_signer */
+0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05,/* [6211] OBJ_ct_cert_scts */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,/* [6221] OBJ_jurisdictionLocalityName */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,/* [6232] OBJ_jurisdictionStateOrProvinceName */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,/* [6243] OBJ_jurisdictionCountryName */
+};
+
+static const ASN1_OBJECT nid_objs[NUM_NID]={
+{"UNDEF","undefined",NID_undef,0,NULL,0},
+{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[0]),0},
+{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[6]),0},
+{"MD2","md2",NID_md2,8,&(lvalues[13]),0},
+{"MD5","md5",NID_md5,8,&(lvalues[21]),0},
+{"RC4","rc4",NID_rc4,8,&(lvalues[29]),0},
+{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[37]),0},
+{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9,
+ &(lvalues[46]),0},
+{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9,
+ &(lvalues[55]),0},
+{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9,
+ &(lvalues[64]),0},
+{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9,
+ &(lvalues[73]),0},
+{"X500","directory services (X.500)",NID_X500,1,&(lvalues[82]),0},
+{"X509","X509",NID_X509,2,&(lvalues[83]),0},
+{"CN","commonName",NID_commonName,3,&(lvalues[85]),0},
+{"C","countryName",NID_countryName,3,&(lvalues[88]),0},
+{"L","localityName",NID_localityName,3,&(lvalues[91]),0},
+{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[94]),0},
+{"O","organizationName",NID_organizationName,3,&(lvalues[97]),0},
+{"OU","organizationalUnitName",NID_organizationalUnitName,3,
+ &(lvalues[100]),0},
+{"RSA","rsa",NID_rsa,4,&(lvalues[103]),0},
+{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[107]),0},
+{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[115]),0},
+{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9,
+ &(lvalues[124]),0},
+{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9,
+ &(lvalues[133]),0},
+{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData",
+ NID_pkcs7_signedAndEnveloped,9,&(lvalues[142]),0},
+{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9,
+ &(lvalues[151]),0},
+{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9,
+ &(lvalues[160]),0},
+{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[169]),0},
+{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9,
+ &(lvalues[177]),0},
+{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[186]),0},
+{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[191]),0},
+{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[196]),0},
+{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[201]),0},
+{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0},
+{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[206]),0},
+{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0},
+{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0},
+{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[217]),0},
+{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0},
+{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0},
+{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0},
+{"SHA","sha",NID_sha,5,&(lvalues[225]),0},
+{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5,
+ &(lvalues[230]),0},
+{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0},
+{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[235]),0},
+{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[243]),0},
+{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0},
+{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[248]),0},
+{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9,
+ &(lvalues[256]),0},
+{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9,
+ &(lvalues[265]),0},
+{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[274]),0},
+{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9,
+ &(lvalues[283]),0},
+{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[292]),0},
+{"countersignature","countersignature",NID_pkcs9_countersignature,9,
+ &(lvalues[301]),0},
+{"challengePassword","challengePassword",NID_pkcs9_challengePassword,
+ 9,&(lvalues[310]),0},
+{"unstructuredAddress","unstructuredAddress",
+ NID_pkcs9_unstructuredAddress,9,&(lvalues[319]),0},
+{"extendedCertificateAttributes","extendedCertificateAttributes",
+ NID_pkcs9_extCertAttributes,9,&(lvalues[328]),0},
+{"Netscape","Netscape Communications Corp.",NID_netscape,7,
+ &(lvalues[337]),0},
+{"nsCertExt","Netscape Certificate Extension",
+ NID_netscape_cert_extension,8,&(lvalues[344]),0},
+{"nsDataType","Netscape Data Type",NID_netscape_data_type,8,
+ &(lvalues[352]),0},
+{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0},
+{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0},
+{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0},
+{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0},
+{"SHA1","sha1",NID_sha1,5,&(lvalues[360]),0},
+{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9,
+ &(lvalues[365]),0},
+{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[374]),0},
+{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[379]),0},
+{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC,
+ 9,&(lvalues[384]),0},
+{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[393]),0},
+{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[402]),0},
+{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9,
+ &(lvalues[407]),0},
+{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9,
+ &(lvalues[416]),0},
+{"nsRevocationUrl","Netscape Revocation Url",
+ NID_netscape_revocation_url,9,&(lvalues[425]),0},
+{"nsCaRevocationUrl","Netscape CA Revocation Url",
+ NID_netscape_ca_revocation_url,9,&(lvalues[434]),0},
+{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9,
+ &(lvalues[443]),0},
+{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url,
+ 9,&(lvalues[452]),0},
+{"nsSslServerName","Netscape SSL Server Name",
+ NID_netscape_ssl_server_name,9,&(lvalues[461]),0},
+{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[470]),0},
+{"nsCertSequence","Netscape Certificate Sequence",
+ NID_netscape_cert_sequence,9,&(lvalues[479]),0},
+{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0},
+{"id-ce","id-ce",NID_id_ce,2,&(lvalues[488]),0},
+{"subjectKeyIdentifier","X509v3 Subject Key Identifier",
+ NID_subject_key_identifier,3,&(lvalues[490]),0},
+{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[493]),0},
+{"privateKeyUsagePeriod","X509v3 Private Key Usage Period",
+ NID_private_key_usage_period,3,&(lvalues[496]),0},
+{"subjectAltName","X509v3 Subject Alternative Name",
+ NID_subject_alt_name,3,&(lvalues[499]),0},
+{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name,
+ 3,&(lvalues[502]),0},
+{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints,
+ 3,&(lvalues[505]),0},
+{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[508]),0},
+{"certificatePolicies","X509v3 Certificate Policies",
+ NID_certificate_policies,3,&(lvalues[511]),0},
+{"authorityKeyIdentifier","X509v3 Authority Key Identifier",
+ NID_authority_key_identifier,3,&(lvalues[514]),0},
+{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[517]),0},
+{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0},
+{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0},
+{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0},
+{"MDC2","mdc2",NID_mdc2,4,&(lvalues[526]),0},
+{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[530]),0},
+{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0},
+{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0},
+{"GN","givenName",NID_givenName,3,&(lvalues[534]),0},
+{"SN","surname",NID_surname,3,&(lvalues[537]),0},
+{"initials","initials",NID_initials,3,&(lvalues[540]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"crlDistributionPoints","X509v3 CRL Distribution Points",
+ NID_crl_distribution_points,3,&(lvalues[543]),0},
+{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[546]),0},
+{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[551]),0},
+{"title","title",NID_title,3,&(lvalues[554]),0},
+{"description","description",NID_description,3,&(lvalues[557]),0},
+{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[560]),0},
+{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0},
+{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0},
+{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0},
+{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC",
+ NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[569]),0},
+{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[578]),0},
+{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0},
+{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[585]),0},
+{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[590]),0},
+{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[597]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6,
+ &(lvalues[602]),0},
+{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[608]),0},
+{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0},
+{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0},
+{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0},
+{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0},
+{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0},
+{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3,
+ &(lvalues[633]),0},
+{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0},
+{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0},
+{"serverAuth","TLS Web Server Authentication",NID_server_auth,8,
+ &(lvalues[649]),0},
+{"clientAuth","TLS Web Client Authentication",NID_client_auth,8,
+ &(lvalues[657]),0},
+{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0},
+{"emailProtection","E-mail Protection",NID_email_protect,8,
+ &(lvalues[673]),0},
+{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0},
+{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10,
+ &(lvalues[689]),0},
+{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10,
+ &(lvalues[699]),0},
+{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10,
+ &(lvalues[709]),0},
+{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0},
+{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10,
+ &(lvalues[729]),0},
+{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0},
+{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3,
+ &(lvalues[748]),0},
+{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0},
+{"invalidityDate","Invalidity Date",NID_invalidity_date,3,
+ &(lvalues[754]),0},
+{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0},
+{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4",
+ NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0},
+{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4",
+ NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0},
+{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC",
+ NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0},
+{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC",
+ NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0},
+{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC",
+ NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0},
+{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC",
+ NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0},
+{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0},
+{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag,
+ 11,&(lvalues[833]),0},
+{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0},
+{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0},
+{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0},
+{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11,
+ &(lvalues[877]),0},
+{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0},
+{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0},
+{"x509Certificate","x509Certificate",NID_x509Certificate,10,
+ &(lvalues[906]),0},
+{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10,
+ &(lvalues[916]),0},
+{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0},
+{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0},
+{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0},
+{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0},
+{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0},
+{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8,
+ &(lvalues[970]),0},
+{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0},
+{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9,
+ &(lvalues[978]),0},
+{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9,
+ &(lvalues[987]),0},
+{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9,
+ &(lvalues[996]),0},
+{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9,
+ &(lvalues[1005]),0},
+{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
+ &(lvalues[1014]),0},
+{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0},
+{"name","name",NID_name,3,&(lvalues[1033]),0},
+{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0},
+{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0},
+{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0},
+{"authorityInfoAccess","Authority Information Access",NID_info_access,
+ 8,&(lvalues[1053]),0},
+{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0},
+{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0},
+{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0},
+{"ISO","iso",NID_iso,0,NULL,0},
+{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0},
+{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0},
+{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0},
+{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0},
+{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0},
+{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0},
+{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0},
+{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0},
+{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0},
+{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0},
+{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0},
+{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0},
+{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0},
+{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0},
+{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11,
+ &(lvalues[1195]),0},
+{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11,
+ &(lvalues[1206]),0},
+{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11,
+ &(lvalues[1217]),0},
+{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3,
+ 11,&(lvalues[1228]),0},
+{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88",
+ NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0},
+{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97",
+ NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0},
+{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88",
+ NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0},
+{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97",
+ NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0},
+{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt,
+ 11,&(lvalues[1283]),0},
+{"id-smime-ct-authData","id-smime-ct-authData",
+ NID_id_smime_ct_authData,11,&(lvalues[1294]),0},
+{"id-smime-ct-publishCert","id-smime-ct-publishCert",
+ NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0},
+{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo,
+ 11,&(lvalues[1316]),0},
+{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo,
+ 11,&(lvalues[1327]),0},
+{"id-smime-ct-contentInfo","id-smime-ct-contentInfo",
+ NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0},
+{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData",
+ NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0},
+{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData",
+ NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0},
+{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest",
+ NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0},
+{"id-smime-aa-securityLabel","id-smime-aa-securityLabel",
+ NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0},
+{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory",
+ NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0},
+{"id-smime-aa-contentHint","id-smime-aa-contentHint",
+ NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0},
+{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest",
+ NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0},
+{"id-smime-aa-encapContentType","id-smime-aa-encapContentType",
+ NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0},
+{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier",
+ NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0},
+{"id-smime-aa-macValue","id-smime-aa-macValue",
+ NID_id_smime_aa_macValue,11,&(lvalues[1448]),0},
+{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels",
+ NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0},
+{"id-smime-aa-contentReference","id-smime-aa-contentReference",
+ NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0},
+{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref",
+ NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0},
+{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate",
+ NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0},
+{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts",
+ NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0},
+{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken",
+ NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0},
+{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId",
+ NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0},
+{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType",
+ NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0},
+{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation",
+ NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0},
+{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr",
+ NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0},
+{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert",
+ NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0},
+{"id-smime-aa-ets-contentTimestamp",
+ "id-smime-aa-ets-contentTimestamp",
+ NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0},
+{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs",
+ NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0},
+{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs",
+ NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0},
+{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues",
+ NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0},
+{"id-smime-aa-ets-revocationValues",
+ "id-smime-aa-ets-revocationValues",
+ NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0},
+{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp",
+ NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0},
+{"id-smime-aa-ets-certCRLTimestamp",
+ "id-smime-aa-ets-certCRLTimestamp",
+ NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0},
+{"id-smime-aa-ets-archiveTimeStamp",
+ "id-smime-aa-ets-archiveTimeStamp",
+ NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0},
+{"id-smime-aa-signatureType","id-smime-aa-signatureType",
+ NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0},
+{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc",
+ NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0},
+{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES",
+ NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0},
+{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2",
+ NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0},
+{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap",
+ NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0},
+{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap",
+ NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0},
+{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11,
+ &(lvalues[1734]),0},
+{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap",
+ NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0},
+{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap",
+ NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0},
+{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11,
+ &(lvalues[1767]),0},
+{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri",
+ NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0},
+{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice",
+ NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0},
+{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin",
+ NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0},
+{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt",
+ NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0},
+{"id-smime-cti-ets-proofOfDelivery",
+ "id-smime-cti-ets-proofOfDelivery",
+ NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0},
+{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender",
+ NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0},
+{"id-smime-cti-ets-proofOfApproval",
+ "id-smime-cti-ets-proofOfApproval",
+ NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0},
+{"id-smime-cti-ets-proofOfCreation",
+ "id-smime-cti-ets-proofOfCreation",
+ NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0},
+{"MD4","md4",NID_md4,8,&(lvalues[1866]),0},
+{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0},
+{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0},
+{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0},
+{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0},
+{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0},
+{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0},
+{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0},
+{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0},
+{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0},
+{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0},
+{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0},
+{"id-pkix1-explicit-88","id-pkix1-explicit-88",
+ NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0},
+{"id-pkix1-implicit-88","id-pkix1-implicit-88",
+ NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0},
+{"id-pkix1-explicit-93","id-pkix1-explicit-93",
+ NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0},
+{"id-pkix1-implicit-93","id-pkix1-implicit-93",
+ NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0},
+{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0},
+{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0},
+{"id-mod-kea-profile-88","id-mod-kea-profile-88",
+ NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0},
+{"id-mod-kea-profile-93","id-mod-kea-profile-93",
+ NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0},
+{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0},
+{"id-mod-qualified-cert-88","id-mod-qualified-cert-88",
+ NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0},
+{"id-mod-qualified-cert-93","id-mod-qualified-cert-93",
+ NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0},
+{"id-mod-attribute-cert","id-mod-attribute-cert",
+ NID_id_mod_attribute_cert,8,&(lvalues[2039]),0},
+{"id-mod-timestamp-protocol","id-mod-timestamp-protocol",
+ NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0},
+{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0},
+{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0},
+{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8,
+ &(lvalues[2071]),0},
+{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0},
+{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0},
+{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8,
+ &(lvalues[2095]),0},
+{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0},
+{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0},
+{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8,
+ &(lvalues[2119]),0},
+{"sbgp-autonomousSysNum","sbgp-autonomousSysNum",
+ NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0},
+{"sbgp-routerIdentifier","sbgp-routerIdentifier",
+ NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0},
+{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0},
+{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8,
+ &(lvalues[2151]),0},
+{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0},
+{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0},
+{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0},
+{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert,
+ 8,&(lvalues[2183]),0},
+{"id-it-signKeyPairTypes","id-it-signKeyPairTypes",
+ NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0},
+{"id-it-encKeyPairTypes","id-it-encKeyPairTypes",
+ NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0},
+{"id-it-preferredSymmAlg","id-it-preferredSymmAlg",
+ NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0},
+{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo",
+ NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0},
+{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8,
+ &(lvalues[2223]),0},
+{"id-it-unsupportedOIDs","id-it-unsupportedOIDs",
+ NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0},
+{"id-it-subscriptionRequest","id-it-subscriptionRequest",
+ NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0},
+{"id-it-subscriptionResponse","id-it-subscriptionResponse",
+ NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0},
+{"id-it-keyPairParamReq","id-it-keyPairParamReq",
+ NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0},
+{"id-it-keyPairParamRep","id-it-keyPairParamRep",
+ NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0},
+{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase,
+ 8,&(lvalues[2271]),0},
+{"id-it-implicitConfirm","id-it-implicitConfirm",
+ NID_id_it_implicitConfirm,8,&(lvalues[2279]),0},
+{"id-it-confirmWaitTime","id-it-confirmWaitTime",
+ NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0},
+{"id-it-origPKIMessage","id-it-origPKIMessage",
+ NID_id_it_origPKIMessage,8,&(lvalues[2295]),0},
+{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0},
+{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0},
+{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken,
+ 9,&(lvalues[2319]),0},
+{"id-regCtrl-authenticator","id-regCtrl-authenticator",
+ NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0},
+{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo",
+ NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0},
+{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions",
+ NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0},
+{"id-regCtrl-oldCertID","id-regCtrl-oldCertID",
+ NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0},
+{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey",
+ NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0},
+{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs",
+ NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0},
+{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9,
+ &(lvalues[2382]),0},
+{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0},
+{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8,
+ &(lvalues[2399]),0},
+{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1",
+ NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0},
+{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0},
+{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8,
+ &(lvalues[2423]),0},
+{"id-cmc-identification","id-cmc-identification",
+ NID_id_cmc_identification,8,&(lvalues[2431]),0},
+{"id-cmc-identityProof","id-cmc-identityProof",
+ NID_id_cmc_identityProof,8,&(lvalues[2439]),0},
+{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8,
+ &(lvalues[2447]),0},
+{"id-cmc-transactionId","id-cmc-transactionId",
+ NID_id_cmc_transactionId,8,&(lvalues[2455]),0},
+{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8,
+ &(lvalues[2463]),0},
+{"id-cmc-recipientNonce","id-cmc-recipientNonce",
+ NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0},
+{"id-cmc-addExtensions","id-cmc-addExtensions",
+ NID_id_cmc_addExtensions,8,&(lvalues[2479]),0},
+{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP,
+ 8,&(lvalues[2487]),0},
+{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP,
+ 8,&(lvalues[2495]),0},
+{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness",
+ NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0},
+{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8,
+ &(lvalues[2511]),0},
+{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0},
+{"id-cmc-revokeRequest","id-cmc-revokeRequest",
+ NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0},
+{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8,
+ &(lvalues[2535]),0},
+{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo,
+ 8,&(lvalues[2543]),0},
+{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending,
+ 8,&(lvalues[2551]),0},
+{"id-cmc-popLinkRandom","id-cmc-popLinkRandom",
+ NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0},
+{"id-cmc-popLinkWitness","id-cmc-popLinkWitness",
+ NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0},
+{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance",
+ NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0},
+{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8,
+ &(lvalues[2583]),0},
+{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8,
+ &(lvalues[2591]),0},
+{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth,
+ 8,&(lvalues[2599]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0},
+{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship",
+ NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0},
+{"id-pda-countryOfResidence","id-pda-countryOfResidence",
+ NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0},
+{"id-aca-authenticationInfo","id-aca-authenticationInfo",
+ NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0},
+{"id-aca-accessIdentity","id-aca-accessIdentity",
+ NID_id_aca_accessIdentity,8,&(lvalues[2639]),0},
+{"id-aca-chargingIdentity","id-aca-chargingIdentity",
+ NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0},
+{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0},
+{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0},
+{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1",
+ NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0},
+{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0},
+{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8,
+ &(lvalues[2687]),0},
+{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8,
+ &(lvalues[2695]),0},
+{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8,
+ &(lvalues[2703]),0},
+{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0},
+{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9,
+ &(lvalues[2719]),0},
+{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0},
+{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0},
+{"acceptableResponses","Acceptable OCSP Responses",
+ NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0},
+{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0},
+{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff,
+ 9,&(lvalues[2764]),0},
+{"serviceLocator","OCSP Service Locator",
+ NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0},
+{"extendedStatus","Extended OCSP Status",
+ NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0},
+{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0},
+{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0},
+{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9,
+ &(lvalues[2809]),0},
+{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0},
+{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0},
+{"X500algorithms","directory services - algorithms",
+ NID_X500algorithms,2,&(lvalues[2827]),0},
+{"ORG","org",NID_org,1,&(lvalues[2829]),0},
+{"DOD","dod",NID_dod,2,&(lvalues[2830]),0},
+{"IANA","iana",NID_iana,3,&(lvalues[2832]),0},
+{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0},
+{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0},
+{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0},
+{"private","Private",NID_Private,4,&(lvalues[2847]),0},
+{"security","Security",NID_Security,4,&(lvalues[2851]),0},
+{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0},
+{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0},
+{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0},
+{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0},
+{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0},
+{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0},
+{"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0},
+{"selected-attribute-types","Selected Attribute Types",
+ NID_selected_attribute_types,3,&(lvalues[2897]),0},
+{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0},
+{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9,
+ &(lvalues[2904]),0},
+{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0},
+{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8,
+ &(lvalues[2921]),0},
+{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8,
+ &(lvalues[2929]),0},
+{"role","role",NID_role,3,&(lvalues[2937]),0},
+{"policyConstraints","X509v3 Policy Constraints",
+ NID_policy_constraints,3,&(lvalues[2940]),0},
+{"targetInformation","X509v3 AC Targeting",NID_target_information,3,
+ &(lvalues[2943]),0},
+{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3,
+ &(lvalues[2946]),0},
+{"NULL","NULL",NID_ccitt,0,NULL,0},
+{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0},
+{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0},
+{"characteristic-two-field","characteristic-two-field",
+ NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0},
+{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7,
+ &(lvalues[2968]),0},
+{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0},
+{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0},
+{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0},
+{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0},
+{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0},
+{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0},
+{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0},
+{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7,
+ &(lvalues[3031]),0},
+{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0},
+{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0},
+{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0},
+{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0},
+{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0},
+{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0},
+{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0},
+{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0},
+{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0},
+{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0},
+{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0},
+{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0},
+{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0},
+{"holdInstructionCode","Hold Instruction Code",
+ NID_hold_instruction_code,3,&(lvalues[3155]),0},
+{"holdInstructionNone","Hold Instruction None",
+ NID_hold_instruction_none,7,&(lvalues[3158]),0},
+{"holdInstructionCallIssuer","Hold Instruction Call Issuer",
+ NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0},
+{"holdInstructionReject","Hold Instruction Reject",
+ NID_hold_instruction_reject,7,&(lvalues[3172]),0},
+{"data","data",NID_data,1,&(lvalues[3179]),0},
+{"pss","pss",NID_pss,3,&(lvalues[3180]),0},
+{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0},
+{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0},
+{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9,
+ &(lvalues[3198]),0},
+{"pilotAttributeSyntax","pilotAttributeSyntax",
+ NID_pilotAttributeSyntax,9,&(lvalues[3207]),0},
+{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9,
+ &(lvalues[3216]),0},
+{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0},
+{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10,
+ &(lvalues[3234]),0},
+{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax",
+ NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0},
+{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0},
+{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0},
+{"account","account",NID_account,10,&(lvalues[3274]),0},
+{"document","document",NID_document,10,&(lvalues[3284]),0},
+{"room","room",NID_room,10,&(lvalues[3294]),0},
+{"documentSeries","documentSeries",NID_documentSeries,10,
+ &(lvalues[3304]),0},
+{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10,
+ &(lvalues[3314]),0},
+{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0},
+{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject,
+ 10,&(lvalues[3334]),0},
+{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10,
+ &(lvalues[3344]),0},
+{"simpleSecurityObject","simpleSecurityObject",
+ NID_simpleSecurityObject,10,&(lvalues[3354]),0},
+{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10,
+ &(lvalues[3364]),0},
+{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0},
+{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData,
+ 10,&(lvalues[3384]),0},
+{"UID","userId",NID_userId,10,&(lvalues[3394]),0},
+{"textEncodedORAddress","textEncodedORAddress",
+ NID_textEncodedORAddress,10,&(lvalues[3404]),0},
+{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0},
+{"info","info",NID_info,10,&(lvalues[3424]),0},
+{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10,
+ &(lvalues[3434]),0},
+{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0},
+{"photo","photo",NID_photo,10,&(lvalues[3454]),0},
+{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0},
+{"host","host",NID_host,10,&(lvalues[3474]),0},
+{"manager","manager",NID_manager,10,&(lvalues[3484]),0},
+{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10,
+ &(lvalues[3494]),0},
+{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0},
+{"documentVersion","documentVersion",NID_documentVersion,10,
+ &(lvalues[3514]),0},
+{"documentAuthor","documentAuthor",NID_documentAuthor,10,
+ &(lvalues[3524]),0},
+{"documentLocation","documentLocation",NID_documentLocation,10,
+ &(lvalues[3534]),0},
+{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber,
+ 10,&(lvalues[3544]),0},
+{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0},
+{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0},
+{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10,
+ &(lvalues[3574]),0},
+{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10,
+ &(lvalues[3584]),0},
+{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0},
+{"pilotAttributeType27","pilotAttributeType27",
+ NID_pilotAttributeType27,10,&(lvalues[3604]),0},
+{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0},
+{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0},
+{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0},
+{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0},
+{"associatedDomain","associatedDomain",NID_associatedDomain,10,
+ &(lvalues[3654]),0},
+{"associatedName","associatedName",NID_associatedName,10,
+ &(lvalues[3664]),0},
+{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10,
+ &(lvalues[3674]),0},
+{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0},
+{"mobileTelephoneNumber","mobileTelephoneNumber",
+ NID_mobileTelephoneNumber,10,&(lvalues[3694]),0},
+{"pagerTelephoneNumber","pagerTelephoneNumber",
+ NID_pagerTelephoneNumber,10,&(lvalues[3704]),0},
+{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName,
+ 10,&(lvalues[3714]),0},
+{"organizationalStatus","organizationalStatus",
+ NID_organizationalStatus,10,&(lvalues[3724]),0},
+{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0},
+{"mailPreferenceOption","mailPreferenceOption",
+ NID_mailPreferenceOption,10,&(lvalues[3744]),0},
+{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0},
+{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0},
+{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10,
+ &(lvalues[3774]),0},
+{"subtreeMinimumQuality","subtreeMinimumQuality",
+ NID_subtreeMinimumQuality,10,&(lvalues[3784]),0},
+{"subtreeMaximumQuality","subtreeMaximumQuality",
+ NID_subtreeMaximumQuality,10,&(lvalues[3794]),0},
+{"personalSignature","personalSignature",NID_personalSignature,10,
+ &(lvalues[3804]),0},
+{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0},
+{"audio","audio",NID_audio,10,&(lvalues[3824]),0},
+{"documentPublisher","documentPublisher",NID_documentPublisher,10,
+ &(lvalues[3834]),0},
+{"x500UniqueIdentifier","x500UniqueIdentifier",
+ NID_x500UniqueIdentifier,3,&(lvalues[3844]),0},
+{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0},
+{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6,
+ &(lvalues[3852]),0},
+{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6,
+ &(lvalues[3858]),0},
+{"id-hex-partial-message","id-hex-partial-message",
+ NID_id_hex_partial_message,7,&(lvalues[3864]),0},
+{"id-hex-multipart-message","id-hex-multipart-message",
+ NID_id_hex_multipart_message,7,&(lvalues[3871]),0},
+{"generationQualifier","generationQualifier",NID_generationQualifier,
+ 3,&(lvalues[3878]),0},
+{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"id-set","Secure Electronic Transactions",NID_id_set,2,
+ &(lvalues[3884]),0},
+{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0},
+{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0},
+{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0},
+{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0},
+{"set-certExt","certificate extensions",NID_set_certExt,3,
+ &(lvalues[3898]),0},
+{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0},
+{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0},
+{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4,
+ &(lvalues[3908]),0},
+{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0},
+{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0},
+{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0},
+{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0},
+{"setct-PIDataUnsigned","setct-PIDataUnsigned",
+ NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0},
+{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4,
+ &(lvalues[3932]),0},
+{"setct-AuthResBaggage","setct-AuthResBaggage",
+ NID_setct_AuthResBaggage,4,&(lvalues[3936]),0},
+{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage",
+ NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0},
+{"setct-AuthRevResBaggage","setct-AuthRevResBaggage",
+ NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0},
+{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4,
+ &(lvalues[3948]),0},
+{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4,
+ &(lvalues[3952]),0},
+{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0},
+{"setct-PResData","setct-PResData",NID_setct_PResData,4,
+ &(lvalues[3960]),0},
+{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4,
+ &(lvalues[3964]),0},
+{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4,
+ &(lvalues[3968]),0},
+{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4,
+ &(lvalues[3972]),0},
+{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4,
+ &(lvalues[3976]),0},
+{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4,
+ &(lvalues[3980]),0},
+{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4,
+ &(lvalues[3984]),0},
+{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg",
+ NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0},
+{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS,
+ 4,&(lvalues[3992]),0},
+{"setct-AuthRevResData","setct-AuthRevResData",
+ NID_setct_AuthRevResData,4,&(lvalues[3996]),0},
+{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS,
+ 4,&(lvalues[4000]),0},
+{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4,
+ &(lvalues[4004]),0},
+{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4,
+ &(lvalues[4008]),0},
+{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4,
+ &(lvalues[4012]),0},
+{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4,
+ &(lvalues[4016]),0},
+{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX,
+ 4,&(lvalues[4020]),0},
+{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData,
+ 4,&(lvalues[4024]),0},
+{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4,
+ &(lvalues[4028]),0},
+{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4,
+ &(lvalues[4032]),0},
+{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4,
+ &(lvalues[4036]),0},
+{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS,
+ 4,&(lvalues[4040]),0},
+{"setct-CredRevReqTBSX","setct-CredRevReqTBSX",
+ NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0},
+{"setct-CredRevResData","setct-CredRevResData",
+ NID_setct_CredRevResData,4,&(lvalues[4048]),0},
+{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4,
+ &(lvalues[4052]),0},
+{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4,
+ &(lvalues[4056]),0},
+{"setct-BatchAdminReqData","setct-BatchAdminReqData",
+ NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0},
+{"setct-BatchAdminResData","setct-BatchAdminResData",
+ NID_setct_BatchAdminResData,4,&(lvalues[4064]),0},
+{"setct-CardCInitResTBS","setct-CardCInitResTBS",
+ NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0},
+{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS",
+ NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0},
+{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS,
+ 4,&(lvalues[4076]),0},
+{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4,
+ &(lvalues[4080]),0},
+{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4,
+ &(lvalues[4084]),0},
+{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4,
+ &(lvalues[4088]),0},
+{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS,
+ 4,&(lvalues[4092]),0},
+{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4,
+ &(lvalues[4096]),0},
+{"setct-PIDualSignedTBE","setct-PIDualSignedTBE",
+ NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0},
+{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE,
+ 4,&(lvalues[4104]),0},
+{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4,
+ &(lvalues[4108]),0},
+{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4,
+ &(lvalues[4112]),0},
+{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4,
+ &(lvalues[4116]),0},
+{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4,
+ &(lvalues[4120]),0},
+{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4,
+ &(lvalues[4124]),0},
+{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4,
+ &(lvalues[4128]),0},
+{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE",
+ NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0},
+{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE,
+ 4,&(lvalues[4136]),0},
+{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE,
+ 4,&(lvalues[4140]),0},
+{"setct-AuthRevResTBEB","setct-AuthRevResTBEB",
+ NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0},
+{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4,
+ &(lvalues[4148]),0},
+{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4,
+ &(lvalues[4152]),0},
+{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4,
+ &(lvalues[4156]),0},
+{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4,
+ &(lvalues[4160]),0},
+{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX,
+ 4,&(lvalues[4164]),0},
+{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4,
+ &(lvalues[4168]),0},
+{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4,
+ &(lvalues[4172]),0},
+{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4,
+ &(lvalues[4176]),0},
+{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4,
+ &(lvalues[4180]),0},
+{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE,
+ 4,&(lvalues[4184]),0},
+{"setct-CredRevReqTBEX","setct-CredRevReqTBEX",
+ NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0},
+{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE,
+ 4,&(lvalues[4192]),0},
+{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE",
+ NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0},
+{"setct-BatchAdminResTBE","setct-BatchAdminResTBE",
+ NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0},
+{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE,
+ 4,&(lvalues[4204]),0},
+{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4,
+ &(lvalues[4208]),0},
+{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4,
+ &(lvalues[4212]),0},
+{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4,
+ &(lvalues[4216]),0},
+{"setct-CRLNotificationTBS","setct-CRLNotificationTBS",
+ NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0},
+{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS",
+ NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0},
+{"setct-BCIDistributionTBS","setct-BCIDistributionTBS",
+ NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0},
+{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4,
+ &(lvalues[4232]),0},
+{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4,
+ &(lvalues[4236]),0},
+{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4,
+ &(lvalues[4240]),0},
+{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0},
+{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0},
+{"setext-cv","additional verification",NID_setext_cv,4,
+ &(lvalues[4252]),0},
+{"set-policy-root","set-policy-root",NID_set_policy_root,4,
+ &(lvalues[4256]),0},
+{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4,
+ &(lvalues[4260]),0},
+{"setCext-certType","setCext-certType",NID_setCext_certType,4,
+ &(lvalues[4264]),0},
+{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4,
+ &(lvalues[4268]),0},
+{"setCext-cCertRequired","setCext-cCertRequired",
+ NID_setCext_cCertRequired,4,&(lvalues[4272]),0},
+{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4,
+ &(lvalues[4276]),0},
+{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4,
+ &(lvalues[4280]),0},
+{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4,
+ &(lvalues[4284]),0},
+{"setCext-PGWYcapabilities","setCext-PGWYcapabilities",
+ NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0},
+{"setCext-TokenIdentifier","setCext-TokenIdentifier",
+ NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0},
+{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4,
+ &(lvalues[4296]),0},
+{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4,
+ &(lvalues[4300]),0},
+{"setCext-IssuerCapabilities","setCext-IssuerCapabilities",
+ NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0},
+{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0},
+{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap,
+ 4,&(lvalues[4312]),0},
+{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4,
+ &(lvalues[4316]),0},
+{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4,
+ &(lvalues[4320]),0},
+{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5,
+ &(lvalues[4324]),0},
+{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0},
+{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5,
+ &(lvalues[4334]),0},
+{"setAttr-Token-B0Prime","setAttr-Token-B0Prime",
+ NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0},
+{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5,
+ &(lvalues[4344]),0},
+{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5,
+ &(lvalues[4349]),0},
+{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5,
+ &(lvalues[4354]),0},
+{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm,
+ 6,&(lvalues[4359]),0},
+{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6,
+ &(lvalues[4365]),0},
+{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6,
+ &(lvalues[4371]),0},
+{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6,
+ &(lvalues[4377]),0},
+{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig,
+ 6,&(lvalues[4383]),0},
+{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4,
+ &(lvalues[4389]),0},
+{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4,
+ &(lvalues[4393]),0},
+{"set-brand-AmericanExpress","set-brand-AmericanExpress",
+ NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0},
+{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0},
+{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4,
+ &(lvalues[4405]),0},
+{"set-brand-MasterCard","set-brand-MasterCard",
+ NID_set_brand_MasterCard,4,&(lvalues[4409]),0},
+{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5,
+ &(lvalues[4413]),0},
+{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0},
+{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET",
+ NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0},
+{"ITU-T","itu-t",NID_itu_t,0,NULL,0},
+{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0},
+{"international-organizations","International Organizations",
+ NID_international_organizations,1,&(lvalues[4435]),0},
+{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login,
+ 10,&(lvalues[4436]),0},
+{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10,
+ &(lvalues[4446]),0},
+{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0},
+{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0},
+{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0},
+{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0},
+{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0},
+{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0},
+{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0},
+{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0},
+{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0},
+{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0},
+{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0},
+{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0},
+{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0},
+{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
+ &(lvalues[4469]),0},
+{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8,
+ &(lvalues[4477]),0},
+{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8,
+ &(lvalues[4485]),0},
+{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3,
+ &(lvalues[4493]),0},
+{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0},
+{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9,
+ &(lvalues[4504]),0},
+{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9,
+ &(lvalues[4513]),0},
+{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9,
+ &(lvalues[4522]),0},
+{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9,
+ &(lvalues[4531]),0},
+{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0},
+{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0},
+{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0},
+{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0},
+{"identified-organization","identified-organization",
+ NID_identified_organization,1,&(lvalues[4576]),0},
+{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0},
+{"wap","wap",NID_wap,2,&(lvalues[4580]),0},
+{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0},
+{"id-characteristic-two-basis","id-characteristic-two-basis",
+ NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0},
+{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0},
+{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0},
+{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0},
+{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0},
+{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0},
+{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0},
+{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0},
+{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0},
+{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0},
+{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0},
+{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0},
+{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0},
+{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0},
+{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0},
+{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0},
+{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0},
+{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0},
+{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0},
+{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0},
+{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0},
+{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0},
+{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0},
+{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0},
+{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0},
+{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0},
+{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0},
+{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0},
+{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0},
+{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0},
+{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0},
+{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0},
+{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0},
+{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0},
+{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0},
+{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0},
+{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0},
+{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0},
+{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0},
+{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0},
+{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0},
+{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0},
+{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0},
+{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0},
+{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0},
+{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0},
+{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0},
+{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0},
+{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0},
+{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0},
+{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0},
+{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0},
+{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0},
+{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0},
+{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0},
+{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1",
+ NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0},
+{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3",
+ NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0},
+{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4",
+ NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0},
+{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5",
+ NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0},
+{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6",
+ NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0},
+{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7",
+ NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0},
+{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8",
+ NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0},
+{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9",
+ NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0},
+{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10",
+ NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0},
+{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11",
+ NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0},
+{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12",
+ NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0},
+{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0},
+{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3,
+ &(lvalues[4994]),0},
+{"inhibitAnyPolicy","X509v3 Inhibit Any Policy",
+ NID_inhibit_any_policy,3,&(lvalues[4997]),0},
+{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0},
+{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0},
+{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11,
+ &(lvalues[5000]),0},
+{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11,
+ &(lvalues[5011]),0},
+{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11,
+ &(lvalues[5022]),0},
+{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8,
+ &(lvalues[5033]),0},
+{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8,
+ &(lvalues[5041]),0},
+{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8,
+ &(lvalues[5049]),0},
+{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8,
+ &(lvalues[5057]),0},
+{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8,
+ &(lvalues[5065]),0},
+{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8,
+ &(lvalues[5073]),0},
+{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0},
+{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0},
+{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0},
+{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0},
+{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0},
+{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0},
+{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8,
+ &(lvalues[5081]),0},
+{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8,
+ &(lvalues[5089]),0},
+{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8,
+ &(lvalues[5097]),0},
+{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes",
+ NID_subject_directory_attributes,3,&(lvalues[5105]),0},
+{"issuingDistributionPoint","X509v3 Issuing Distrubution Point",
+ NID_issuing_distribution_point,3,&(lvalues[5108]),0},
+{"certificateIssuer","X509v3 Certificate Issuer",
+ NID_certificate_issuer,3,&(lvalues[5111]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0},
+{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0},
+{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0},
+{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0},
+{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0},
+{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0},
+{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9,
+ &(lvalues[5168]),0},
+{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9,
+ &(lvalues[5177]),0},
+{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8,
+ &(lvalues[5186]),0},
+{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0},
+{"id-smime-ct-compressedData","id-smime-ct-compressedData",
+ NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0},
+{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF",
+ NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0},
+{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9,
+ &(lvalues[5224]),0},
+{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9,
+ &(lvalues[5233]),0},
+{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9,
+ &(lvalues[5242]),0},
+{"ecdsa-with-Recommended","ecdsa-with-Recommended",
+ NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0},
+{"ecdsa-with-Specified","ecdsa-with-Specified",
+ NID_ecdsa_with_Specified,7,&(lvalues[5258]),0},
+{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8,
+ &(lvalues[5265]),0},
+{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8,
+ &(lvalues[5273]),0},
+{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8,
+ &(lvalues[5281]),0},
+{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8,
+ &(lvalues[5289]),0},
+{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0},
+{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8,
+ &(lvalues[5305]),0},
+{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8,
+ &(lvalues[5313]),0},
+{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8,
+ &(lvalues[5321]),0},
+{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8,
+ &(lvalues[5329]),0},
+{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9,
+ &(lvalues[5337]),0},
+{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9,
+ &(lvalues[5346]),0},
+{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0},
+{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0},
+{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0},
+{"id-GostR3411-94-with-GostR3410-2001",
+ "GOST R 34.11-94 with GOST R 34.10-2001",
+ NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0},
+{"id-GostR3411-94-with-GostR3410-94",
+ "GOST R 34.11-94 with GOST R 34.10-94",
+ NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0},
+{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0},
+{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6,
+ &(lvalues[5389]),0},
+{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6,
+ &(lvalues[5395]),0},
+{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0},
+{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0},
+{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0},
+{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6,
+ &(lvalues[5413]),0},
+{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6,
+ &(lvalues[5419]),0},
+{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH,
+ 6,&(lvalues[5425]),0},
+{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6,
+ &(lvalues[5431]),0},
+{"id-Gost28147-89-CryptoPro-KeyMeshing",
+ "id-Gost28147-89-CryptoPro-KeyMeshing",
+ NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0},
+{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing",
+ NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0},
+{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet",
+ NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0},
+{"id-GostR3411-94-CryptoProParamSet",
+ "id-GostR3411-94-CryptoProParamSet",
+ NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0},
+{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet",
+ NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0},
+{"id-Gost28147-89-CryptoPro-A-ParamSet",
+ "id-Gost28147-89-CryptoPro-A-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0},
+{"id-Gost28147-89-CryptoPro-B-ParamSet",
+ "id-Gost28147-89-CryptoPro-B-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0},
+{"id-Gost28147-89-CryptoPro-C-ParamSet",
+ "id-Gost28147-89-CryptoPro-C-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0},
+{"id-Gost28147-89-CryptoPro-D-ParamSet",
+ "id-Gost28147-89-CryptoPro-D-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+ "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]),
+ 0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+ "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]),
+ 0},
+{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+ "id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+ NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0},
+{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet",
+ NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0},
+{"id-GostR3410-94-CryptoPro-A-ParamSet",
+ "id-GostR3410-94-CryptoPro-A-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0},
+{"id-GostR3410-94-CryptoPro-B-ParamSet",
+ "id-GostR3410-94-CryptoPro-B-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0},
+{"id-GostR3410-94-CryptoPro-C-ParamSet",
+ "id-GostR3410-94-CryptoPro-C-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0},
+{"id-GostR3410-94-CryptoPro-D-ParamSet",
+ "id-GostR3410-94-CryptoPro-D-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0},
+{"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+ "id-GostR3410-94-CryptoPro-XchA-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0},
+{"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+ "id-GostR3410-94-CryptoPro-XchB-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0},
+{"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+ "id-GostR3410-94-CryptoPro-XchC-ParamSet",
+ NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0},
+{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet",
+ NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0},
+{"id-GostR3410-2001-CryptoPro-A-ParamSet",
+ "id-GostR3410-2001-CryptoPro-A-ParamSet",
+ NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0},
+{"id-GostR3410-2001-CryptoPro-B-ParamSet",
+ "id-GostR3410-2001-CryptoPro-B-ParamSet",
+ NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0},
+{"id-GostR3410-2001-CryptoPro-C-ParamSet",
+ "id-GostR3410-2001-CryptoPro-C-ParamSet",
+ NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0},
+{"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+ "id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+ NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0},
+
+{"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+ "id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+ NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0},
+
+{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7,
+ &(lvalues[5619]),0},
+{"id-GostR3410-94-aBis","id-GostR3410-94-aBis",
+ NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0},
+{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7,
+ &(lvalues[5633]),0},
+{"id-GostR3410-94-bBis","id-GostR3410-94-bBis",
+ NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0},
+{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet",
+ NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0},
+{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8,
+ &(lvalues[5655]),0},
+{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8,
+ &(lvalues[5663]),0},
+{"id-GostR3411-94-with-GostR3410-94-cc",
+ "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom",
+ NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0},
+{"id-GostR3411-94-with-GostR3410-2001-cc",
+ "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom",
+ NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0},
+{"id-GostR3410-2001-ParamSet-cc",
+ "GOST R 3410-2001 Parameter Set Cryptocom",
+ NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0},
+{"HMAC","hmac",NID_hmac,0,NULL,0},
+{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
+ &(lvalues[5695]),0},
+{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3,
+ &(lvalues[5704]),0},
+{"id-on-permanentIdentifier","Permanent Identifier",
+ NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0},
+{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0},
+{"businessCategory","businessCategory",NID_businessCategory,3,
+ &(lvalues[5718]),0},
+{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0},
+{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0},
+{"physicalDeliveryOfficeName","physicalDeliveryOfficeName",
+ NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0},
+{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3,
+ &(lvalues[5730]),0},
+{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0},
+{"teletexTerminalIdentifier","teletexTerminalIdentifier",
+ NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0},
+{"facsimileTelephoneNumber","facsimileTelephoneNumber",
+ NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0},
+{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0},
+{"internationaliSDNNumber","internationaliSDNNumber",
+ NID_internationaliSDNNumber,3,&(lvalues[5745]),0},
+{"registeredAddress","registeredAddress",NID_registeredAddress,3,
+ &(lvalues[5748]),0},
+{"destinationIndicator","destinationIndicator",
+ NID_destinationIndicator,3,&(lvalues[5751]),0},
+{"preferredDeliveryMethod","preferredDeliveryMethod",
+ NID_preferredDeliveryMethod,3,&(lvalues[5754]),0},
+{"presentationAddress","presentationAddress",NID_presentationAddress,
+ 3,&(lvalues[5757]),0},
+{"supportedApplicationContext","supportedApplicationContext",
+ NID_supportedApplicationContext,3,&(lvalues[5760]),0},
+{"member","member",NID_member,3,&(lvalues[5763]),0},
+{"owner","owner",NID_owner,3,&(lvalues[5766]),0},
+{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0},
+{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0},
+{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0},
+{"userCertificate","userCertificate",NID_userCertificate,3,
+ &(lvalues[5778]),0},
+{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0},
+{"authorityRevocationList","authorityRevocationList",
+ NID_authorityRevocationList,3,&(lvalues[5784]),0},
+{"certificateRevocationList","certificateRevocationList",
+ NID_certificateRevocationList,3,&(lvalues[5787]),0},
+{"crossCertificatePair","crossCertificatePair",
+ NID_crossCertificatePair,3,&(lvalues[5790]),0},
+{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide,
+ 3,&(lvalues[5793]),0},
+{"protocolInformation","protocolInformation",NID_protocolInformation,
+ 3,&(lvalues[5796]),0},
+{"distinguishedName","distinguishedName",NID_distinguishedName,3,
+ &(lvalues[5799]),0},
+{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0},
+{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3,
+ &(lvalues[5805]),0},
+{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms,
+ 3,&(lvalues[5808]),0},
+{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
+ 3,&(lvalues[5811]),0},
+{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0},
+{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11,
+ &(lvalues[5817]),0},
+{"CMAC","cmac",NID_cmac,0,NULL,0},
+{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0},
+{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0},
+{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9,
+ &(lvalues[5846]),0},
+{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0},
+{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0},
+{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9,
+ &(lvalues[5873]),0},
+{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0},
+{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0},
+{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9,
+ &(lvalues[5900]),0},
+{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0},
+{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0},
+{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0},
+{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap,
+ 11,&(lvalues[5909]),0},
+{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap,
+ 11,&(lvalues[5920]),0},
+{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap,
+ 11,&(lvalues[5931]),0},
+{"anyExtendedKeyUsage","Any Extended Key Usage",
+ NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0},
+{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0},
+{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0},
+{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0},
+{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0},
+{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0},
+{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1",
+ NID_aes_128_cbc_hmac_sha1,0,NULL,0},
+{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1",
+ NID_aes_192_cbc_hmac_sha1,0,NULL,0},
+{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1",
+ NID_aes_256_cbc_hmac_sha1,0,NULL,0},
+{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0},
+{"dhpublicnumber","X9.42 DH",NID_dhpublicnumber,7,&(lvalues[5973]),0},
+{"brainpoolP160r1","brainpoolP160r1",NID_brainpoolP160r1,9,
+ &(lvalues[5980]),0},
+{"brainpoolP160t1","brainpoolP160t1",NID_brainpoolP160t1,9,
+ &(lvalues[5989]),0},
+{"brainpoolP192r1","brainpoolP192r1",NID_brainpoolP192r1,9,
+ &(lvalues[5998]),0},
+{"brainpoolP192t1","brainpoolP192t1",NID_brainpoolP192t1,9,
+ &(lvalues[6007]),0},
+{"brainpoolP224r1","brainpoolP224r1",NID_brainpoolP224r1,9,
+ &(lvalues[6016]),0},
+{"brainpoolP224t1","brainpoolP224t1",NID_brainpoolP224t1,9,
+ &(lvalues[6025]),0},
+{"brainpoolP256r1","brainpoolP256r1",NID_brainpoolP256r1,9,
+ &(lvalues[6034]),0},
+{"brainpoolP256t1","brainpoolP256t1",NID_brainpoolP256t1,9,
+ &(lvalues[6043]),0},
+{"brainpoolP320r1","brainpoolP320r1",NID_brainpoolP320r1,9,
+ &(lvalues[6052]),0},
+{"brainpoolP320t1","brainpoolP320t1",NID_brainpoolP320t1,9,
+ &(lvalues[6061]),0},
+{"brainpoolP384r1","brainpoolP384r1",NID_brainpoolP384r1,9,
+ &(lvalues[6070]),0},
+{"brainpoolP384t1","brainpoolP384t1",NID_brainpoolP384t1,9,
+ &(lvalues[6079]),0},
+{"brainpoolP512r1","brainpoolP512r1",NID_brainpoolP512r1,9,
+ &(lvalues[6088]),0},
+{"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9,
+ &(lvalues[6097]),0},
+{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6106]),0},
+{"dhSinglePass-stdDH-sha1kdf-scheme",
+ "dhSinglePass-stdDH-sha1kdf-scheme",
+ NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6115]),0},
+{"dhSinglePass-stdDH-sha224kdf-scheme",
+ "dhSinglePass-stdDH-sha224kdf-scheme",
+ NID_dhSinglePass_stdDH_sha224kdf_scheme,6,&(lvalues[6124]),0},
+{"dhSinglePass-stdDH-sha256kdf-scheme",
+ "dhSinglePass-stdDH-sha256kdf-scheme",
+ NID_dhSinglePass_stdDH_sha256kdf_scheme,6,&(lvalues[6130]),0},
+{"dhSinglePass-stdDH-sha384kdf-scheme",
+ "dhSinglePass-stdDH-sha384kdf-scheme",
+ NID_dhSinglePass_stdDH_sha384kdf_scheme,6,&(lvalues[6136]),0},
+{"dhSinglePass-stdDH-sha512kdf-scheme",
+ "dhSinglePass-stdDH-sha512kdf-scheme",
+ NID_dhSinglePass_stdDH_sha512kdf_scheme,6,&(lvalues[6142]),0},
+{"dhSinglePass-cofactorDH-sha1kdf-scheme",
+ "dhSinglePass-cofactorDH-sha1kdf-scheme",
+ NID_dhSinglePass_cofactorDH_sha1kdf_scheme,9,&(lvalues[6148]),0},
+{"dhSinglePass-cofactorDH-sha224kdf-scheme",
+ "dhSinglePass-cofactorDH-sha224kdf-scheme",
+ NID_dhSinglePass_cofactorDH_sha224kdf_scheme,6,&(lvalues[6157]),0},
+{"dhSinglePass-cofactorDH-sha256kdf-scheme",
+ "dhSinglePass-cofactorDH-sha256kdf-scheme",
+ NID_dhSinglePass_cofactorDH_sha256kdf_scheme,6,&(lvalues[6163]),0},
+{"dhSinglePass-cofactorDH-sha384kdf-scheme",
+ "dhSinglePass-cofactorDH-sha384kdf-scheme",
+ NID_dhSinglePass_cofactorDH_sha384kdf_scheme,6,&(lvalues[6169]),0},
+{"dhSinglePass-cofactorDH-sha512kdf-scheme",
+ "dhSinglePass-cofactorDH-sha512kdf-scheme",
+ NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6175]),0},
+{"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0},
+{"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0},
+{"AES-128-CBC-HMAC-SHA256","aes-128-cbc-hmac-sha256",
+ NID_aes_128_cbc_hmac_sha256,0,NULL,0},
+{"AES-192-CBC-HMAC-SHA256","aes-192-cbc-hmac-sha256",
+ NID_aes_192_cbc_hmac_sha256,0,NULL,0},
+{"AES-256-CBC-HMAC-SHA256","aes-256-cbc-hmac-sha256",
+ NID_aes_256_cbc_hmac_sha256,0,NULL,0},
+{"ct_precert_scts","CT Precertificate SCTs",NID_ct_precert_scts,10,
+ &(lvalues[6181]),0},
+{"ct_precert_poison","CT Precertificate Poison",NID_ct_precert_poison,
+ 10,&(lvalues[6191]),0},
+{"ct_precert_signer","CT Precertificate Signer",NID_ct_precert_signer,
+ 10,&(lvalues[6201]),0},
+{"ct_cert_scts","CT Certificate SCTs",NID_ct_cert_scts,10,
+ &(lvalues[6211]),0},
+{"jurisdictionL","jurisdictionLocalityName",
+ NID_jurisdictionLocalityName,11,&(lvalues[6221]),0},
+{"jurisdictionST","jurisdictionStateOrProvinceName",
+ NID_jurisdictionStateOrProvinceName,11,&(lvalues[6232]),0},
+{"jurisdictionC","jurisdictionCountryName",
+ NID_jurisdictionCountryName,11,&(lvalues[6243]),0},
+};
+
+static const unsigned int sn_objs[NUM_SN]={
+364, /* "AD_DVCS" */
+419, /* "AES-128-CBC" */
+916, /* "AES-128-CBC-HMAC-SHA1" */
+948, /* "AES-128-CBC-HMAC-SHA256" */
+421, /* "AES-128-CFB" */
+650, /* "AES-128-CFB1" */
+653, /* "AES-128-CFB8" */
+904, /* "AES-128-CTR" */
+418, /* "AES-128-ECB" */
+420, /* "AES-128-OFB" */
+913, /* "AES-128-XTS" */
+423, /* "AES-192-CBC" */
+917, /* "AES-192-CBC-HMAC-SHA1" */
+949, /* "AES-192-CBC-HMAC-SHA256" */
+425, /* "AES-192-CFB" */
+651, /* "AES-192-CFB1" */
+654, /* "AES-192-CFB8" */
+905, /* "AES-192-CTR" */
+422, /* "AES-192-ECB" */
+424, /* "AES-192-OFB" */
+427, /* "AES-256-CBC" */
+918, /* "AES-256-CBC-HMAC-SHA1" */
+950, /* "AES-256-CBC-HMAC-SHA256" */
+429, /* "AES-256-CFB" */
+652, /* "AES-256-CFB1" */
+655, /* "AES-256-CFB8" */
+906, /* "AES-256-CTR" */
+426, /* "AES-256-ECB" */
+428, /* "AES-256-OFB" */
+914, /* "AES-256-XTS" */
+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" */
+894, /* "CMAC" */
+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" */
+911, /* "MGF1" */
+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" */
+935, /* "PSPECIFIED" */
+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" */
+915, /* "RC4-HMAC-MD5" */
+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" */
+919, /* "RSAES-OAEP" */
+912, /* "RSASSA-PSS" */
+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" */
+910, /* "anyExtendedKeyUsage" */
+746, /* "anyPolicy" */
+370, /* "archiveCutoff" */
+484, /* "associatedDomain" */
+485, /* "associatedName" */
+501, /* "audio" */
+177, /* "authorityInfoAccess" */
+90, /* "authorityKeyIdentifier" */
+882, /* "authorityRevocationList" */
+87, /* "basicConstraints" */
+365, /* "basicOCSPResponse" */
+285, /* "biometricInfo" */
+921, /* "brainpoolP160r1" */
+922, /* "brainpoolP160t1" */
+923, /* "brainpoolP192r1" */
+924, /* "brainpoolP192t1" */
+925, /* "brainpoolP224r1" */
+926, /* "brainpoolP224t1" */
+927, /* "brainpoolP256r1" */
+928, /* "brainpoolP256t1" */
+929, /* "brainpoolP320r1" */
+930, /* "brainpoolP320t1" */
+931, /* "brainpoolP384r1" */
+932, /* "brainpoolP384t1" */
+933, /* "brainpoolP512r1" */
+934, /* "brainpoolP512t1" */
+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" */
+954, /* "ct_cert_scts" */
+952, /* "ct_precert_poison" */
+951, /* "ct_precert_scts" */
+953, /* "ct_precert_signer" */
+500, /* "dITRedirect" */
+451, /* "dNSDomain" */
+495, /* "dSAQuality" */
+434, /* "data" */
+390, /* "dcobject" */
+140, /* "deltaCRL" */
+891, /* "deltaRevocationList" */
+107, /* "description" */
+871, /* "destinationIndicator" */
+947, /* "dh-cofactor-kdf" */
+946, /* "dh-std-kdf" */
+28, /* "dhKeyAgreement" */
+941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
+942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
+943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
+944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
+945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
+936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */
+937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */
+938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */
+939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */
+940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */
+920, /* "dhpublicnumber" */
+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" */
+896, /* "id-aes128-CCM" */
+895, /* "id-aes128-GCM" */
+788, /* "id-aes128-wrap" */
+897, /* "id-aes128-wrap-pad" */
+899, /* "id-aes192-CCM" */
+898, /* "id-aes192-GCM" */
+789, /* "id-aes192-wrap" */
+900, /* "id-aes192-wrap-pad" */
+902, /* "id-aes256-CCM" */
+901, /* "id-aes256-GCM" */
+790, /* "id-aes256-wrap" */
+903, /* "id-aes256-wrap-pad" */
+262, /* "id-alg" */
+893, /* "id-alg-PWRI-KEK" */
+323, /* "id-alg-des40" */
+326, /* "id-alg-dh-pop" */
+325, /* "id-alg-dh-sig-hmac-sha1" */
+324, /* "id-alg-noSignature" */
+907, /* "id-camellia128-wrap" */
+908, /* "id-camellia192-wrap" */
+909, /* "id-camellia256-wrap" */
+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" */
+957, /* "jurisdictionC" */
+955, /* "jurisdictionL" */
+956, /* "jurisdictionST" */
+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 const unsigned int ln_objs[NUM_LN]={
+363, /* "AD Time Stamping" */
+405, /* "ANSI X9.62" */
+368, /* "Acceptable OCSP Responses" */
+910, /* "Any Extended Key Usage" */
+664, /* "Any language" */
+177, /* "Authority Information Access" */
+365, /* "Basic OCSP Response" */
+285, /* "Biometric Info" */
+179, /* "CA Issuers" */
+785, /* "CA Repository" */
+954, /* "CT Certificate SCTs" */
+952, /* "CT Precertificate Poison" */
+951, /* "CT Precertificate SCTs" */
+953, /* "CT Precertificate Signer" */
+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" */
+920, /* "X9.42 DH" */
+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" */
+916, /* "aes-128-cbc-hmac-sha1" */
+948, /* "aes-128-cbc-hmac-sha256" */
+896, /* "aes-128-ccm" */
+421, /* "aes-128-cfb" */
+650, /* "aes-128-cfb1" */
+653, /* "aes-128-cfb8" */
+904, /* "aes-128-ctr" */
+418, /* "aes-128-ecb" */
+895, /* "aes-128-gcm" */
+420, /* "aes-128-ofb" */
+913, /* "aes-128-xts" */
+423, /* "aes-192-cbc" */
+917, /* "aes-192-cbc-hmac-sha1" */
+949, /* "aes-192-cbc-hmac-sha256" */
+899, /* "aes-192-ccm" */
+425, /* "aes-192-cfb" */
+651, /* "aes-192-cfb1" */
+654, /* "aes-192-cfb8" */
+905, /* "aes-192-ctr" */
+422, /* "aes-192-ecb" */
+898, /* "aes-192-gcm" */
+424, /* "aes-192-ofb" */
+427, /* "aes-256-cbc" */
+918, /* "aes-256-cbc-hmac-sha1" */
+950, /* "aes-256-cbc-hmac-sha256" */
+902, /* "aes-256-ccm" */
+429, /* "aes-256-cfb" */
+652, /* "aes-256-cfb1" */
+655, /* "aes-256-cfb8" */
+906, /* "aes-256-ctr" */
+426, /* "aes-256-ecb" */
+901, /* "aes-256-gcm" */
+428, /* "aes-256-ofb" */
+914, /* "aes-256-xts" */
+376, /* "algorithm" */
+484, /* "associatedDomain" */
+485, /* "associatedName" */
+501, /* "audio" */
+882, /* "authorityRevocationList" */
+91, /* "bf-cbc" */
+93, /* "bf-cfb" */
+92, /* "bf-ecb" */
+94, /* "bf-ofb" */
+921, /* "brainpoolP160r1" */
+922, /* "brainpoolP160t1" */
+923, /* "brainpoolP192r1" */
+924, /* "brainpoolP192t1" */
+925, /* "brainpoolP224r1" */
+926, /* "brainpoolP224t1" */
+927, /* "brainpoolP256r1" */
+928, /* "brainpoolP256t1" */
+929, /* "brainpoolP320r1" */
+930, /* "brainpoolP320t1" */
+931, /* "brainpoolP384r1" */
+932, /* "brainpoolP384t1" */
+933, /* "brainpoolP512r1" */
+934, /* "brainpoolP512t1" */
+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" */
+894, /* "cmac" */
+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" */
+947, /* "dh-cofactor-kdf" */
+946, /* "dh-std-kdf" */
+28, /* "dhKeyAgreement" */
+941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
+942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
+943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
+944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
+945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
+936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */
+937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */
+938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */
+939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */
+940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */
+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" */
+897, /* "id-aes128-wrap-pad" */
+789, /* "id-aes192-wrap" */
+900, /* "id-aes192-wrap-pad" */
+790, /* "id-aes256-wrap" */
+903, /* "id-aes256-wrap-pad" */
+262, /* "id-alg" */
+893, /* "id-alg-PWRI-KEK" */
+323, /* "id-alg-des40" */
+326, /* "id-alg-dh-pop" */
+325, /* "id-alg-dh-sig-hmac-sha1" */
+324, /* "id-alg-noSignature" */
+907, /* "id-camellia128-wrap" */
+908, /* "id-camellia192-wrap" */
+909, /* "id-camellia256-wrap" */
+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" */
+957, /* "jurisdictionCountryName" */
+955, /* "jurisdictionLocalityName" */
+956, /* "jurisdictionStateOrProvinceName" */
+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" */
+911, /* "mgf1" */
+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" */
+935, /* "pSpecified" */
+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" */
+915, /* "rc4-hmac-md5" */
+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" */
+919, /* "rsaesOaep" */
+912, /* "rsassaPss" */
+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 const unsigned int obj_objs[NUM_OBJ]={
+ 0, /* OBJ_undef 0 */
+181, /* OBJ_iso 1 */
+393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */
+404, /* OBJ_ccitt OBJ_itu_t */
+645, /* OBJ_itu_t 0 */
+646, /* OBJ_joint_iso_itu_t 2 */
+434, /* OBJ_data 0 9 */
+182, /* OBJ_member_body 1 2 */
+379, /* OBJ_org 1 3 */
+676, /* OBJ_identified_organization 1 3 */
+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 */
+910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 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 */
+937, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */
+938, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */
+939, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */
+940, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */
+942, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */
+943, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */
+944, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */
+945, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */
+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 */
+920, /* OBJ_dhpublicnumber 1 2 840 10046 2 1 */
+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 */
+919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */
+911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */
+935, /* OBJ_pSpecified 1 2 840 113549 1 1 9 */
+912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */
+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 */
+921, /* OBJ_brainpoolP160r1 1 3 36 3 3 2 8 1 1 1 */
+922, /* OBJ_brainpoolP160t1 1 3 36 3 3 2 8 1 1 2 */
+923, /* OBJ_brainpoolP192r1 1 3 36 3 3 2 8 1 1 3 */
+924, /* OBJ_brainpoolP192t1 1 3 36 3 3 2 8 1 1 4 */
+925, /* OBJ_brainpoolP224r1 1 3 36 3 3 2 8 1 1 5 */
+926, /* OBJ_brainpoolP224t1 1 3 36 3 3 2 8 1 1 6 */
+927, /* OBJ_brainpoolP256r1 1 3 36 3 3 2 8 1 1 7 */
+928, /* OBJ_brainpoolP256t1 1 3 36 3 3 2 8 1 1 8 */
+929, /* OBJ_brainpoolP320r1 1 3 36 3 3 2 8 1 1 9 */
+930, /* OBJ_brainpoolP320t1 1 3 36 3 3 2 8 1 1 10 */
+931, /* OBJ_brainpoolP384r1 1 3 36 3 3 2 8 1 1 11 */
+932, /* OBJ_brainpoolP384t1 1 3 36 3 3 2 8 1 1 12 */
+933, /* OBJ_brainpoolP512r1 1 3 36 3 3 2 8 1 1 13 */
+934, /* OBJ_brainpoolP512t1 1 3 36 3 3 2 8 1 1 14 */
+936, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */
+941, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */
+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 */
+895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */
+896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */
+897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */
+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 */
+898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */
+899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */
+900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */
+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 */
+901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */
+902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */
+903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */
+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 */
+951, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */
+952, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */
+953, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */
+954, /* OBJ_ct_cert_scts 1 3 6 1 4 1 11129 2 4 5 */
+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 */
+907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */
+908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */
+909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 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 */
+893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */
+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 */
+955, /* OBJ_jurisdictionLocalityName 1 3 6 1 4 1 311 60 2 1 1 */
+956, /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */
+957, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */
+};
+
diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_err.c b/Cryptlib/OpenSSL/crypto/objects/obj_err.c
new file mode 100644
index 00000000..238aaa59
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_err.c
@@ -0,0 +1,100 @@
+/* crypto/objects/obj_err.c */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason)
+
+static ERR_STRING_DATA OBJ_str_functs[] = {
+ {ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT), "OBJ_add_object"},
+ {ERR_FUNC(OBJ_F_OBJ_CREATE), "OBJ_create"},
+ {ERR_FUNC(OBJ_F_OBJ_DUP), "OBJ_dup"},
+ {ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX), "OBJ_NAME_new_index"},
+ {ERR_FUNC(OBJ_F_OBJ_NID2LN), "OBJ_nid2ln"},
+ {ERR_FUNC(OBJ_F_OBJ_NID2OBJ), "OBJ_nid2obj"},
+ {ERR_FUNC(OBJ_F_OBJ_NID2SN), "OBJ_nid2sn"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA OBJ_str_reasons[] = {
+ {ERR_REASON(OBJ_R_MALLOC_FAILURE), "malloc failure"},
+ {ERR_REASON(OBJ_R_UNKNOWN_NID), "unknown nid"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_OBJ_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, OBJ_str_functs);
+ ERR_load_strings(0, OBJ_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_lib.c b/Cryptlib/OpenSSL/crypto/objects/obj_lib.c
new file mode 100644
index 00000000..8851baff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_lib.c
@@ -0,0 +1,135 @@
+/* crypto/objects/obj_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+
+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
+{
+ ASN1_OBJECT *r;
+ int i;
+ char *ln = NULL, *sn = NULL;
+ unsigned char *data = NULL;
+
+ if (o == NULL)
+ return (NULL);
+ if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
+ return ((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of duplication
+ * is this??? */
+
+ r = ASN1_OBJECT_new();
+ if (r == NULL) {
+ OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB);
+ return (NULL);
+ }
+ data = OPENSSL_malloc(o->length);
+ if (data == NULL)
+ goto err;
+ if (o->data != NULL)
+ 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;
+ ln = OPENSSL_malloc(i);
+ if (ln == NULL)
+ goto err;
+ memcpy(ln, o->ln, i);
+ r->ln = ln;
+ }
+
+ if (o->sn != NULL) {
+ i = strlen(o->sn) + 1;
+ 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 (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);
+}
+
+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
+{
+ int ret;
+
+ ret = (a->length - b->length);
+ if (ret)
+ return (ret);
+ return (memcmp(a->data, b->data, a->length));
+}
diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_xref.c b/Cryptlib/OpenSSL/crypto/objects/obj_xref.c
new file mode 100644
index 00000000..97b305d2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_xref.c
@@ -0,0 +1,222 @@
+/* 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 <openssl/objects.h>
+#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;
+ if (pdig_nid)
+ *pdig_nid = rv->hash_id;
+ if (ppkey_nid)
+ *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;
+ if (psignid)
+ *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/Cryptlib/OpenSSL/crypto/objects/obj_xref.h b/Cryptlib/OpenSSL/crypto/objects/obj_xref.h
new file mode 100644
index 00000000..e453e99f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/objects/obj_xref.h
@@ -0,0 +1,99 @@
+/* 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},
+ {NID_rsassaPss, NID_undef, NID_rsaEncryption},
+ {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf},
+ {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf},
+ {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf},
+ {NID_dhSinglePass_stdDH_sha384kdf_scheme, NID_sha384, NID_dh_std_kdf},
+ {NID_dhSinglePass_stdDH_sha512kdf_scheme, NID_sha512, NID_dh_std_kdf},
+ {NID_dhSinglePass_cofactorDH_sha1kdf_scheme, NID_sha1,
+ NID_dh_cofactor_kdf},
+ {NID_dhSinglePass_cofactorDH_sha224kdf_scheme, NID_sha224,
+ NID_dh_cofactor_kdf},
+ {NID_dhSinglePass_cofactorDH_sha256kdf_scheme, NID_sha256,
+ NID_dh_cofactor_kdf},
+ {NID_dhSinglePass_cofactorDH_sha384kdf_scheme, NID_sha384,
+ NID_dh_cofactor_kdf},
+ {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512,
+ NID_dh_cofactor_kdf},
+};
+
+static const nid_triple *const sigoid_srt_xref[] = {
+ &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[30],
+ &sigoid_srt[35],
+ &sigoid_srt[6],
+ &sigoid_srt[10],
+ &sigoid_srt[11],
+ &sigoid_srt[13],
+ &sigoid_srt[24],
+ &sigoid_srt[20],
+ &sigoid_srt[32],
+ &sigoid_srt[37],
+ &sigoid_srt[14],
+ &sigoid_srt[21],
+ &sigoid_srt[33],
+ &sigoid_srt[38],
+ &sigoid_srt[15],
+ &sigoid_srt[22],
+ &sigoid_srt[34],
+ &sigoid_srt[39],
+ &sigoid_srt[16],
+ &sigoid_srt[23],
+ &sigoid_srt[19],
+ &sigoid_srt[31],
+ &sigoid_srt[36],
+ &sigoid_srt[25],
+ &sigoid_srt[26],
+ &sigoid_srt[27],
+ &sigoid_srt[28],
+};
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_asn.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_asn.c
new file mode 100644
index 00000000..e2e52e77
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_asn.c
@@ -0,0 +1,183 @@
+/* ocsp_asn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/ocsp.h>
+
+ASN1_SEQUENCE(OCSP_SIGNATURE) = {
+ ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR),
+ ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING),
+ ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0)
+} ASN1_SEQUENCE_END(OCSP_SIGNATURE)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+
+ASN1_SEQUENCE(OCSP_CERTID) = {
+ ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR),
+ ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(OCSP_CERTID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID)
+
+ASN1_SEQUENCE(OCSP_ONEREQ) = {
+ ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID),
+ ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END(OCSP_ONEREQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ)
+
+ASN1_SEQUENCE(OCSP_REQINFO) = {
+ ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0),
+ ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1),
+ ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ),
+ ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2)
+} ASN1_SEQUENCE_END(OCSP_REQINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO)
+
+ASN1_SEQUENCE(OCSP_REQUEST) = {
+ ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO),
+ ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0)
+} ASN1_SEQUENCE_END(OCSP_REQUEST)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST)
+
+/* OCSP_RESPONSE templates */
+
+ASN1_SEQUENCE(OCSP_RESPBYTES) = {
+ ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT),
+ ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(OCSP_RESPBYTES)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+
+ASN1_SEQUENCE(OCSP_RESPONSE) = {
+ ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED),
+ ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0)
+} ASN1_SEQUENCE_END(OCSP_RESPONSE)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE)
+
+ASN1_CHOICE(OCSP_RESPID) = {
+ ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1),
+ ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2)
+} ASN1_CHOICE_END(OCSP_RESPID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID)
+
+ASN1_SEQUENCE(OCSP_REVOKEDINFO) = {
+ ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME),
+ ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0)
+} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+
+ASN1_CHOICE(OCSP_CERTSTATUS) = {
+ ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0),
+ ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1),
+ ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2)
+} ASN1_CHOICE_END(OCSP_CERTSTATUS)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+
+ASN1_SEQUENCE(OCSP_SINGLERESP) = {
+ ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID),
+ ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS),
+ ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME),
+ ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0),
+ ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(OCSP_SINGLERESP)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+
+ASN1_SEQUENCE(OCSP_RESPDATA) = {
+ ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0),
+ ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID),
+ ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME),
+ ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP),
+ ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(OCSP_RESPDATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA)
+
+ASN1_SEQUENCE(OCSP_BASICRESP) = {
+ ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA),
+ ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR),
+ ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING),
+ ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0)
+} ASN1_SEQUENCE_END(OCSP_BASICRESP)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP)
+
+ASN1_SEQUENCE(OCSP_CRLID) = {
+ ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0),
+ ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1),
+ ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2)
+} ASN1_SEQUENCE_END(OCSP_CRLID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID)
+
+ASN1_SEQUENCE(OCSP_SERVICELOC) = {
+ ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME),
+ ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION)
+} ASN1_SEQUENCE_END(OCSP_SERVICELOC)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC)
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_cl.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_cl.c
new file mode 100644
index 00000000..b3612c8d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_cl.c
@@ -0,0 +1,383 @@
+/* ocsp_cl.c */
+/*
+ * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project.
+ */
+
+/*
+ * History: This file was transfered to Richard Levitte from CertCo by Kathy
+ * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a
+ * patch kit.
+ */
+
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/*
+ * Utility functions related to sending OCSP requests and extracting relevant
+ * information from the response.
+ */
+
+/*
+ * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer:
+ * useful if we want to add extensions.
+ */
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
+{
+ OCSP_ONEREQ *one = NULL;
+
+ if (!(one = OCSP_ONEREQ_new()))
+ goto err;
+ if (one->reqCert)
+ OCSP_CERTID_free(one->reqCert);
+ one->reqCert = cid;
+ if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
+ goto err;
+ return one;
+ err:
+ OCSP_ONEREQ_free(one);
+ return NULL;
+}
+
+/* Set requestorName from an X509_NAME structure */
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
+{
+ GENERAL_NAME *gen;
+ gen = GENERAL_NAME_new();
+ if (gen == NULL)
+ return 0;
+ if (!X509_NAME_set(&gen->d.directoryName, nm)) {
+ GENERAL_NAME_free(gen);
+ return 0;
+ }
+ gen->type = GEN_DIRNAME;
+ if (req->tbsRequest->requestorName)
+ GENERAL_NAME_free(req->tbsRequest->requestorName);
+ req->tbsRequest->requestorName = gen;
+ return 1;
+}
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
+{
+ OCSP_SIGNATURE *sig;
+ if (!req->optionalSignature)
+ req->optionalSignature = OCSP_SIGNATURE_new();
+ sig = req->optionalSignature;
+ if (!sig)
+ return 0;
+ if (!cert)
+ return 1;
+ if (!sig->certs && !(sig->certs = sk_X509_new_null()))
+ return 0;
+
+ if (!sk_X509_push(sig->certs, cert))
+ return 0;
+ CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+ return 1;
+}
+
+/*
+ * Sign an OCSP request set the requestorName to the subjec name of an
+ * optional signers certificate and include one or more optional certificates
+ * in the request. Behaves like PKCS7_sign().
+ */
+
+int OCSP_request_sign(OCSP_REQUEST *req,
+ X509 *signer,
+ EVP_PKEY *key,
+ const EVP_MD *dgst,
+ STACK_OF(X509) *certs, unsigned long flags)
+{
+ int i;
+ OCSP_SIGNATURE *sig;
+ X509 *x;
+
+ if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
+ goto err;
+
+ if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new()))
+ goto err;
+ if (key) {
+ if (!X509_check_private_key(signer, key)) {
+ OCSPerr(OCSP_F_OCSP_REQUEST_SIGN,
+ OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+ goto err;
+ }
+ if (!OCSP_REQUEST_sign(req, key, dgst))
+ goto err;
+ }
+
+ if (!(flags & OCSP_NOCERTS)) {
+ if (!OCSP_request_add1_cert(req, signer))
+ goto err;
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ x = sk_X509_value(certs, i);
+ if (!OCSP_request_add1_cert(req, x))
+ goto err;
+ }
+ }
+
+ return 1;
+ err:
+ OCSP_SIGNATURE_free(req->optionalSignature);
+ req->optionalSignature = NULL;
+ return 0;
+}
+
+/* Get response status */
+
+int OCSP_response_status(OCSP_RESPONSE *resp)
+{
+ return ASN1_ENUMERATED_get(resp->responseStatus);
+}
+
+/*
+ * Extract basic response from OCSP_RESPONSE or NULL if no basic response
+ * present.
+ */
+
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
+{
+ OCSP_RESPBYTES *rb;
+ rb = resp->responseBytes;
+ if (!rb) {
+ OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
+ return NULL;
+ }
+ if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
+ OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
+ return NULL;
+ }
+
+ return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
+}
+
+/*
+ * Return number of OCSP_SINGLERESP reponses present in a basic response.
+ */
+
+int OCSP_resp_count(OCSP_BASICRESP *bs)
+{
+ if (!bs)
+ return -1;
+ return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
+}
+
+/* Extract an OCSP_SINGLERESP response with a given index */
+
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
+{
+ if (!bs)
+ return NULL;
+ return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
+}
+
+/* Look single response matching a given certificate ID */
+
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
+{
+ int i;
+ STACK_OF(OCSP_SINGLERESP) *sresp;
+ OCSP_SINGLERESP *single;
+ if (!bs)
+ return -1;
+ if (last < 0)
+ last = 0;
+ else
+ last++;
+ sresp = bs->tbsResponseData->responses;
+ for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
+ single = sk_OCSP_SINGLERESP_value(sresp, i);
+ if (!OCSP_id_cmp(id, single->certId))
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Extract status information from an OCSP_SINGLERESP structure. Note: the
+ * revtime and reason values are only set if the certificate status is
+ * revoked. Returns numerical value of status.
+ */
+
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+ ASN1_GENERALIZEDTIME **revtime,
+ ASN1_GENERALIZEDTIME **thisupd,
+ ASN1_GENERALIZEDTIME **nextupd)
+{
+ int ret;
+ OCSP_CERTSTATUS *cst;
+ if (!single)
+ return -1;
+ cst = single->certStatus;
+ ret = cst->type;
+ if (ret == V_OCSP_CERTSTATUS_REVOKED) {
+ OCSP_REVOKEDINFO *rev = cst->value.revoked;
+ if (revtime)
+ *revtime = rev->revocationTime;
+ if (reason) {
+ if (rev->revocationReason)
+ *reason = ASN1_ENUMERATED_get(rev->revocationReason);
+ else
+ *reason = -1;
+ }
+ }
+ if (thisupd)
+ *thisupd = single->thisUpdate;
+ if (nextupd)
+ *nextupd = single->nextUpdate;
+ return ret;
+}
+
+/*
+ * This function combines the previous ones: look up a certificate ID and if
+ * found extract status information. Return 0 is successful.
+ */
+
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+ int *reason,
+ ASN1_GENERALIZEDTIME **revtime,
+ ASN1_GENERALIZEDTIME **thisupd,
+ ASN1_GENERALIZEDTIME **nextupd)
+{
+ int i;
+ OCSP_SINGLERESP *single;
+ i = OCSP_resp_find(bs, id, -1);
+ /* Maybe check for multiple responses and give an error? */
+ if (i < 0)
+ return 0;
+ single = OCSP_resp_get0(bs, i);
+ i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
+ if (status)
+ *status = i;
+ return 1;
+}
+
+/*
+ * Check validity of thisUpdate and nextUpdate fields. It is possible that
+ * the request will take a few seconds to process and/or the time wont be
+ * totally accurate. Therefore to avoid rejecting otherwise valid time we
+ * allow the times to be within 'nsec' of the current time. Also to avoid
+ * accepting very old responses without a nextUpdate field an optional maxage
+ * parameter specifies the maximum age the thisUpdate field can be.
+ */
+
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+ ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
+{
+ int ret = 1;
+ time_t t_now, t_tmp;
+ time(&t_now);
+ /* Check thisUpdate is valid and not more than nsec in the future */
+ if (!ASN1_GENERALIZEDTIME_check(thisupd)) {
+ OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
+ ret = 0;
+ } else {
+ t_tmp = t_now + nsec;
+ if (X509_cmp_time(thisupd, &t_tmp) > 0) {
+ OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
+ ret = 0;
+ }
+
+ /*
+ * If maxsec specified check thisUpdate is not more than maxsec in
+ * the past
+ */
+ if (maxsec >= 0) {
+ t_tmp = t_now - maxsec;
+ if (X509_cmp_time(thisupd, &t_tmp) < 0) {
+ OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
+ ret = 0;
+ }
+ }
+ }
+
+ if (!nextupd)
+ return ret;
+
+ /* Check nextUpdate is valid and not more than nsec in the past */
+ if (!ASN1_GENERALIZEDTIME_check(nextupd)) {
+ OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
+ ret = 0;
+ } else {
+ t_tmp = t_now - nsec;
+ if (X509_cmp_time(nextupd, &t_tmp) < 0) {
+ OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
+ ret = 0;
+ }
+ }
+
+ /* Also don't allow nextUpdate to precede thisUpdate */
+ if (ASN1_STRING_cmp(nextupd, thisupd) < 0) {
+ OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+ OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_err.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_err.c
new file mode 100644
index 00000000..722043c0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_err.c
@@ -0,0 +1,149 @@
+/* crypto/ocsp/ocsp_err.c */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ocsp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason)
+
+static ERR_STRING_DATA OCSP_str_functs[] = {
+ {ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE), "ASN1_STRING_encode"},
+ {ERR_FUNC(OCSP_F_D2I_OCSP_NONCE), "D2I_OCSP_NONCE"},
+ {ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS), "OCSP_basic_add1_status"},
+ {ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN), "OCSP_basic_sign"},
+ {ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY), "OCSP_basic_verify"},
+ {ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW), "OCSP_cert_id_new"},
+ {ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED), "OCSP_CHECK_DELEGATED"},
+ {ERR_FUNC(OCSP_F_OCSP_CHECK_IDS), "OCSP_CHECK_IDS"},
+ {ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER), "OCSP_CHECK_ISSUER"},
+ {ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY), "OCSP_check_validity"},
+ {ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID), "OCSP_MATCH_ISSUERID"},
+ {ERR_FUNC(OCSP_F_OCSP_PARSE_URL), "OCSP_parse_url"},
+ {ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN), "OCSP_request_sign"},
+ {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}
+};
+
+static ERR_STRING_DATA OCSP_str_reasons[] = {
+ {ERR_REASON(OCSP_R_BAD_DATA), "bad data"},
+ {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+ {ERR_REASON(OCSP_R_DIGEST_ERR), "digest err"},
+ {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD),
+ "error in nextupdate field"},
+ {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD),
+ "error in thisupdate field"},
+ {ERR_REASON(OCSP_R_ERROR_PARSING_URL), "error parsing url"},
+ {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE),
+ "missing ocspsigning usage"},
+ {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE),
+ "nextupdate before thisupdate"},
+ {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE), "not basic response"},
+ {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"},
+ {ERR_REASON(OCSP_R_NO_CONTENT), "no content"},
+ {ERR_REASON(OCSP_R_NO_PUBLIC_KEY), "no public key"},
+ {ERR_REASON(OCSP_R_NO_RESPONSE_DATA), "no response data"},
+ {ERR_REASON(OCSP_R_NO_REVOKED_TIME), "no revoked time"},
+ {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
+ "private key does not match certificate"},
+ {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED), "request not signed"},
+ {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA),
+ "response contains no revocation data"},
+ {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"},
+ {ERR_REASON(OCSP_R_SERVER_READ_ERROR), "server read error"},
+ {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"},
+ {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR),
+ "server response parse error"},
+ {ERR_REASON(OCSP_R_SERVER_WRITE_ERROR), "server write error"},
+ {ERR_REASON(OCSP_R_SIGNATURE_FAILURE), "signature failure"},
+ {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND),
+ "signer certificate not found"},
+ {ERR_REASON(OCSP_R_STATUS_EXPIRED), "status expired"},
+ {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID), "status not yet valid"},
+ {ERR_REASON(OCSP_R_STATUS_TOO_OLD), "status too old"},
+ {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"},
+ {ERR_REASON(OCSP_R_UNKNOWN_NID), "unknown nid"},
+ {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE),
+ "unsupported requestorname type"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_OCSP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, OCSP_str_functs);
+ ERR_load_strings(0, OCSP_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_ext.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_ext.c
new file mode 100644
index 00000000..c19648c7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_ext.c
@@ -0,0 +1,566 @@
+/* ocsp_ext.c */
+/*
+ * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project.
+ */
+
+/*
+ * History: This file was transfered to Richard Levitte from CertCo by Kathy
+ * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a
+ * patch kit.
+ */
+
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/ocsp.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+
+/* Standard wrapper functions for extensions */
+
+/* OCSP request extensions */
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
+{
+ return (X509v3_get_ext_count(x->tbsRequest->requestExtensions));
+}
+
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID
+ (x->tbsRequest->requestExtensions, nid, lastpos));
+}
+
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ
+ (x->tbsRequest->requestExtensions, obj, lastpos));
+}
+
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
+{
+ return (X509v3_get_ext_by_critical
+ (x->tbsRequest->requestExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
+{
+ return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
+{
+ return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc));
+}
+
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
+{
+ return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
+}
+
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+ unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value,
+ crit, flags);
+}
+
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) !=
+ NULL);
+}
+
+/* Single extensions */
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
+{
+ return (X509v3_get_ext_count(x->singleRequestExtensions));
+}
+
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos));
+}
+
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos));
+}
+
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
+{
+ return (X509v3_get_ext_by_critical
+ (x->singleRequestExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
+{
+ return (X509v3_get_ext(x->singleRequestExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
+{
+ return (X509v3_delete_ext(x->singleRequestExtensions, loc));
+}
+
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
+{
+ return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
+}
+
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+ unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
+ flags);
+}
+
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL);
+}
+
+/* OCSP Basic response */
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
+{
+ return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions));
+}
+
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID
+ (x->tbsResponseData->responseExtensions, nid, lastpos));
+}
+
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ
+ (x->tbsResponseData->responseExtensions, obj, lastpos));
+}
+
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
+ int lastpos)
+{
+ return (X509v3_get_ext_by_critical
+ (x->tbsResponseData->responseExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
+{
+ return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
+{
+ return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc));
+}
+
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
+ int *idx)
+{
+ return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit,
+ idx);
+}
+
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
+ int crit, unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid,
+ value, crit, flags);
+}
+
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc)
+ != NULL);
+}
+
+/* OCSP single response extensions */
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
+{
+ return (X509v3_get_ext_count(x->singleExtensions));
+}
+
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos));
+}
+
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos));
+}
+
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
+ int lastpos)
+{
+ return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
+{
+ return (X509v3_get_ext(x->singleExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
+{
+ return (X509v3_delete_ext(x->singleExtensions, loc));
+}
+
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
+ int *idx)
+{
+ return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
+}
+
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
+ int crit, unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
+}
+
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL);
+}
+
+/* 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)
+{
+ int i;
+ unsigned char *p, *b = NULL;
+
+ if (data) {
+ if ((i = i2d(data, NULL)) <= 0)
+ goto err;
+ if (!(b = p = OPENSSL_malloc((unsigned int)i)))
+ goto err;
+ if (i2d(data, &p) <= 0)
+ goto err;
+ } else if (sk) {
+ if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL,
+ (I2D_OF(ASN1_OBJECT)) i2d,
+ V_ASN1_SEQUENCE,
+ V_ASN1_UNIVERSAL,
+ IS_SEQUENCE)) <= 0)
+ goto err;
+ if (!(b = p = OPENSSL_malloc((unsigned int)i)))
+ goto err;
+ if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d,
+ V_ASN1_SEQUENCE,
+ V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0)
+ goto err;
+ } else {
+ OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA);
+ goto err;
+ }
+ if (!s && !(s = ASN1_STRING_new()))
+ goto err;
+ if (!(ASN1_STRING_set(s, b, i)))
+ goto err;
+ OPENSSL_free(b);
+ return s;
+ err:
+ if (b)
+ OPENSSL_free(b);
+ return NULL;
+}
+#endif
+
+/* Nonce handling functions */
+
+/*
+ * Add a nonce to an extension stack. A nonce can be specificed or if NULL a
+ * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an
+ * OCTET STRING containing the nonce, previous versions used the raw nonce.
+ */
+
+static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
+ unsigned char *val, int len)
+{
+ unsigned char *tmpval;
+ ASN1_OCTET_STRING os;
+ int ret = 0;
+ if (len <= 0)
+ len = OCSP_DEFAULT_NONCE_LENGTH;
+ /*
+ * Create the OCTET STRING manually by writing out the header and
+ * appending the content octets. This avoids an extra memory allocation
+ * operation in some cases. Applications should *NOT* do this because it
+ * relies on library internals.
+ */
+ os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
+ os.data = OPENSSL_malloc(os.length);
+ if (os.data == NULL)
+ goto err;
+ tmpval = os.data;
+ ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
+ if (val)
+ memcpy(tmpval, val, len);
+ else if (RAND_pseudo_bytes(tmpval, len) < 0)
+ goto err;
+ if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
+ &os, 0, X509V3_ADD_REPLACE))
+ goto err;
+ ret = 1;
+ err:
+ if (os.data)
+ OPENSSL_free(os.data);
+ return ret;
+}
+
+/* Add nonce to an OCSP request */
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
+{
+ return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
+}
+
+/* Same as above but for a response */
+
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
+{
+ return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val,
+ len);
+}
+
+/*-
+ * Check nonce validity in a request and response.
+ * Return value reflects result:
+ * 1: nonces present and equal.
+ * 2: nonces both absent.
+ * 3: nonce present in response only.
+ * 0: nonces both present and not equal.
+ * -1: nonce in request only.
+ *
+ * For most responders clients can check return > 0.
+ * If responder doesn't handle nonces return != 0 may be
+ * necessary. return == 0 is always an error.
+ */
+
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
+{
+ /*
+ * Since we are only interested in the presence or absence of
+ * the nonce and comparing its value there is no need to use
+ * the X509V3 routines: this way we can avoid them allocating an
+ * ASN1_OCTET_STRING structure for the value which would be
+ * freed immediately anyway.
+ */
+
+ int req_idx, resp_idx;
+ X509_EXTENSION *req_ext, *resp_ext;
+ req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+ resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
+ /* Check both absent */
+ if ((req_idx < 0) && (resp_idx < 0))
+ return 2;
+ /* Check in request only */
+ if ((req_idx >= 0) && (resp_idx < 0))
+ return -1;
+ /* Check in response but not request */
+ if ((req_idx < 0) && (resp_idx >= 0))
+ return 3;
+ /*
+ * Otherwise nonce in request and response so retrieve the extensions
+ */
+ req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+ resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
+ if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
+ return 0;
+ return 1;
+}
+
+/*
+ * Copy the nonce value (if any) from an OCSP request to a response.
+ */
+
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
+{
+ X509_EXTENSION *req_ext;
+ int req_idx;
+ /* Check for nonce in request */
+ req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+ /* If no nonce that's OK */
+ if (req_idx < 0)
+ return 2;
+ req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+ return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
+}
+
+X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
+{
+ X509_EXTENSION *x = NULL;
+ OCSP_CRLID *cid = NULL;
+
+ if (!(cid = OCSP_CRLID_new()))
+ goto err;
+ if (url) {
+ if (!(cid->crlUrl = ASN1_IA5STRING_new()))
+ goto err;
+ if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
+ goto err;
+ }
+ if (n) {
+ if (!(cid->crlNum = ASN1_INTEGER_new()))
+ goto err;
+ if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
+ goto err;
+ }
+ if (tim) {
+ if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new()))
+ goto err;
+ if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
+ goto err;
+ }
+ x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
+ err:
+ if (cid)
+ OCSP_CRLID_free(cid);
+ return x;
+}
+
+/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
+X509_EXTENSION *OCSP_accept_responses_new(char **oids)
+{
+ int nid;
+ STACK_OF(ASN1_OBJECT) *sk = NULL;
+ ASN1_OBJECT *o = NULL;
+ X509_EXTENSION *x = NULL;
+
+ if (!(sk = sk_ASN1_OBJECT_new_null()))
+ goto err;
+ while (oids && *oids) {
+ if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid)))
+ sk_ASN1_OBJECT_push(sk, o);
+ oids++;
+ }
+ x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
+ err:
+ if (sk)
+ sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
+ return x;
+}
+
+/* ArchiveCutoff ::= GeneralizedTime */
+X509_EXTENSION *OCSP_archive_cutoff_new(char *tim)
+{
+ X509_EXTENSION *x = NULL;
+ ASN1_GENERALIZEDTIME *gt = NULL;
+
+ if (!(gt = ASN1_GENERALIZEDTIME_new()))
+ goto err;
+ if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
+ goto err;
+ x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
+ err:
+ if (gt)
+ ASN1_GENERALIZEDTIME_free(gt);
+ return x;
+}
+
+/*
+ * per ACCESS_DESCRIPTION parameter are oids, of which there are currently
+ * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method
+ * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
+ */
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls)
+{
+ X509_EXTENSION *x = NULL;
+ ASN1_IA5STRING *ia5 = NULL;
+ OCSP_SERVICELOC *sloc = NULL;
+ ACCESS_DESCRIPTION *ad = NULL;
+
+ if (!(sloc = OCSP_SERVICELOC_new()))
+ goto err;
+ if (!(sloc->issuer = X509_NAME_dup(issuer)))
+ goto err;
+ if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null()))
+ goto err;
+ while (urls && *urls) {
+ if (!(ad = ACCESS_DESCRIPTION_new()))
+ goto err;
+ if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP)))
+ goto err;
+ if (!(ad->location = GENERAL_NAME_new()))
+ goto err;
+ if (!(ia5 = ASN1_IA5STRING_new()))
+ goto err;
+ if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1))
+ goto err;
+ ad->location->type = GEN_URI;
+ ad->location->d.ia5 = ia5;
+ if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
+ goto err;
+ urls++;
+ }
+ x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
+ err:
+ if (sloc)
+ OCSP_SERVICELOC_free(sloc);
+ return x;
+}
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_ht.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_ht.c
new file mode 100644
index 00000000..88b26b38
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_ht.c
@@ -0,0 +1,555 @@
+/* ocsp_ht.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 <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "e_os.h"
+#include <openssl/asn1.h>
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+#ifdef OPENSSL_SYS_SUNOS
+# define strtoul (unsigned long)strtol
+#endif /* OPENSSL_SYS_SUNOS */
+
+/* Stateful OCSP request code, supporting non-blocking I/O */
+
+/* Opaque OCSP request status structure */
+
+struct ocsp_req_ctx_st {
+ int state; /* Current I/O state */
+ unsigned char *iobuf; /* Line buffer */
+ int iobuflen; /* Line buffer length */
+ BIO *io; /* BIO to perform I/O with */
+ BIO *mem; /* Memory BIO response is built into */
+ unsigned long asn1_len; /* ASN1 length of response */
+ unsigned long max_resp_len; /* Maximum length of response */
+};
+
+#define OCSP_MAX_RESP_LENGTH (100 * 1024)
+#define OCSP_MAX_LINE_LEN 4096;
+
+/* OCSP states */
+
+/* If set no reading should be performed */
+#define OHS_NOREAD 0x1000
+/* Error condition */
+#define OHS_ERROR (0 | OHS_NOREAD)
+/* First line being read */
+#define OHS_FIRSTLINE 1
+/* MIME headers being read */
+#define OHS_HEADERS 2
+/* OCSP initial header (tag + length) being read */
+#define OHS_ASN1_HEADER 3
+/* OCSP content octets being read */
+#define OHS_ASN1_CONTENT 4
+/* First call: ready to start I/O */
+#define OHS_ASN1_WRITE_INIT (5 | OHS_NOREAD)
+/* Request being sent */
+#define OHS_ASN1_WRITE (6 | OHS_NOREAD)
+/* Request being flushed */
+#define OHS_ASN1_FLUSH (7 | OHS_NOREAD)
+/* Completed */
+#define OHS_DONE (8 | OHS_NOREAD)
+/* Headers set, no final \r\n included */
+#define OHS_HTTP_HEADER (9 | OHS_NOREAD)
+
+static int parse_http_line1(char *line);
+
+OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline)
+{
+ OCSP_REQ_CTX *rctx;
+ rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
+ if (!rctx)
+ return NULL;
+ rctx->state = OHS_ERROR;
+ rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
+ 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 || !rctx->mem) {
+ OCSP_REQ_CTX_free(rctx);
+ return NULL;
+ }
+ return rctx;
+}
+
+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
+{
+ if (rctx->mem)
+ BIO_free(rctx->mem);
+ if (rctx->iobuf)
+ OPENSSL_free(rctx->iobuf);
+ OPENSSL_free(rctx);
+}
+
+BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx)
+{
+ return rctx->mem;
+}
+
+void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len)
+{
+ if (len == 0)
+ rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
+ else
+ rctx->max_resp_len = len;
+}
+
+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val)
+{
+ static const char req_hdr[] =
+ "Content-Type: application/ocsp-request\r\n"
+ "Content-Length: %d\r\n\r\n";
+ int reqlen = ASN1_item_i2d(val, NULL, it);
+ if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0)
+ return 0;
+ if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0)
+ return 0;
+ rctx->state = OHS_ASN1_WRITE_INIT;
+ return 1;
+}
+
+int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx,
+ ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ int rv, len;
+ const unsigned char *p;
+
+ rv = OCSP_REQ_CTX_nbio(rctx);
+ if (rv != 1)
+ return rv;
+
+ len = BIO_get_mem_data(rctx->mem, &p);
+ *pval = ASN1_item_d2i(NULL, &p, len, it);
+ if (*pval == NULL) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+ return 1;
+}
+
+int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path)
+{
+ static const char http_hdr[] = "%s %s HTTP/1.0\r\n";
+
+ if (!path)
+ path = "/";
+
+ if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0)
+ return 0;
+ rctx->state = OHS_HTTP_HEADER;
+ return 1;
+}
+
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
+{
+ return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST),
+ (ASN1_VALUE *)req);
+}
+
+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;
+ rctx->state = OHS_HTTP_HEADER;
+ return 1;
+}
+
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
+ int maxline)
+{
+
+ OCSP_REQ_CTX *rctx = NULL;
+ rctx = OCSP_REQ_CTX_new(io, maxline);
+ if (!rctx)
+ return NULL;
+
+ if (!OCSP_REQ_CTX_http(rctx, "POST", path))
+ goto err;
+
+ if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
+ goto err;
+
+ return rctx;
+
+ err:
+ OCSP_REQ_CTX_free(rctx);
+ return NULL;
+}
+
+/*
+ * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We
+ * need to obtain the numeric code and (optional) informational message.
+ */
+
+static int parse_http_line1(char *line)
+{
+ int retcode;
+ char *p, *q, *r;
+ /* Skip to first white space (passed protocol info) */
+
+ for (p = line; *p && !isspace((unsigned char)*p); p++)
+ continue;
+ if (!*p) {
+ OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+ return 0;
+ }
+
+ /* Skip past white space to start of response code */
+ while (*p && isspace((unsigned char)*p))
+ p++;
+
+ if (!*p) {
+ OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+ return 0;
+ }
+
+ /* Find end of response code: first whitespace after start of code */
+ for (q = p; *q && !isspace((unsigned char)*q); q++)
+ continue;
+
+ if (!*q) {
+ OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+ return 0;
+ }
+
+ /* Set end of response code and start of message */
+ *q++ = 0;
+
+ /* Attempt to parse numeric code */
+ retcode = strtoul(p, &r, 10);
+
+ if (*r)
+ return 0;
+
+ /* Skip over any leading white space in message */
+ while (*q && isspace((unsigned char)*q))
+ q++;
+
+ if (*q) {
+ /*
+ * Finally zap any trailing white space in message (include CRLF)
+ */
+
+ /* We know q has a non white space character so this is OK */
+ for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
+ *r = 0;
+ }
+ if (retcode != 200) {
+ OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
+ if (!*q)
+ ERR_add_error_data(2, "Code=", p);
+ else
+ ERR_add_error_data(4, "Code=", p, ",Reason=", q);
+ return 0;
+ }
+
+ return 1;
+
+}
+
+int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx)
+{
+ int i, n;
+ const unsigned char *p;
+ next_io:
+ if (!(rctx->state & OHS_NOREAD)) {
+ n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
+
+ if (n <= 0) {
+ if (BIO_should_retry(rctx->io))
+ return -1;
+ return 0;
+ }
+
+ /* Write data to memory BIO */
+
+ if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
+ return 0;
+ }
+
+ switch (rctx->state) {
+ case OHS_HTTP_HEADER:
+ /* Last operation was adding headers: need a final \r\n */
+ if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+ rctx->state = OHS_ASN1_WRITE_INIT;
+
+ case OHS_ASN1_WRITE_INIT:
+ rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
+ rctx->state = OHS_ASN1_WRITE;
+
+ case OHS_ASN1_WRITE:
+ n = BIO_get_mem_data(rctx->mem, &p);
+
+ i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len);
+
+ if (i <= 0) {
+ if (BIO_should_retry(rctx->io))
+ return -1;
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+
+ rctx->asn1_len -= i;
+
+ if (rctx->asn1_len > 0)
+ goto next_io;
+
+ rctx->state = OHS_ASN1_FLUSH;
+
+ (void)BIO_reset(rctx->mem);
+
+ case OHS_ASN1_FLUSH:
+
+ i = BIO_flush(rctx->io);
+
+ if (i > 0) {
+ rctx->state = OHS_FIRSTLINE;
+ goto next_io;
+ }
+
+ if (BIO_should_retry(rctx->io))
+ return -1;
+
+ rctx->state = OHS_ERROR;
+ return 0;
+
+ case OHS_ERROR:
+ return 0;
+
+ case OHS_FIRSTLINE:
+ case OHS_HEADERS:
+
+ /* Attempt to read a line in */
+
+ next_line:
+ /*
+ * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check
+ * there's a complete line in there before calling BIO_gets or we'll
+ * just get a partial read.
+ */
+ n = BIO_get_mem_data(rctx->mem, &p);
+ if ((n <= 0) || !memchr(p, '\n', n)) {
+ if (n >= rctx->iobuflen) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+ goto next_io;
+ }
+ n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
+
+ if (n <= 0) {
+ if (BIO_should_retry(rctx->mem))
+ goto next_io;
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+
+ /* Don't allow excessive lines */
+ if (n == rctx->iobuflen) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+
+ /* First line */
+ if (rctx->state == OHS_FIRSTLINE) {
+ if (parse_http_line1((char *)rctx->iobuf)) {
+ rctx->state = OHS_HEADERS;
+ goto next_line;
+ } else {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+ } else {
+ /* Look for blank line: end of headers */
+ for (p = rctx->iobuf; *p; p++) {
+ if ((*p != '\r') && (*p != '\n'))
+ break;
+ }
+ if (*p)
+ goto next_line;
+
+ rctx->state = OHS_ASN1_HEADER;
+
+ }
+
+ /* Fall thru */
+
+ case OHS_ASN1_HEADER:
+ /*
+ * Now reading ASN1 header: can read at least 2 bytes which is enough
+ * for ASN1 SEQUENCE header and either length field or at least the
+ * length of the length field.
+ */
+ n = BIO_get_mem_data(rctx->mem, &p);
+ if (n < 2)
+ goto next_io;
+
+ /* Check it is an ASN1 SEQUENCE */
+ if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+
+ /* Check out length field */
+ if (*p & 0x80) {
+ /*
+ * If MSB set on initial length octet we can now always read 6
+ * octets: make sure we have them.
+ */
+ if (n < 6)
+ goto next_io;
+ n = *p & 0x7F;
+ /* Not NDEF or excessive length */
+ if (!n || (n > 4)) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+ p++;
+ rctx->asn1_len = 0;
+ for (i = 0; i < n; i++) {
+ rctx->asn1_len <<= 8;
+ rctx->asn1_len |= *p++;
+ }
+
+ if (rctx->asn1_len > rctx->max_resp_len) {
+ rctx->state = OHS_ERROR;
+ return 0;
+ }
+
+ rctx->asn1_len += n + 2;
+ } else
+ rctx->asn1_len = *p + 2;
+
+ rctx->state = OHS_ASN1_CONTENT;
+
+ /* Fall thru */
+
+ case OHS_ASN1_CONTENT:
+ n = BIO_get_mem_data(rctx->mem, NULL);
+ if (n < (int)rctx->asn1_len)
+ goto next_io;
+
+ rctx->state = OHS_DONE;
+ return 1;
+
+ break;
+
+ case OHS_DONE:
+ return 1;
+
+ }
+
+ return 0;
+
+}
+
+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
+{
+ return OCSP_REQ_CTX_nbio_d2i(rctx,
+ (ASN1_VALUE **)presp,
+ ASN1_ITEM_rptr(OCSP_RESPONSE));
+}
+
+/* Blocking OCSP request handler: now a special case of non-blocking I/O */
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req)
+{
+ OCSP_RESPONSE *resp = NULL;
+ OCSP_REQ_CTX *ctx;
+ int rv;
+
+ ctx = OCSP_sendreq_new(b, path, req, -1);
+
+ if (!ctx)
+ return NULL;
+
+ do {
+ rv = OCSP_sendreq_nbio(&resp, ctx);
+ } while ((rv == -1) && BIO_should_retry(b));
+
+ OCSP_REQ_CTX_free(ctx);
+
+ if (rv)
+ return resp;
+
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_lib.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_lib.c
new file mode 100644
index 00000000..cabf5393
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_lib.c
@@ -0,0 +1,284 @@
+/* ocsp_lib.c */
+/*
+ * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project.
+ */
+
+/*
+ * History: This file was transfered to Richard Levitte from CertCo by Kathy
+ * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a
+ * patch kit.
+ */
+
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+#include <openssl/asn1t.h>
+
+/* Convert a certificate and its issuer to an OCSP_CERTID */
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
+{
+ X509_NAME *iname;
+ ASN1_INTEGER *serial;
+ ASN1_BIT_STRING *ikey;
+#ifndef OPENSSL_NO_SHA1
+ if (!dgst)
+ dgst = EVP_sha1();
+#endif
+ if (subject) {
+ iname = X509_get_issuer_name(subject);
+ serial = X509_get_serialNumber(subject);
+ } else {
+ iname = X509_get_subject_name(issuer);
+ serial = NULL;
+ }
+ ikey = X509_get0_pubkey_bitstr(issuer);
+ return OCSP_cert_id_new(dgst, iname, ikey, serial);
+}
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
+ X509_NAME *issuerName,
+ ASN1_BIT_STRING *issuerKey,
+ ASN1_INTEGER *serialNumber)
+{
+ int nid;
+ unsigned int i;
+ X509_ALGOR *alg;
+ OCSP_CERTID *cid = NULL;
+ unsigned char md[EVP_MAX_MD_SIZE];
+
+ if (!(cid = OCSP_CERTID_new()))
+ goto err;
+
+ alg = cid->hashAlgorithm;
+ if (alg->algorithm != NULL)
+ ASN1_OBJECT_free(alg->algorithm);
+ if ((nid = EVP_MD_type(dgst)) == NID_undef) {
+ OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID);
+ goto err;
+ }
+ if (!(alg->algorithm = OBJ_nid2obj(nid)))
+ goto err;
+ if ((alg->parameter = ASN1_TYPE_new()) == NULL)
+ goto err;
+ alg->parameter->type = V_ASN1_NULL;
+
+ if (!X509_NAME_digest(issuerName, dgst, md, &i))
+ goto digerr;
+ if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i)))
+ goto err;
+
+ /* Calculate the issuerKey hash, excluding tag and length */
+ if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
+ goto err;
+
+ if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i)))
+ goto err;
+
+ if (serialNumber) {
+ ASN1_INTEGER_free(cid->serialNumber);
+ if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber)))
+ goto err;
+ }
+ return cid;
+ digerr:
+ OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR);
+ err:
+ if (cid)
+ OCSP_CERTID_free(cid);
+ return NULL;
+}
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+{
+ int ret;
+ ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
+ if (ret)
+ return ret;
+ ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
+ if (ret)
+ return ret;
+ return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
+}
+
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+{
+ int ret;
+ ret = OCSP_id_issuer_cmp(a, b);
+ if (ret)
+ return ret;
+ return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
+}
+
+/*
+ * Parse a URL and split it up into host, port and path components and
+ * whether it is SSL.
+ */
+
+int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
+ int *pssl)
+{
+ char *p, *buf;
+
+ char *host, *port;
+
+ *phost = NULL;
+ *pport = NULL;
+ *ppath = NULL;
+
+ /* dup the buffer since we are going to mess with it */
+ buf = BUF_strdup(url);
+ if (!buf)
+ goto mem_err;
+
+ /* Check for initial colon */
+ p = strchr(buf, ':');
+
+ if (!p)
+ goto parse_err;
+
+ *(p++) = '\0';
+
+ if (!strcmp(buf, "http")) {
+ *pssl = 0;
+ port = "80";
+ } else if (!strcmp(buf, "https")) {
+ *pssl = 1;
+ port = "443";
+ } else
+ goto parse_err;
+
+ /* Check for double slash */
+ if ((p[0] != '/') || (p[1] != '/'))
+ goto parse_err;
+
+ p += 2;
+
+ host = p;
+
+ /* Check for trailing part of path */
+
+ p = strchr(p, '/');
+
+ if (!p)
+ *ppath = BUF_strdup("/");
+ else {
+ *ppath = BUF_strdup(p);
+ /* Set start of path to 0 so hostname is valid */
+ *p = '\0';
+ }
+
+ if (!*ppath)
+ goto mem_err;
+
+ p = host;
+ if (host[0] == '[') {
+ /* ipv6 literal */
+ host++;
+ p = strchr(host, ']');
+ if (!p)
+ goto parse_err;
+ *p = '\0';
+ p++;
+ }
+
+ /* Look for optional ':' for port number */
+ if ((p = strchr(p, ':'))) {
+ *p = 0;
+ port = p + 1;
+ }
+
+ *pport = BUF_strdup(port);
+ if (!*pport)
+ goto mem_err;
+
+ *phost = BUF_strdup(host);
+
+ if (!*phost)
+ goto mem_err;
+
+ OPENSSL_free(buf);
+
+ return 1;
+
+ mem_err:
+ OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
+ goto err;
+
+ parse_err:
+ OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
+
+ err:
+ if (buf)
+ OPENSSL_free(buf);
+ if (*ppath)
+ OPENSSL_free(*ppath);
+ if (*pport)
+ OPENSSL_free(*pport);
+ if (*phost)
+ OPENSSL_free(*phost);
+ return 0;
+
+}
+
+IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_prn.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_prn.c
new file mode 100644
index 00000000..47d5f83e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_prn.c
@@ -0,0 +1,299 @@
+/* ocsp_prn.c */
+/*
+ * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project.
+ */
+
+/*
+ * History: This file was originally part of ocsp.c and was transfered to
+ * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be
+ * included in OpenSSL or released as a patch kit.
+ */
+
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+
+static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent)
+{
+ BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
+ indent += 2;
+ BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
+ i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm);
+ BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
+ i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING);
+ BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
+ i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING);
+ BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
+ i2a_ASN1_INTEGER(bp, a->serialNumber);
+ BIO_printf(bp, "\n");
+ return 1;
+}
+
+typedef struct {
+ long t;
+ const char *m;
+} OCSP_TBLSTR;
+
+static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
+{
+ const OCSP_TBLSTR *p;
+ for (p = ts; p < ts + len; p++)
+ if (p->t == s)
+ return p->m;
+ return "(UNKNOWN)";
+}
+
+const char *OCSP_response_status_str(long s)
+{
+ static const OCSP_TBLSTR rstat_tbl[] = {
+ {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"},
+ {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"},
+ {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"},
+ {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"},
+ {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"},
+ {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"}
+ };
+ return table2string(s, rstat_tbl, 6);
+}
+
+const char *OCSP_cert_status_str(long s)
+{
+ 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);
+}
+
+const char *OCSP_crl_reason_str(long s)
+{
+ static const OCSP_TBLSTR reason_tbl[] = {
+ {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"},
+ {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"},
+ {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"},
+ {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"},
+ {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"},
+ {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"},
+ {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"},
+ {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"}
+ };
+ return table2string(s, reason_tbl, 8);
+}
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags)
+{
+ int i;
+ long l;
+ OCSP_CERTID *cid = NULL;
+ OCSP_ONEREQ *one = NULL;
+ OCSP_REQINFO *inf = o->tbsRequest;
+ OCSP_SIGNATURE *sig = o->optionalSignature;
+
+ if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0)
+ goto err;
+ l = ASN1_INTEGER_get(inf->version);
+ if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0)
+ goto err;
+ if (inf->requestorName != NULL) {
+ if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0)
+ goto err;
+ GENERAL_NAME_print(bp, inf->requestorName);
+ }
+ if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0)
+ goto err;
+ for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) {
+ one = sk_OCSP_ONEREQ_value(inf->requestList, i);
+ cid = one->reqCert;
+ ocsp_certid_print(bp, cid, 8);
+ if (!X509V3_extensions_print(bp,
+ "Request Single Extensions",
+ one->singleRequestExtensions, flags, 8))
+ goto err;
+ }
+ if (!X509V3_extensions_print(bp, "Request Extensions",
+ inf->requestExtensions, flags, 4))
+ goto err;
+ if (sig) {
+ X509_signature_print(bp, sig->signatureAlgorithm, sig->signature);
+ for (i = 0; i < sk_X509_num(sig->certs); i++) {
+ X509_print(bp, sk_X509_value(sig->certs, i));
+ PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i));
+ }
+ }
+ return 1;
+ err:
+ return 0;
+}
+
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags)
+{
+ int i, ret = 0;
+ long l;
+ OCSP_CERTID *cid = NULL;
+ OCSP_BASICRESP *br = NULL;
+ OCSP_RESPID *rid = NULL;
+ OCSP_RESPDATA *rd = NULL;
+ OCSP_CERTSTATUS *cst = NULL;
+ OCSP_REVOKEDINFO *rev = NULL;
+ OCSP_SINGLERESP *single = NULL;
+ OCSP_RESPBYTES *rb = o->responseBytes;
+
+ if (BIO_puts(bp, "OCSP Response Data:\n") <= 0)
+ goto err;
+ l = ASN1_ENUMERATED_get(o->responseStatus);
+ if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n",
+ OCSP_response_status_str(l), l) <= 0)
+ goto err;
+ if (rb == NULL)
+ return 1;
+ if (BIO_puts(bp, " Response Type: ") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
+ goto err;
+ if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
+ BIO_puts(bp, " (unknown response type)\n");
+ return 1;
+ }
+
+ if ((br = OCSP_response_get1_basic(o)) == NULL)
+ goto err;
+ rd = br->tbsResponseData;
+ l = ASN1_INTEGER_get(rd->version);
+ if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0)
+ goto err;
+ if (BIO_puts(bp, " Responder Id: ") <= 0)
+ goto err;
+
+ rid = rd->responderId;
+ switch (rid->type) {
+ case V_OCSP_RESPID_NAME:
+ X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
+ break;
+ case V_OCSP_RESPID_KEY:
+ i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING);
+ break;
+ }
+
+ if (BIO_printf(bp, "\n Produced At: ") <= 0)
+ goto err;
+ if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt))
+ goto err;
+ if (BIO_printf(bp, "\n Responses:\n") <= 0)
+ goto err;
+ for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) {
+ if (!sk_OCSP_SINGLERESP_value(rd->responses, i))
+ continue;
+ single = sk_OCSP_SINGLERESP_value(rd->responses, i);
+ cid = single->certId;
+ if (ocsp_certid_print(bp, cid, 4) <= 0)
+ goto err;
+ cst = single->certStatus;
+ if (BIO_printf(bp, " Cert Status: %s",
+ OCSP_cert_status_str(cst->type)) <= 0)
+ goto err;
+ if (cst->type == V_OCSP_CERTSTATUS_REVOKED) {
+ rev = cst->value.revoked;
+ if (BIO_printf(bp, "\n Revocation Time: ") <= 0)
+ goto err;
+ if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime))
+ goto err;
+ if (rev->revocationReason) {
+ l = ASN1_ENUMERATED_get(rev->revocationReason);
+ if (BIO_printf(bp,
+ "\n Revocation Reason: %s (0x%lx)",
+ OCSP_crl_reason_str(l), l) <= 0)
+ goto err;
+ }
+ }
+ if (BIO_printf(bp, "\n This Update: ") <= 0)
+ goto err;
+ if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate))
+ goto err;
+ if (single->nextUpdate) {
+ if (BIO_printf(bp, "\n Next Update: ") <= 0)
+ goto err;
+ if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate))
+ goto err;
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ if (!X509V3_extensions_print(bp,
+ "Response Single Extensions",
+ single->singleExtensions, flags, 8))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ 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;
+
+ for (i = 0; i < sk_X509_num(br->certs); i++) {
+ X509_print(bp, sk_X509_value(br->certs, i));
+ PEM_write_bio_X509(bp, sk_X509_value(br->certs, i));
+ }
+
+ ret = 1;
+ err:
+ OCSP_BASICRESP_free(br);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_srv.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_srv.c
new file mode 100644
index 00000000..2ec2c636
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_srv.c
@@ -0,0 +1,271 @@
+/* ocsp_srv.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/*
+ * Utility functions related to sending OCSP responses and extracting
+ * relevant information from the request.
+ */
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req)
+{
+ return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList);
+}
+
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
+{
+ return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i);
+}
+
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one)
+{
+ return one->reqCert;
+}
+
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+ ASN1_OCTET_STRING **pikeyHash,
+ ASN1_INTEGER **pserial, OCSP_CERTID *cid)
+{
+ if (!cid)
+ return 0;
+ if (pmd)
+ *pmd = cid->hashAlgorithm->algorithm;
+ if (piNameHash)
+ *piNameHash = cid->issuerNameHash;
+ if (pikeyHash)
+ *pikeyHash = cid->issuerKeyHash;
+ if (pserial)
+ *pserial = cid->serialNumber;
+ return 1;
+}
+
+int OCSP_request_is_signed(OCSP_REQUEST *req)
+{
+ if (req->optionalSignature)
+ return 1;
+ return 0;
+}
+
+/* Create an OCSP response and encode an optional basic response */
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
+{
+ OCSP_RESPONSE *rsp = NULL;
+
+ if (!(rsp = OCSP_RESPONSE_new()))
+ goto err;
+ if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status)))
+ goto err;
+ if (!bs)
+ return rsp;
+ if (!(rsp->responseBytes = OCSP_RESPBYTES_new()))
+ goto err;
+ rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
+ if (!ASN1_item_pack
+ (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response))
+ goto err;
+ return rsp;
+ err:
+ if (rsp)
+ OCSP_RESPONSE_free(rsp);
+ return NULL;
+}
+
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+ OCSP_CERTID *cid,
+ int status, int reason,
+ ASN1_TIME *revtime,
+ ASN1_TIME *thisupd,
+ ASN1_TIME *nextupd)
+{
+ OCSP_SINGLERESP *single = NULL;
+ OCSP_CERTSTATUS *cs;
+ OCSP_REVOKEDINFO *ri;
+
+ if (!rsp->tbsResponseData->responses &&
+ !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null()))
+ goto err;
+
+ if (!(single = OCSP_SINGLERESP_new()))
+ goto err;
+
+ if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
+ goto err;
+ if (nextupd &&
+ !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
+ goto err;
+
+ OCSP_CERTID_free(single->certId);
+
+ if (!(single->certId = OCSP_CERTID_dup(cid)))
+ goto err;
+
+ cs = single->certStatus;
+ switch (cs->type = status) {
+ case V_OCSP_CERTSTATUS_REVOKED:
+ if (!revtime) {
+ OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME);
+ goto err;
+ }
+ if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new()))
+ goto err;
+ if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
+ goto err;
+ if (reason != OCSP_REVOKED_STATUS_NOSTATUS) {
+ if (!(ri->revocationReason = ASN1_ENUMERATED_new()))
+ goto err;
+ if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason)))
+ goto err;
+ }
+ break;
+
+ case V_OCSP_CERTSTATUS_GOOD:
+ cs->value.good = ASN1_NULL_new();
+ break;
+
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ cs->value.unknown = ASN1_NULL_new();
+ break;
+
+ default:
+ goto err;
+
+ }
+ if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single)))
+ goto err;
+ return single;
+ err:
+ OCSP_SINGLERESP_free(single);
+ return NULL;
+}
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
+{
+ if (!resp->certs && !(resp->certs = sk_X509_new_null()))
+ return 0;
+
+ if (!sk_X509_push(resp->certs, cert))
+ return 0;
+ CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+ return 1;
+}
+
+int OCSP_basic_sign(OCSP_BASICRESP *brsp,
+ X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+ STACK_OF(X509) *certs, unsigned long flags)
+{
+ int i;
+ OCSP_RESPID *rid;
+
+ if (!X509_check_private_key(signer, key)) {
+ OCSPerr(OCSP_F_OCSP_BASIC_SIGN,
+ OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+ goto err;
+ }
+
+ if (!(flags & OCSP_NOCERTS)) {
+ if (!OCSP_basic_add1_cert(brsp, signer))
+ goto err;
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ X509 *tmpcert = sk_X509_value(certs, i);
+ if (!OCSP_basic_add1_cert(brsp, tmpcert))
+ goto err;
+ }
+ }
+
+ rid = brsp->tbsResponseData->responderId;
+ if (flags & OCSP_RESPID_KEY) {
+ unsigned char md[SHA_DIGEST_LENGTH];
+ X509_pubkey_digest(signer, EVP_sha1(), md, NULL);
+ if (!(rid->value.byKey = ASN1_OCTET_STRING_new()))
+ goto err;
+ if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH)))
+ goto err;
+ rid->type = V_OCSP_RESPID_KEY;
+ } else {
+ if (!X509_NAME_set(&rid->value.byName, X509_get_subject_name(signer)))
+ goto err;
+ rid->type = V_OCSP_RESPID_NAME;
+ }
+
+ if (!(flags & OCSP_NOTIME) &&
+ !X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0))
+ goto err;
+
+ /*
+ * Right now, I think that not doing double hashing is the right thing.
+ * -- Richard Levitte
+ */
+
+ if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0))
+ goto err;
+
+ return 1;
+ err:
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/ocsp/ocsp_vfy.c b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_vfy.c
new file mode 100644
index 00000000..d4a257c3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ocsp/ocsp_vfy.c
@@ -0,0 +1,454 @@
+/* ocsp_vfy.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#include <string.h>
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
+ STACK_OF(X509) *certs, X509_STORE *st,
+ unsigned long flags);
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain,
+ unsigned long flags);
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
+ OCSP_CERTID **ret);
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+ STACK_OF(OCSP_SINGLERESP) *sresp);
+static int ocsp_check_delegated(X509 *x, int flags);
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
+ X509_NAME *nm, STACK_OF(X509) *certs,
+ X509_STORE *st, unsigned long flags);
+
+/* Verify a basic response message */
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+ X509_STORE *st, unsigned long flags)
+{
+ X509 *signer, *x;
+ STACK_OF(X509) *chain = NULL;
+ STACK_OF(X509) *untrusted = NULL;
+ X509_STORE_CTX ctx;
+ int i, ret = 0;
+ ret = ocsp_find_signer(&signer, bs, certs, st, flags);
+ if (!ret) {
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+ OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+ goto end;
+ }
+ if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+ flags |= OCSP_NOVERIFY;
+ if (!(flags & OCSP_NOSIGS)) {
+ EVP_PKEY *skey;
+ skey = X509_get_pubkey(signer);
+ if (skey) {
+ ret = OCSP_BASICRESP_verify(bs, skey, 0);
+ EVP_PKEY_free(skey);
+ }
+ if (!skey || ret <= 0) {
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
+ goto end;
+ }
+ }
+ if (!(flags & OCSP_NOVERIFY)) {
+ int init_res;
+ if (flags & OCSP_NOCHAIN) {
+ untrusted = NULL;
+ } else if (bs->certs && certs) {
+ untrusted = sk_X509_dup(bs->certs);
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) {
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+ }
+ } else {
+ untrusted = bs->certs;
+ }
+ init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted);
+ if (!init_res) {
+ ret = -1;
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB);
+ goto end;
+ }
+
+ X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+ ret = X509_verify_cert(&ctx);
+ chain = X509_STORE_CTX_get1_chain(&ctx);
+ X509_STORE_CTX_cleanup(&ctx);
+ if (ret <= 0) {
+ i = X509_STORE_CTX_get_error(&ctx);
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+ OCSP_R_CERTIFICATE_VERIFY_ERROR);
+ ERR_add_error_data(2, "Verify error:",
+ X509_verify_cert_error_string(i));
+ goto end;
+ }
+ if (flags & OCSP_NOCHECKS) {
+ ret = 1;
+ goto end;
+ }
+ /*
+ * At this point we have a valid certificate chain need to verify it
+ * against the OCSP issuer criteria.
+ */
+ ret = ocsp_check_issuer(bs, chain, flags);
+
+ /* If fatal error or valid match then finish */
+ if (ret != 0)
+ goto end;
+
+ /*
+ * Easy case: explicitly trusted. Get root CA and check for explicit
+ * trust
+ */
+ if (flags & OCSP_NOEXPLICIT)
+ goto end;
+
+ x = sk_X509_value(chain, sk_X509_num(chain) - 1);
+ if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) {
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED);
+ goto end;
+ }
+ ret = 1;
+ }
+
+ end:
+ if (chain)
+ sk_X509_pop_free(chain, X509_free);
+ if (bs->certs && certs)
+ sk_X509_free(untrusted);
+ return ret;
+}
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
+ STACK_OF(X509) *certs, X509_STORE *st,
+ unsigned long flags)
+{
+ X509 *signer;
+ OCSP_RESPID *rid = bs->tbsResponseData->responderId;
+ if ((signer = ocsp_find_signer_sk(certs, rid))) {
+ *psigner = signer;
+ return 2;
+ }
+ if (!(flags & OCSP_NOINTERN) &&
+ (signer = ocsp_find_signer_sk(bs->certs, rid))) {
+ *psigner = signer;
+ return 1;
+ }
+ /* Maybe lookup from store if by subject name */
+
+ *psigner = NULL;
+ return 0;
+}
+
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
+{
+ int i;
+ unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
+ X509 *x;
+
+ /* Easy if lookup by name */
+ if (id->type == V_OCSP_RESPID_NAME)
+ return X509_find_by_subject(certs, id->value.byName);
+
+ /* Lookup by key hash */
+
+ /* If key hash isn't SHA1 length then forget it */
+ if (id->value.byKey->length != SHA_DIGEST_LENGTH)
+ return NULL;
+ keyhash = id->value.byKey->data;
+ /* Calculate hash of each key and compare */
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ x = sk_X509_value(certs, i);
+ X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
+ if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
+ return x;
+ }
+ return NULL;
+}
+
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain,
+ unsigned long flags)
+{
+ STACK_OF(OCSP_SINGLERESP) *sresp;
+ X509 *signer, *sca;
+ OCSP_CERTID *caid = NULL;
+ int i;
+ sresp = bs->tbsResponseData->responses;
+
+ if (sk_X509_num(chain) <= 0) {
+ OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
+ return -1;
+ }
+
+ /* See if the issuer IDs match. */
+ i = ocsp_check_ids(sresp, &caid);
+
+ /* If ID mismatch or other error then return */
+ if (i <= 0)
+ return i;
+
+ signer = sk_X509_value(chain, 0);
+ /* Check to see if OCSP responder CA matches request CA */
+ if (sk_X509_num(chain) > 1) {
+ sca = sk_X509_value(chain, 1);
+ i = ocsp_match_issuerid(sca, caid, sresp);
+ if (i < 0)
+ return i;
+ if (i) {
+ /* We have a match, if extensions OK then success */
+ if (ocsp_check_delegated(signer, flags))
+ return 1;
+ return 0;
+ }
+ }
+
+ /* Otherwise check if OCSP request signed directly by request CA */
+ return ocsp_match_issuerid(signer, caid, sresp);
+}
+
+/*
+ * Check the issuer certificate IDs for equality. If there is a mismatch with
+ * the same algorithm then there's no point trying to match any certificates
+ * against the issuer. If the issuer IDs all match then we just need to check
+ * equality against one of them.
+ */
+
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
+{
+ OCSP_CERTID *tmpid, *cid;
+ int i, idcount;
+
+ idcount = sk_OCSP_SINGLERESP_num(sresp);
+ if (idcount <= 0) {
+ OCSPerr(OCSP_F_OCSP_CHECK_IDS,
+ OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
+ return -1;
+ }
+
+ cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
+
+ *ret = NULL;
+
+ for (i = 1; i < idcount; i++) {
+ tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+ /* Check to see if IDs match */
+ if (OCSP_id_issuer_cmp(cid, tmpid)) {
+ /* If algoritm mismatch let caller deal with it */
+ if (OBJ_cmp(tmpid->hashAlgorithm->algorithm,
+ cid->hashAlgorithm->algorithm))
+ return 2;
+ /* Else mismatch */
+ return 0;
+ }
+ }
+
+ /* All IDs match: only need to check one ID */
+ *ret = cid;
+ return 1;
+}
+
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+ STACK_OF(OCSP_SINGLERESP) *sresp)
+{
+ /* If only one ID to match then do it */
+ if (cid) {
+ const EVP_MD *dgst;
+ X509_NAME *iname;
+ int mdlen;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) {
+ OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID,
+ OCSP_R_UNKNOWN_MESSAGE_DIGEST);
+ return -1;
+ }
+
+ mdlen = EVP_MD_size(dgst);
+ if (mdlen < 0)
+ return -1;
+ if ((cid->issuerNameHash->length != mdlen) ||
+ (cid->issuerKeyHash->length != mdlen))
+ return 0;
+ iname = X509_get_subject_name(cert);
+ if (!X509_NAME_digest(iname, dgst, md, NULL))
+ return -1;
+ if (memcmp(md, cid->issuerNameHash->data, mdlen))
+ return 0;
+ X509_pubkey_digest(cert, dgst, md, NULL);
+ if (memcmp(md, cid->issuerKeyHash->data, mdlen))
+ return 0;
+
+ return 1;
+
+ } else {
+ /* We have to match the whole lot */
+ int i, ret;
+ OCSP_CERTID *tmpid;
+ for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
+ tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+ ret = ocsp_match_issuerid(cert, tmpid, NULL);
+ if (ret <= 0)
+ return ret;
+ }
+ return 1;
+ }
+
+}
+
+static int ocsp_check_delegated(X509 *x, int flags)
+{
+ X509_check_purpose(x, -1, 0);
+ if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN))
+ return 1;
+ OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
+ return 0;
+}
+
+/*
+ * Verify an OCSP request. This is fortunately much easier than OCSP response
+ * verify. Just find the signers certificate and verify it against a given
+ * trust value.
+ */
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
+ X509_STORE *store, unsigned long flags)
+{
+ X509 *signer;
+ X509_NAME *nm;
+ GENERAL_NAME *gen;
+ int ret;
+ X509_STORE_CTX ctx;
+ if (!req->optionalSignature) {
+ OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
+ return 0;
+ }
+ gen = req->tbsRequest->requestorName;
+ if (!gen || gen->type != GEN_DIRNAME) {
+ OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+ OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
+ return 0;
+ }
+ nm = gen->d.directoryName;
+ ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags);
+ if (ret <= 0) {
+ OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+ OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+ return 0;
+ }
+ if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+ flags |= OCSP_NOVERIFY;
+ if (!(flags & OCSP_NOSIGS)) {
+ EVP_PKEY *skey;
+ skey = X509_get_pubkey(signer);
+ ret = OCSP_REQUEST_verify(req, skey);
+ EVP_PKEY_free(skey);
+ if (ret <= 0) {
+ OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
+ return 0;
+ }
+ }
+ if (!(flags & OCSP_NOVERIFY)) {
+ int init_res;
+ if (flags & OCSP_NOCHAIN)
+ init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL);
+ else
+ init_res = X509_STORE_CTX_init(&ctx, store, signer,
+ req->optionalSignature->certs);
+ if (!init_res) {
+ OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB);
+ return 0;
+ }
+
+ X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+ X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST);
+ ret = X509_verify_cert(&ctx);
+ X509_STORE_CTX_cleanup(&ctx);
+ if (ret <= 0) {
+ ret = X509_STORE_CTX_get_error(&ctx);
+ OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+ OCSP_R_CERTIFICATE_VERIFY_ERROR);
+ ERR_add_error_data(2, "Verify error:",
+ X509_verify_cert_error_string(ret));
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
+ X509_NAME *nm, STACK_OF(X509) *certs,
+ X509_STORE *st, unsigned long flags)
+{
+ X509 *signer;
+ if (!(flags & OCSP_NOINTERN)) {
+ signer = X509_find_by_subject(req->optionalSignature->certs, nm);
+ if (signer) {
+ *psigner = signer;
+ return 1;
+ }
+ }
+
+ signer = X509_find_by_subject(certs, nm);
+ if (signer) {
+ *psigner = signer;
+ return 2;
+ }
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_all.c b/Cryptlib/OpenSSL/crypto/pem/pem_all.c
new file mode 100644
index 00000000..0e5be63e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_all.c
@@ -0,0 +1,427 @@
+/* crypto/pem/pem_all.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-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
+#endif
+
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
+#endif
+
+IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
+
+IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
+IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
+IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
+
+IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
+ PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
+#ifndef OPENSSL_NO_RSA
+/*
+ * We treat RSA or DSA private keys as a special case. For private keys we
+ * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract
+ * the relevant private key: this means can handle "traditional" and PKCS#8
+ * formats transparently.
+ */
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
+{
+ RSA *rtmp;
+ if (!key)
+ return NULL;
+ rtmp = EVP_PKEY_get1_RSA(key);
+ EVP_PKEY_free(key);
+ if (!rtmp)
+ return NULL;
+ if (rsa) {
+ RSA_free(*rsa);
+ *rsa = rtmp;
+ }
+ return rtmp;
+}
+
+RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
+ void *u)
+{
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+ return pkey_get_rsa(pktmp, rsa);
+}
+
+# ifndef OPENSSL_NO_FP_API
+
+RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
+{
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+ return pkey_get_rsa(pktmp, rsa);
+}
+
+# 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)
+{
+ if (FIPS_mode()) {
+ 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;
+ } else
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
+ PEM_STRING_RSA, bp, x, enc, kstr, klen, cb,
+ u);
+}
+
+# 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)
+{
+ if (FIPS_mode()) {
+ 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;
+ } else
+ return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
+ PEM_STRING_RSA, fp, x, enc, kstr, klen, cb, u);
+}
+# 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)
+#endif
+#ifndef OPENSSL_NO_DSA
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
+{
+ DSA *dtmp;
+ if (!key)
+ return NULL;
+ dtmp = EVP_PKEY_get1_DSA(key);
+ EVP_PKEY_free(key);
+ if (!dtmp)
+ return NULL;
+ if (dsa) {
+ DSA_free(*dsa);
+ *dsa = dtmp;
+ }
+ return dtmp;
+}
+
+DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
+ void *u)
+{
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+ 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)
+{
+ if (FIPS_mode()) {
+ 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;
+ } else
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
+ PEM_STRING_DSA, bp, x, enc, kstr, klen, cb,
+ u);
+}
+
+# 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)
+{
+ if (FIPS_mode()) {
+ 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;
+ } else
+ return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
+ PEM_STRING_DSA, fp, x, enc, kstr, klen, cb, u);
+}
+# 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
+DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
+{
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+ return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
+}
+
+# endif
+
+IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
+#endif
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
+{
+ EC_KEY *dtmp;
+ if (!key)
+ return NULL;
+ dtmp = EVP_PKEY_get1_EC_KEY(key);
+ EVP_PKEY_free(key);
+ if (!dtmp)
+ return NULL;
+ if (eckey) {
+ EC_KEY_free(*eckey);
+ *eckey = dtmp;
+ }
+ return dtmp;
+}
+
+EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
+ void *u)
+{
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+ 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)
+{
+ if (FIPS_mode()) {
+ 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;
+ } else
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
+ PEM_STRING_ECPRIVATEKEY,
+ bp, x, enc, kstr, klen, cb, u);
+}
+
+# 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)
+{
+ if (FIPS_mode()) {
+ 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;
+ } else
+ return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
+ PEM_STRING_ECPRIVATEKEY,
+ fp, x, enc, kstr, klen, cb, u);
+}
+# 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
+EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
+ void *u)
+{
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+ return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
+}
+
+# endif
+
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
+ IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams)
+#endif
+IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_err.c b/Cryptlib/OpenSSL/crypto/pem/pem_err.c
new file mode 100644
index 00000000..e1f4fdb4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_err.c
@@ -0,0 +1,168 @@
+/* crypto/pem/pem_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
+
+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"},
+ {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"},
+ {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"},
+ {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"},
+ {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"},
+ {ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY),
+ "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
+ {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"},
+ {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_DHPARAMS), "PEM_READ_BIO_DHPARAMS"},
+ {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_DHPARAMS), "PEM_READ_DHPARAMS"},
+ {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"},
+ {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"},
+ {ERR_FUNC(PEM_F_PEM_SEALINIT), "PEM_SealInit"},
+ {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"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA PEM_str_reasons[] = {
+ {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"},
+ {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}
+};
+
+#endif
+
+void ERR_load_PEM_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, PEM_str_functs);
+ ERR_load_strings(0, PEM_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_info.c b/Cryptlib/OpenSSL/crypto/pem/pem_info.c
new file mode 100644
index 00000000..4d736a1d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_info.c
@@ -0,0 +1,394 @@
+/* crypto/pem/pem_info.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ STACK_OF(X509_INFO) *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u)
+{
+ X509_INFO *xi = NULL;
+ char *name = NULL, *header = NULL;
+ void *pp;
+ unsigned char *data = NULL;
+ const unsigned char *p;
+ long len, error = 0;
+ int ok = 0;
+ STACK_OF(X509_INFO) *ret = NULL;
+ unsigned int i, raw, ptype;
+ d2i_of_void *d2i = 0;
+
+ if (sk == NULL) {
+ if ((ret = sk_X509_INFO_new_null()) == NULL) {
+ PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else
+ ret = sk;
+
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ for (;;) {
+ raw = 0;
+ ptype = 0;
+ i = PEM_read_bio(bp, &name, &header, &data, &len);
+ if (i == 0) {
+ error = ERR_GET_REASON(ERR_peek_last_error());
+ if (error == PEM_R_NO_START_LINE) {
+ ERR_clear_error();
+ break;
+ }
+ goto err;
+ }
+ start:
+ if ((strcmp(name, PEM_STRING_X509) == 0) ||
+ (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
+ d2i = (D2I_OF(void)) d2i_X509;
+ if (xi->x509 != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+ pp = &(xi->x509);
+ } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
+ d2i = (D2I_OF(void)) d2i_X509_AUX;
+ if (xi->x509 != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+ pp = &(xi->x509);
+ } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
+ d2i = (D2I_OF(void)) d2i_X509_CRL;
+ if (xi->crl != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+ pp = &(xi->crl);
+ } else
+#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;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+
+ xi->enc_data = NULL;
+ xi->enc_len = 0;
+
+ xi->x_pkey = X509_PKEY_new();
+ if (xi->x_pkey == NULL)
+ goto err;
+ ptype = EVP_PKEY_RSA;
+ pp = &xi->x_pkey->dec_pkey;
+ if ((int)strlen(header) > 10) /* assume encrypted */
+ raw = 1;
+ } else
+#endif
+#ifndef OPENSSL_NO_DSA
+ if (strcmp(name, PEM_STRING_DSA) == 0) {
+ d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
+ if (xi->x_pkey != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+
+ xi->enc_data = NULL;
+ xi->enc_len = 0;
+
+ xi->x_pkey = X509_PKEY_new();
+ if (xi->x_pkey == NULL)
+ goto err;
+ ptype = EVP_PKEY_DSA;
+ pp = &xi->x_pkey->dec_pkey;
+ if ((int)strlen(header) > 10) /* assume encrypted */
+ raw = 1;
+ } else
+#endif
+#ifndef OPENSSL_NO_EC
+ if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
+ d2i = (D2I_OF(void)) d2i_ECPrivateKey;
+ if (xi->x_pkey != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+
+ xi->enc_data = NULL;
+ xi->enc_len = 0;
+
+ xi->x_pkey = X509_PKEY_new();
+ if (xi->x_pkey == NULL)
+ goto err;
+ ptype = EVP_PKEY_EC;
+ pp = &xi->x_pkey->dec_pkey;
+ if ((int)strlen(header) > 10) /* assume encrypted */
+ raw = 1;
+ } else
+#endif
+ {
+ d2i = NULL;
+ pp = NULL;
+ }
+
+ if (d2i != NULL) {
+ if (!raw) {
+ EVP_CIPHER_INFO cipher;
+
+ if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+ goto err;
+ if (!PEM_do_header(&cipher, data, &len, cb, u))
+ goto err;
+ p = data;
+ 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;
+ }
+ } else { /* encrypted RSA data */
+ if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
+ goto err;
+ xi->enc_data = (char *)data;
+ xi->enc_len = (int)len;
+ data = NULL;
+ }
+ } else {
+ /* unknown */
+ }
+ if (name != NULL)
+ OPENSSL_free(name);
+ if (header != NULL)
+ OPENSSL_free(header);
+ if (data != NULL)
+ OPENSSL_free(data);
+ name = NULL;
+ header = NULL;
+ data = NULL;
+ }
+
+ /*
+ * if the last one hasn't been pushed yet and there is anything in it
+ * then add it to the stack ...
+ */
+ if ((xi->x509 != NULL) || (xi->crl != NULL) ||
+ (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ xi = NULL;
+ }
+ ok = 1;
+ err:
+ if (xi != NULL)
+ X509_INFO_free(xi);
+ if (!ok) {
+ for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) {
+ xi = sk_X509_INFO_value(ret, i);
+ X509_INFO_free(xi);
+ }
+ if (ret != sk)
+ sk_X509_INFO_free(ret);
+ ret = NULL;
+ }
+
+ if (name != NULL)
+ OPENSSL_free(name);
+ if (header != NULL)
+ OPENSSL_free(header);
+ if (data != NULL)
+ OPENSSL_free(data);
+ return (ret);
+}
+
+/* A TJH addition */
+int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ EVP_CIPHER_CTX ctx;
+ int i, ret = 0;
+ unsigned char *data = NULL;
+ const char *objstr = NULL;
+ char buf[PEM_BUFSIZE];
+ unsigned char *iv = NULL;
+
+ if (enc != NULL) {
+ objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+ if (objstr == NULL) {
+ PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+ }
+
+ /*
+ * now for the fun part ... if we have a private key then we have to be
+ * able to handle a not-yet-decrypted key being written out correctly ...
+ * if it is decrypted or it is non-encrypted then we use the base code
+ */
+ if (xi->x_pkey != NULL) {
+ 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;
+ i = xi->enc_len;
+
+ /*
+ * we take the encryption data from the internal stuff rather
+ * than what the user has passed us ... as we have to match
+ * exactly for some strange reason
+ */
+ objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
+ if (objstr == NULL) {
+ PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
+ PEM_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+
+ /* create the right magic header stuff */
+ OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <=
+ sizeof buf);
+ buf[0] = '\0';
+ PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+ PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
+
+ /* use the normal code to write things out */
+ i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
+ if (i <= 0)
+ goto err;
+ } else {
+ /* Add DSA/DH */
+#ifndef OPENSSL_NO_RSA
+ /* normal optionally encrypted stuff */
+ if (PEM_write_bio_RSAPrivateKey(bp,
+ xi->x_pkey->dec_pkey->pkey.rsa,
+ enc, kstr, klen, cb, u) <= 0)
+ goto err;
+#endif
+ }
+ }
+
+ /* if we have a certificate then write it out now */
+ if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
+ goto err;
+
+ /*
+ * we are ignoring anything else that is loaded into the X509_INFO
+ * structure for the moment ... as I don't need it so I'm not coding it
+ * here and Eric can do it when this makes it into the base library --tjh
+ */
+
+ ret = 1;
+
+ err:
+ OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
+ OPENSSL_cleanse(buf, PEM_BUFSIZE);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_lib.c b/Cryptlib/OpenSSL/crypto/pem/pem_lib.c
new file mode 100644
index 00000000..e25cc685
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_lib.c
@@ -0,0 +1,865 @@
+/* crypto/pem/pem_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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include "asn1_locl.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+const char PEM_version[] = "PEM" OPENSSL_VERSION_PTEXT;
+
+#define MIN_LENGTH 4
+
+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)
+{
+#if defined(OPENSSL_NO_FP_API) || defined(OPENSSL_NO_UI)
+ /*
+ * We should not ever call the default callback routine from windows.
+ */
+ PEMerr(PEM_F_PEM_DEF_CALLBACK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return (-1);
+#else
+ int i, j;
+ const char *prompt;
+ if (key) {
+ i = strlen(key);
+ i = (i > num) ? num : i;
+ memcpy(buf, key, i);
+ return (i);
+ }
+
+ prompt = EVP_get_pw_prompt();
+ if (prompt == NULL)
+ prompt = "Enter PEM pass phrase:";
+
+ for (;;) {
+ 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);
+ memset(buf, 0, (unsigned int)num);
+ return (-1);
+ }
+ j = strlen(buf);
+ if (j < MIN_LENGTH) {
+ fprintf(stderr,
+ "phrase is too short, needs to be at least %d chars\n",
+ MIN_LENGTH);
+ } else
+ break;
+ }
+ return (j);
+#endif
+}
+
+void PEM_proc_type(char *buf, int type)
+{
+ const char *str;
+
+ if (type == PEM_TYPE_ENCRYPTED)
+ str = "ENCRYPTED";
+ else if (type == PEM_TYPE_MIC_CLEAR)
+ str = "MIC-CLEAR";
+ else if (type == PEM_TYPE_MIC_ONLY)
+ str = "MIC-ONLY";
+ else
+ str = "BAD-TYPE";
+
+ BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
+ BUF_strlcat(buf, str, PEM_BUFSIZE);
+ BUF_strlcat(buf, "\n", PEM_BUFSIZE);
+}
+
+void PEM_dek_info(char *buf, const char *type, int len, char *str)
+{
+ static const unsigned char map[17] = "0123456789ABCDEF";
+ long i;
+ int j;
+
+ BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
+ BUF_strlcat(buf, type, PEM_BUFSIZE);
+ BUF_strlcat(buf, ",", PEM_BUFSIZE);
+ j = strlen(buf);
+ if (j + (len * 2) + 1 > PEM_BUFSIZE)
+ return;
+ for (i = 0; i < len; i++) {
+ buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
+ buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
+ }
+ buf[j + i * 2] = '\n';
+ buf[j + i * 2 + 1] = '\0';
+}
+
+#ifndef OPENSSL_NO_FP_API
+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+ pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ void *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+static int check_pem(const char *nm, const char *name)
+{
+ /* Normal matching nm and name */
+ if (!strcmp(nm, name))
+ return 1;
+
+ /* Make PEM_STRING_EVP_PKEY match any private key */
+
+ 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(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 reading DH parameters handle X9.42 DH format too */
+ if (!strcmp(nm, PEM_STRING_DHXPARAMS) &&
+ !strcmp(name, PEM_STRING_DHPARAMS))
+ return 1;
+
+ /* Permit older strings */
+
+ if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509))
+ return 1;
+
+ if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) &&
+ !strcmp(name, PEM_STRING_X509_REQ))
+ return 1;
+
+ /* Allow normal certs to be read as trusted certs */
+ if (!strcmp(nm, PEM_STRING_X509) &&
+ !strcmp(name, PEM_STRING_X509_TRUSTED))
+ return 1;
+
+ if (!strcmp(nm, PEM_STRING_X509_OLD) &&
+ !strcmp(name, PEM_STRING_X509_TRUSTED))
+ return 1;
+
+ /* Some CAs use PKCS#7 with CERTIFICATE headers */
+ if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7))
+ return 1;
+
+ 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;
+}
+
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+ const char *name, BIO *bp, pem_password_cb *cb,
+ void *u)
+{
+ EVP_CIPHER_INFO cipher;
+ char *nm = NULL, *header = NULL;
+ unsigned char *data = NULL;
+ long len;
+ int ret = 0;
+
+ for (;;) {
+ if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
+ if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
+ ERR_add_error_data(2, "Expecting: ", name);
+ return 0;
+ }
+ if (check_pem(nm, name))
+ break;
+ OPENSSL_free(nm);
+ OPENSSL_free(header);
+ OPENSSL_free(data);
+ }
+ if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+ goto err;
+ if (!PEM_do_header(&cipher, data, &len, cb, u))
+ goto err;
+
+ *pdata = data;
+ *plen = len;
+
+ if (pnm)
+ *pnm = nm;
+
+ ret = 1;
+
+ err:
+ if (!ret || !pnm)
+ OPENSSL_free(nm);
+ OPENSSL_free(header);
+ if (!ret)
+ OPENSSL_free(data);
+ return ret;
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
+ void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+ int klen, pem_password_cb *callback, void *u)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+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 *callback, void *u)
+{
+ EVP_CIPHER_CTX ctx;
+ int dsize = 0, i, j, ret = 0;
+ unsigned char *p, *data = NULL;
+ const char *objstr = NULL;
+ char buf[PEM_BUFSIZE];
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+
+ if (enc != NULL) {
+ objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+ if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) {
+ PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+ }
+
+ if ((dsize = i2d(x, NULL)) < 0) {
+ PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB);
+ dsize = 0;
+ goto err;
+ }
+ /* dzise + 8 bytes are needed */
+ /* actually it needs the cipher block size extra... */
+ data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20);
+ if (data == NULL) {
+ PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = data;
+ i = i2d(x, &p);
+
+ if (enc != NULL) {
+ if (kstr == NULL) {
+ if (callback == NULL)
+ klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+ else
+ klen = (*callback) (buf, PEM_BUFSIZE, 1, u);
+ if (klen <= 0) {
+ PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY);
+ goto err;
+ }
+#ifdef CHARSET_EBCDIC
+ /* Convert the pass phrase from EBCDIC */
+ ebcdic2ascii(buf, buf, klen);
+#endif
+ kstr = (unsigned char *)buf;
+ }
+ RAND_add(data, i, 0); /* put in the RSA key. */
+ OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
+ if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) /* Generate a salt */
+ goto err;
+ /*
+ * The 'iv' is used as the iv and as a salt. It is NOT taken from
+ * the BytesToKey function
+ */
+ if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL))
+ goto err;
+
+ if (kstr == (unsigned char *)buf)
+ OPENSSL_cleanse(buf, PEM_BUFSIZE);
+
+ OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <=
+ sizeof buf);
+
+ buf[0] = '\0';
+ PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+ PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
+ /* k=strlen(buf); */
+
+ EVP_CIPHER_CTX_init(&ctx);
+ ret = 1;
+ if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv)
+ || !EVP_EncryptUpdate(&ctx, data, &j, data, i)
+ || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i))
+ ret = 0;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ if (ret == 0)
+ goto err;
+ i += j;
+ } else {
+ ret = 1;
+ buf[0] = '\0';
+ }
+ i = PEM_write_bio(bp, name, buf, data, i);
+ if (i <= 0)
+ ret = 0;
+ err:
+ OPENSSL_cleanse(key, sizeof(key));
+ OPENSSL_cleanse(iv, sizeof(iv));
+ OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
+ OPENSSL_cleanse(buf, PEM_BUFSIZE);
+ if (data != NULL) {
+ OPENSSL_cleanse(data, (unsigned int)dsize);
+ OPENSSL_free(data);
+ }
+ return (ret);
+}
+
+int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
+ pem_password_cb *callback, void *u)
+{
+ int i = 0, j, o, klen;
+ long len;
+ EVP_CIPHER_CTX ctx;
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ char buf[PEM_BUFSIZE];
+
+ len = *plen;
+
+ if (cipher->cipher == NULL)
+ return (1);
+ if (callback == NULL)
+ klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
+ else
+ klen = callback(buf, PEM_BUFSIZE, 0, u);
+ if (klen <= 0) {
+ PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ);
+ return (0);
+ }
+#ifdef CHARSET_EBCDIC
+ /* Convert the pass phrase from EBCDIC */
+ ebcdic2ascii(buf, buf, klen);
+#endif
+
+ if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
+ (unsigned char *)buf, klen, 1, key, NULL))
+ return 0;
+
+ j = (int)len;
+ EVP_CIPHER_CTX_init(&ctx);
+ o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0]));
+ if (o)
+ o = EVP_DecryptUpdate(&ctx, data, &i, data, j);
+ if (o)
+ o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ OPENSSL_cleanse((char *)buf, sizeof(buf));
+ OPENSSL_cleanse((char *)key, sizeof(key));
+ if (o)
+ j += i;
+ else {
+ PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
+ return (0);
+ }
+ *plen = j;
+ return (1);
+}
+
+int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
+{
+ const EVP_CIPHER *enc = NULL;
+ char *p, c;
+ char **header_pp = &header;
+
+ cipher->cipher = NULL;
+ if ((header == NULL) || (*header == '\0') || (*header == '\n'))
+ return (1);
+ if (strncmp(header, "Proc-Type: ", 11) != 0) {
+ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE);
+ return (0);
+ }
+ header += 11;
+ if (*header != '4')
+ return (0);
+ header++;
+ if (*header != ',')
+ return (0);
+ header++;
+ if (strncmp(header, "ENCRYPTED", 9) != 0) {
+ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED);
+ return (0);
+ }
+ for (; (*header != '\n') && (*header != '\0'); header++) ;
+ if (*header == '\0') {
+ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER);
+ return (0);
+ }
+ header++;
+ if (strncmp(header, "DEK-Info: ", 10) != 0) {
+ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO);
+ return (0);
+ }
+ header += 10;
+
+ p = header;
+ for (;;) {
+ c = *header;
+#ifndef CHARSET_EBCDIC
+ if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') ||
+ ((c >= '0') && (c <= '9'))))
+ break;
+#else
+ if (!(isupper(c) || (c == '-') || isdigit(c)))
+ break;
+#endif
+ header++;
+ }
+ *header = '\0';
+ cipher->cipher = enc = EVP_get_cipherbyname(p);
+ *header = c;
+ header++;
+
+ if (enc == NULL) {
+ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION);
+ return (0);
+ }
+ if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len))
+ return (0);
+
+ return (1);
+}
+
+static int load_iv(char **fromp, unsigned char *to, int num)
+{
+ int v, i;
+ char *from;
+
+ from = *fromp;
+ for (i = 0; i < num; i++)
+ to[i] = 0;
+ num *= 2;
+ for (i = 0; i < num; i++) {
+ if ((*from >= '0') && (*from <= '9'))
+ v = *from - '0';
+ else if ((*from >= 'A') && (*from <= 'F'))
+ v = *from - 'A' + 10;
+ else if ((*from >= 'a') && (*from <= 'f'))
+ v = *from - 'a' + 10;
+ else {
+ PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS);
+ return (0);
+ }
+ from++;
+ to[i / 2] |= v << (long)((!(i & 1)) * 4);
+ }
+
+ *fromp = from;
+ return (1);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write(FILE *fp, const char *name, const char *header,
+ const unsigned char *data, long len)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_write_bio(b, name, header, data, len);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int PEM_write_bio(BIO *bp, const char *name, const char *header,
+ const unsigned char *data, long len)
+{
+ int nlen, n, i, j, outl;
+ unsigned char *buf = NULL;
+ EVP_ENCODE_CTX ctx;
+ int reason = ERR_R_BUF_LIB;
+
+ EVP_EncodeInit(&ctx);
+ nlen = strlen(name);
+
+ if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
+ (BIO_write(bp, name, nlen) != nlen) ||
+ (BIO_write(bp, "-----\n", 6) != 6))
+ goto err;
+
+ i = strlen(header);
+ if (i > 0) {
+ if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1))
+ goto err;
+ }
+
+ buf = OPENSSL_malloc(PEM_BUFSIZE * 8);
+ if (buf == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ i = j = 0;
+ while (len > 0) {
+ n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
+ EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
+ if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
+ goto err;
+ i += outl;
+ len -= n;
+ j += n;
+ }
+ EVP_EncodeFinal(&ctx, buf, &outl);
+ if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
+ goto err;
+ OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
+ OPENSSL_free(buf);
+ buf = NULL;
+ if ((BIO_write(bp, "-----END ", 9) != 9) ||
+ (BIO_write(bp, name, nlen) != nlen) ||
+ (BIO_write(bp, "-----\n", 6) != 6))
+ goto err;
+ return (i + outl);
+ err:
+ if (buf) {
+ OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
+ OPENSSL_free(buf);
+ }
+ PEMerr(PEM_F_PEM_WRITE_BIO, reason);
+ return (0);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
+ long *len)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_read_bio(b, name, header, data, len);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
+ long *len)
+{
+ EVP_ENCODE_CTX ctx;
+ int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
+ char buf[256];
+ BUF_MEM *nameB;
+ BUF_MEM *headerB;
+ BUF_MEM *dataB, *tmpB;
+
+ nameB = BUF_MEM_new();
+ headerB = BUF_MEM_new();
+ dataB = BUF_MEM_new();
+ if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
+ BUF_MEM_free(nameB);
+ BUF_MEM_free(headerB);
+ BUF_MEM_free(dataB);
+ PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+
+ buf[254] = '\0';
+ for (;;) {
+ i = BIO_gets(bp, buf, 254);
+
+ if (i <= 0) {
+ PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE);
+ goto err;
+ }
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ if (strncmp(buf, "-----BEGIN ", 11) == 0) {
+ i = strlen(&(buf[11]));
+
+ if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
+ continue;
+ if (!BUF_MEM_grow(nameB, i + 9)) {
+ PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(nameB->data, &(buf[11]), i - 6);
+ nameB->data[i - 6] = '\0';
+ break;
+ }
+ }
+ hl = 0;
+ if (!BUF_MEM_grow(headerB, 256)) {
+ PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ headerB->data[0] = '\0';
+ for (;;) {
+ i = BIO_gets(bp, buf, 254);
+ if (i <= 0)
+ break;
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ if (buf[0] == '\n')
+ break;
+ if (!BUF_MEM_grow(headerB, hl + i + 9)) {
+ PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (strncmp(buf, "-----END ", 9) == 0) {
+ nohead = 1;
+ break;
+ }
+ memcpy(&(headerB->data[hl]), buf, i);
+ headerB->data[hl + i] = '\0';
+ hl += i;
+ }
+
+ bl = 0;
+ if (!BUF_MEM_grow(dataB, 1024)) {
+ PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ dataB->data[0] = '\0';
+ if (!nohead) {
+ for (;;) {
+ i = BIO_gets(bp, buf, 254);
+ if (i <= 0)
+ break;
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ if (i != 65)
+ end = 1;
+ if (strncmp(buf, "-----END ", 9) == 0)
+ break;
+ if (i > 65)
+ break;
+ if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
+ PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(&(dataB->data[bl]), buf, i);
+ dataB->data[bl + i] = '\0';
+ bl += i;
+ if (end) {
+ buf[0] = '\0';
+ i = BIO_gets(bp, buf, 254);
+ if (i <= 0)
+ break;
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ break;
+ }
+ }
+ } else {
+ tmpB = headerB;
+ headerB = dataB;
+ dataB = tmpB;
+ bl = hl;
+ }
+ i = strlen(nameB->data);
+ if ((strncmp(buf, "-----END ", 9) != 0) ||
+ (strncmp(nameB->data, &(buf[9]), i) != 0) ||
+ (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
+ PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE);
+ goto err;
+ }
+
+ EVP_DecodeInit(&ctx);
+ i = EVP_DecodeUpdate(&ctx,
+ (unsigned char *)dataB->data, &bl,
+ (unsigned char *)dataB->data, bl);
+ if (i < 0) {
+ PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
+ goto err;
+ }
+ i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
+ if (i < 0) {
+ PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
+ goto err;
+ }
+ bl += k;
+
+ if (bl == 0)
+ goto err;
+ *name = nameB->data;
+ *header = headerB->data;
+ *data = (unsigned char *)dataB->data;
+ *len = bl;
+ OPENSSL_free(nameB);
+ OPENSSL_free(headerB);
+ OPENSSL_free(dataB);
+ return (1);
+ err:
+ BUF_MEM_free(nameB);
+ BUF_MEM_free(headerB);
+ 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/Cryptlib/OpenSSL/crypto/pem/pem_oth.c b/Cryptlib/OpenSSL/crypto/pem/pem_oth.c
new file mode 100644
index 00000000..1dd3bd7a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_oth.c
@@ -0,0 +1,86 @@
+/* crypto/pem/pem_oth.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+/* Handle 'other' PEMs: not private keys */
+
+void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
+ pem_password_cb *cb, void *u)
+{
+ const unsigned char *p = NULL;
+ unsigned char *data = NULL;
+ long len;
+ char *ret = NULL;
+
+ if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
+ return NULL;
+ p = data;
+ ret = d2i(x, &p, len);
+ if (ret == NULL)
+ PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB);
+ OPENSSL_free(data);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c b/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c
new file mode 100644
index 00000000..9edca4de
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c
@@ -0,0 +1,261 @@
+/* crypto/pem/pem_pkey.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pem.h>
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
+ int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen, pem_password_cb *cb, void *u);
+#ifndef OPENSSL_NO_FP_API
+static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
+ int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen, pem_password_cb *cb, void *u);
+#endif
+
+/*
+ * These functions write a private key in PKCS#8 format: it is a "drop in"
+ * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
+ * is NULL then it uses the unencrypted private key form. The 'nid' versions
+ * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
+ */
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
+ const EVP_CIPHER *enc, char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ X509_SIG *p8;
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ char buf[PEM_BUFSIZE];
+ int ret;
+ if (!(p8inf = EVP_PKEY2PKCS8(x))) {
+ PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+ return 0;
+ }
+ if (enc || (nid != -1)) {
+ if (!kstr) {
+ if (!cb)
+ klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+ else
+ klen = cb(buf, PEM_BUFSIZE, 1, u);
+ if (klen <= 0) {
+ PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return 0;
+ }
+
+ kstr = buf;
+ }
+ p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
+ if (kstr == buf)
+ OPENSSL_cleanse(buf, klen);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (p8 == NULL)
+ return 0;
+ if (isder)
+ ret = i2d_PKCS8_bio(bp, p8);
+ else
+ ret = PEM_write_bio_PKCS8(bp, p8);
+ X509_SIG_free(p8);
+ return ret;
+ } else {
+ if (isder)
+ ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+ else
+ ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return ret;
+ }
+}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+ void *u)
+{
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ X509_SIG *p8 = NULL;
+ int klen;
+ EVP_PKEY *ret;
+ char psbuf[PEM_BUFSIZE];
+ p8 = d2i_PKCS8_bio(bp, NULL);
+ if (!p8)
+ return NULL;
+ if (cb)
+ klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+ else
+ klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+ if (klen <= 0) {
+ PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
+ X509_SIG_free(p8);
+ return NULL;
+ }
+ p8inf = PKCS8_decrypt(p8, psbuf, klen);
+ X509_SIG_free(p8);
+ if (!p8inf)
+ return NULL;
+ ret = EVP_PKCS82PKEY(p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (!ret)
+ return NULL;
+ if (x) {
+ if (*x)
+ EVP_PKEY_free(*x);
+ *x = ret;
+ }
+ return ret;
+}
+
+#ifndef OPENSSL_NO_FP_API
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen, pem_password_cb *cb,
+ void *u)
+{
+ return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid,
+ const EVP_CIPHER *enc, char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ BIO *bp;
+ int ret;
+ if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+ PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+ BIO_free(bp);
+ return ret;
+}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+ void *u)
+{
+ BIO *bp;
+ EVP_PKEY *ret;
+ if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+ PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB);
+ return NULL;
+ }
+ ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+ BIO_free(bp);
+ return ret;
+}
+
+#endif
+
+IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
+
+
+IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
+ PKCS8_PRIV_KEY_INFO)
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_pkey.c b/Cryptlib/OpenSSL/crypto/pem/pem_pkey.c
new file mode 100644
index 00000000..04d6319a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_pkey.c
@@ -0,0 +1,293 @@
+/* crypto/pem/pem_pkey.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#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)
+{
+ 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_EVP_PKEY, bp, cb, u))
+ return NULL;
+ p = data;
+
+ 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;
+ ret = EVP_PKCS82PKEY(p8inf);
+ if (x) {
+ if (*x)
+ EVP_PKEY_free((EVP_PKEY *)*x);
+ *x = ret;
+ }
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ X509_SIG *p8;
+ int klen;
+ char psbuf[PEM_BUFSIZE];
+ p8 = d2i_X509_SIG(NULL, &p, len);
+ if (!p8)
+ goto p8err;
+ if (cb)
+ klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+ else
+ klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+ if (klen <= 0) {
+ PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ);
+ X509_SIG_free(p8);
+ goto err;
+ }
+ p8inf = PKCS8_decrypt(p8, psbuf, klen);
+ X509_SIG_free(p8);
+ if (!p8inf)
+ goto p8err;
+ ret = EVP_PKCS82PKEY(p8inf);
+ if (x) {
+ if (*x)
+ EVP_PKEY_free((EVP_PKEY *)*x);
+ *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);
+ err:
+ OPENSSL_free(nm);
+ OPENSSL_cleanse(data, len);
+ OPENSSL_free(data);
+ 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)
+{
+ BIO *b;
+ EVP_PKEY *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_read_bio_PrivateKey(b, x, cb, u);
+ 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
+
+#ifndef OPENSSL_NO_DH
+
+/* Transparently read in PKCS#3 or X9.42 DH parameters */
+
+DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
+{
+ char *nm = NULL;
+ const unsigned char *p = NULL;
+ unsigned char *data = NULL;
+ long len;
+ DH *ret = NULL;
+
+ if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u))
+ return NULL;
+ p = data;
+
+ if (!strcmp(nm, PEM_STRING_DHXPARAMS))
+ ret = d2i_DHxparams(x, &p, len);
+ else
+ ret = d2i_DHparams(x, &p, len);
+
+ if (ret == NULL)
+ PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB);
+ OPENSSL_free(nm);
+ OPENSSL_free(data);
+ return ret;
+}
+
+# ifndef OPENSSL_NO_FP_API
+DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ DH *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_read_bio_DHparams(b, x, cb, u);
+ BIO_free(b);
+ return (ret);
+}
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_seal.c b/Cryptlib/OpenSSL/crypto/pem/pem_seal.c
new file mode 100644
index 00000000..a5c18125
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_seal.c
@@ -0,0 +1,191 @@
+/* crypto/pem/pem_seal.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 <openssl/opensslconf.h> /* for OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_RSA
+# include <stdio.h>
+# include "cryptlib.h"
+# include <openssl/evp.h>
+# include <openssl/rand.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+# include <openssl/rsa.h>
+
+int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
+ unsigned char **ek, int *ekl, unsigned char *iv,
+ EVP_PKEY **pubk, int npubk)
+{
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ int ret = -1;
+ int i, j, max = 0;
+ char *s = NULL;
+
+ for (i = 0; i < npubk; i++) {
+ if (pubk[i]->type != EVP_PKEY_RSA) {
+ PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA);
+ goto err;
+ }
+ j = RSA_size(pubk[i]->pkey.rsa);
+ if (j > max)
+ max = j;
+ }
+ s = (char *)OPENSSL_malloc(max * 2);
+ if (s == NULL) {
+ PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ EVP_EncodeInit(&ctx->encode);
+
+ EVP_MD_CTX_init(&ctx->md);
+ if (!EVP_SignInit(&ctx->md, md_type))
+ goto err;
+
+ EVP_CIPHER_CTX_init(&ctx->cipher);
+ ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk);
+ if (ret <= 0)
+ goto err;
+
+ /* base64 encode the keys */
+ for (i = 0; i < npubk; i++) {
+ j = EVP_EncodeBlock((unsigned char *)s, ek[i],
+ RSA_size(pubk[i]->pkey.rsa));
+ ekl[i] = j;
+ memcpy(ek[i], s, j + 1);
+ }
+
+ ret = npubk;
+ err:
+ if (s != NULL)
+ OPENSSL_free(s);
+ OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+ return (ret);
+}
+
+void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+ unsigned char *in, int inl)
+{
+ unsigned char buffer[1600];
+ int i, j;
+
+ *outl = 0;
+ EVP_SignUpdate(&ctx->md, in, inl);
+ for (;;) {
+ if (inl <= 0)
+ break;
+ if (inl > 1200)
+ i = 1200;
+ else
+ i = inl;
+ EVP_EncryptUpdate(&ctx->cipher, buffer, &j, in, i);
+ EVP_EncodeUpdate(&ctx->encode, out, &j, buffer, j);
+ *outl += j;
+ out += j;
+ in += i;
+ inl -= i;
+ }
+}
+
+int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
+ unsigned char *out, int *outl, EVP_PKEY *priv)
+{
+ unsigned char *s = NULL;
+ int ret = 0, j;
+ unsigned int i;
+
+ if (priv->type != EVP_PKEY_RSA) {
+ PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA);
+ goto err;
+ }
+ i = RSA_size(priv->pkey.rsa);
+ if (i < 100)
+ i = 100;
+ s = (unsigned char *)OPENSSL_malloc(i * 2);
+ if (s == NULL) {
+ PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i))
+ goto err;
+ EVP_EncodeUpdate(&ctx->encode, out, &j, s, i);
+ *outl = j;
+ out += j;
+ EVP_EncodeFinal(&ctx->encode, out, &j);
+ *outl += j;
+
+ if (!EVP_SignFinal(&ctx->md, s, &i, priv))
+ goto err;
+ *sigl = EVP_EncodeBlock(sig, s, i);
+
+ ret = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx->md);
+ EVP_CIPHER_CTX_cleanup(&ctx->cipher);
+ if (s != NULL)
+ OPENSSL_free(s);
+ return (ret);
+}
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy = &dummy;
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_sign.c b/Cryptlib/OpenSSL/crypto/pem/pem_sign.c
new file mode 100644
index 00000000..b5e5c29b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_sign.c
@@ -0,0 +1,101 @@
+/* crypto/pem/pem_sign.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+{
+ EVP_DigestInit_ex(ctx, type, NULL);
+}
+
+void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count)
+{
+ EVP_DigestUpdate(ctx, data, count);
+}
+
+int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+ unsigned int *siglen, EVP_PKEY *pkey)
+{
+ unsigned char *m;
+ int i, ret = 0;
+ unsigned int m_len;
+
+ m = (unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey) + 2);
+ if (m == NULL) {
+ PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0)
+ goto err;
+
+ i = EVP_EncodeBlock(sigret, m, m_len);
+ *siglen = i;
+ ret = 1;
+ err:
+ /* ctx has been zeroed by EVP_SignFinal() */
+ if (m != NULL)
+ OPENSSL_free(m);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_x509.c b/Cryptlib/OpenSSL/crypto/pem/pem_x509.c
new file mode 100644
index 00000000..3c20ff28
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_x509.c
@@ -0,0 +1,68 @@
+/* pem_x509.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_xaux.c b/Cryptlib/OpenSSL/crypto/pem/pem_xaux.c
new file mode 100644
index 00000000..c5234301
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_xaux.c
@@ -0,0 +1,70 @@
+/* pem_xaux.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
+IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR,
+ X509_CERT_PAIR)
diff --git a/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c b/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c
new file mode 100644
index 00000000..61864468
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c
@@ -0,0 +1,888 @@
+/*
+ * 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 <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+# include <openssl/dsa.h>
+# include <openssl/rsa.h>
+
+/*
+ * 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
+/* Maximum length in PVK header */
+# define PVK_MAX_KEYLEN 102400
+/* Maximum salt length */
+# define PVK_MAX_SALTLEN 10240
+
+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, is_encrypted;
+ if (skip_magic) {
+ if (length < 20) {
+ PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+ return 0;
+ }
+ } else {
+ if (length < 24) {
+ PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+ return 0;
+ }
+ 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 (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
+ return 0;
+
+ 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;
+ int rv = 1;
+ EVP_MD_CTX_init(&mctx);
+ if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL)
+ || !EVP_DigestUpdate(&mctx, salt, saltlen)
+ || !EVP_DigestUpdate(&mctx, pass, passlen)
+ || !EVP_DigestFinal_ex(&mctx, key, NULL))
+ rv = 0;
+
+ EVP_MD_CTX_cleanup(&mctx);
+ return rv;
+}
+
+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;
+ EVP_CIPHER_CTX cctx;
+ EVP_CIPHER_CTX_init(&cctx);
+ if (saltlen) {
+ char psbuf[PEM_BUFSIZE];
+ unsigned char keybuf[20];
+ 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);
+ goto err;
+ }
+ enctmp = OPENSSL_malloc(keylen + 8);
+ if (!enctmp) {
+ PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!derive_pvk_key(keybuf, p, saltlen,
+ (unsigned char *)psbuf, inlen))
+ goto err;
+ p += saltlen;
+ /* Copy BLOBHEADER across, decrypt rest */
+ memcpy(enctmp, p, 8);
+ p += 8;
+ if (keylen < 8) {
+ PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
+ goto err;
+ }
+ inlen = keylen - 8;
+ q = enctmp + 8;
+ if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+ goto err;
+ if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
+ goto err;
+ magic = read_ledword((const unsigned char **)&q);
+ if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
+ q = enctmp + 8;
+ memset(keybuf + 5, 0, 11);
+ if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+ goto err;
+ OPENSSL_cleanse(keybuf, 20);
+ if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
+ goto err;
+ magic = read_ledword((const unsigned char **)&q);
+ if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
+ PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
+ goto err;
+ }
+ } else
+ OPENSSL_cleanse(keybuf, 20);
+ p = enctmp;
+ }
+
+ ret = b2i_PrivateKey(&p, keylen);
+ err:
+ EVP_CIPHER_CTX_cleanup(&cctx);
+ 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, pklen;
+ unsigned char *p, *salt = NULL;
+ EVP_CIPHER_CTX cctx;
+ EVP_CIPHER_CTX_init(&cctx);
+ 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;
+ else {
+ p = OPENSSL_malloc(outlen);
+ if (!p) {
+ PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ *out = p;
+ }
+
+ 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];
+ 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;
+ if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+ goto error;
+ OPENSSL_cleanse(keybuf, 20);
+ if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
+ goto error;
+ if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
+ goto error;
+ }
+ EVP_CIPHER_CTX_cleanup(&cctx);
+ return outlen;
+
+ error:
+ EVP_CIPHER_CTX_cleanup(&cctx);
+ 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/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c
new file mode 100644
index 00000000..d9f03a39
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c
@@ -0,0 +1,258 @@
+/* p12_add.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Pack an object into an OCTET STRING and turn into a safebag */
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
+ int nid1, int nid2)
+{
+ PKCS12_BAGS *bag;
+ PKCS12_SAFEBAG *safebag;
+ if (!(bag = PKCS12_BAGS_new())) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ bag->type = OBJ_nid2obj(nid1);
+ if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!(safebag = PKCS12_SAFEBAG_new())) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ safebag->value.bag = bag;
+ safebag->type = OBJ_nid2obj(nid2);
+ return safebag;
+
+ err:
+ PKCS12_BAGS_free(bag);
+ return NULL;
+}
+
+/* Turn PKCS8 object into a keybag */
+
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
+{
+ PKCS12_SAFEBAG *bag;
+ if (!(bag = PKCS12_SAFEBAG_new())) {
+ PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ bag->type = OBJ_nid2obj(NID_keyBag);
+ bag->value.keybag = p8;
+ return bag;
+}
+
+/* Turn PKCS8 object into a shrouded keybag */
+
+PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
+ int passlen, unsigned char *salt,
+ int saltlen, int iter,
+ PKCS8_PRIV_KEY_INFO *p8)
+{
+ PKCS12_SAFEBAG *bag;
+ const EVP_CIPHER *pbe_ciph;
+
+ /* Set up the safe bag */
+ if (!(bag = PKCS12_SAFEBAG_new())) {
+ PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ 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, pbe_ciph, pass, passlen, salt, saltlen, iter,
+ p8))) {
+ PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
+ PKCS12_SAFEBAG_free(bag);
+ return NULL;
+ }
+
+ return bag;
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
+{
+ PKCS7 *p7;
+ if (!(p7 = PKCS7_new())) {
+ PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ p7->type = OBJ_nid2obj(NID_pkcs7_data);
+ if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
+ PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
+ PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
+ goto err;
+ }
+ return p7;
+
+ err:
+ PKCS7_free(p7);
+ return NULL;
+}
+
+/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
+{
+ if (!PKCS7_type_is_data(p7)) {
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
+ PKCS12_R_CONTENT_TYPE_NOT_DATA);
+ return NULL;
+ }
+ return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
+
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+ unsigned char *salt, int saltlen, int iter,
+ STACK_OF(PKCS12_SAFEBAG) *bags)
+{
+ 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;
+ }
+ if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
+ PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
+ PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
+ goto err;
+ }
+
+ 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);
+ goto err;
+ }
+ X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
+ p7->d.encrypted->enc_data->algorithm = pbe;
+ M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
+ if (!(p7->d.encrypted->enc_data->enc_data =
+ PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
+ passlen, bags, 1))) {
+ PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
+ goto err;
+ }
+
+ return p7;
+
+ err:
+ PKCS7_free(p7);
+ return NULL;
+}
+
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
+ int passlen)
+{
+ if (!PKCS7_type_is_encrypted(p7))
+ return NULL;
+ return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
+ ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
+ pass, passlen,
+ p7->d.encrypted->enc_data->enc_data, 1);
+}
+
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
+ const char *pass, int passlen)
+{
+ return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
+}
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
+{
+ if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
+ &p12->authsafes->d.data))
+ return 1;
+ return 0;
+}
+
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
+{
+ if (!PKCS7_type_is_data(p12->authsafes)) {
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
+ PKCS12_R_CONTENT_TYPE_NOT_DATA);
+ return NULL;
+ }
+ return ASN1_item_unpack(p12->authsafes->d.data,
+ ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_asn.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_asn.c
new file mode 100644
index 00000000..370ddbd6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_asn.c
@@ -0,0 +1,125 @@
+/* p12_asn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 ASN1 module */
+
+ASN1_SEQUENCE(PKCS12) = {
+ ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER),
+ ASN1_SIMPLE(PKCS12, authsafes, PKCS7),
+ ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA)
+} ASN1_SEQUENCE_END(PKCS12)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12)
+
+ASN1_SEQUENCE(PKCS12_MAC_DATA) = {
+ ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG),
+ ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING),
+ ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PKCS12_MAC_DATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+
+ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS12_BAGS) = {
+ ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)),
+ ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)),
+ ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)),
+} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL);
+
+ASN1_SEQUENCE(PKCS12_BAGS) = {
+ ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT),
+ ASN1_ADB_OBJECT(PKCS12_BAGS),
+} ASN1_SEQUENCE_END(PKCS12_BAGS)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS12_SAFEBAG) = {
+ ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)),
+ ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)),
+ ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)),
+ ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
+ ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
+ ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0))
+} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL);
+
+ASN1_SEQUENCE(PKCS12_SAFEBAG) = {
+ ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT),
+ ASN1_ADB_OBJECT(PKCS12_SAFEBAG),
+ ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE)
+} ASN1_SEQUENCE_END(PKCS12_SAFEBAG)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+
+/* SEQUENCE OF SafeBag */
+ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG)
+ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS)
+
+/* Authsafes: SEQUENCE OF PKCS7 */
+ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7)
+ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES)
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_attr.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_attr.c
new file mode 100644
index 00000000..fff3ba1e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_attr.c
@@ -0,0 +1,147 @@
+/* p12_attr.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Add a local keyid to a safebag */
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
+ int namelen)
+{
+ if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
+ V_ASN1_OCTET_STRING, name, namelen))
+ return 1;
+ else
+ return 0;
+}
+
+/* Add key usage to PKCS#8 structure */
+
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
+{
+ unsigned char us_val;
+ us_val = (unsigned char)usage;
+ if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage,
+ V_ASN1_BIT_STRING, &us_val, 1))
+ return 1;
+ else
+ return 0;
+}
+
+/* Add a friendlyname to a safebag */
+
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+ int namelen)
+{
+ if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+ MBSTRING_ASC, (unsigned char *)name, namelen))
+ return 1;
+ else
+ return 0;
+}
+
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
+ const unsigned char *name, int namelen)
+{
+ if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+ MBSTRING_BMP, name, namelen))
+ return 1;
+ else
+ return 0;
+}
+
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen)
+{
+ if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
+ MBSTRING_ASC, (unsigned char *)name, namelen))
+ return 1;
+ else
+ return 0;
+}
+
+ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid)
+{
+ X509_ATTRIBUTE *attrib;
+ int i;
+ if (!attrs)
+ return NULL;
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
+ attrib = sk_X509_ATTRIBUTE_value(attrs, i);
+ if (OBJ_obj2nid(attrib->object) == attr_nid) {
+ if (sk_ASN1_TYPE_num(attrib->value.set))
+ return sk_ASN1_TYPE_value(attrib->value.set, 0);
+ else
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+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 OPENSSL_uni2asc(atype->value.bmpstring->data,
+ atype->value.bmpstring->length);
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_crpt.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_crpt.c
new file mode 100644
index 00000000..9c2dcab0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_crpt.c
@@ -0,0 +1,119 @@
+/* p12_crpt.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 PBE algorithms now in static table */
+
+void PKCS12_PBE_add(void)
+{
+}
+
+int PKCS12_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)
+{
+ PBEPARAM *pbe;
+ int saltlen, iter, ret;
+ unsigned char *salt;
+ const unsigned char *pbuf;
+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+
+ if (cipher == NULL)
+ return 0;
+
+ /* Extract useful info from parameter */
+ if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
+ return 0;
+ }
+
+ pbuf = param->value.sequence->data;
+ if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+ PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
+ return 0;
+ }
+
+ if (!pbe->iter)
+ iter = 1;
+ else
+ iter = ASN1_INTEGER_get(pbe->iter);
+ salt = pbe->salt->data;
+ saltlen = pbe->salt->length;
+ if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
+ iter, EVP_CIPHER_key_length(cipher), key, md)) {
+ PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR);
+ PBEPARAM_free(pbe);
+ return 0;
+ }
+ if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID,
+ iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
+ PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR);
+ PBEPARAM_free(pbe);
+ return 0;
+ }
+ PBEPARAM_free(pbe);
+ ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
+ OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+ OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_crt.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_crt.c
new file mode 100644
index 00000000..7d2aeefa
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_crt.c
@@ -0,0 +1,358 @@
+/* p12_crt.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+ PKCS12_SAFEBAG *bag);
+
+static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
+{
+ int idx;
+ X509_ATTRIBUTE *attr;
+ idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
+ if (idx < 0)
+ return 1;
+ attr = EVP_PKEY_get_attr(pkey, idx);
+ if (!X509at_add1_attr(&bag->attrib, attr))
+ return 0;
+ return 1;
+}
+
+PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+ STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
+ int mac_iter, int keytype)
+{
+ PKCS12 *p12 = NULL;
+ STACK_OF(PKCS7) *safes = NULL;
+ STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
+ PKCS12_SAFEBAG *bag = NULL;
+ int i;
+ unsigned char keyid[EVP_MAX_MD_SIZE];
+ unsigned int keyidlen = 0;
+
+ /* Set defaults */
+ if (!nid_cert) {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+ else
+#endif
+#ifdef OPENSSL_NO_RC2
+ nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
+ nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
+ }
+ if (!nid_key)
+ nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+ if (!iter)
+ iter = PKCS12_DEFAULT_ITER;
+ if (!mac_iter)
+ mac_iter = 1;
+
+ if (!pkey && !cert && !ca) {
+ PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
+ return NULL;
+ }
+
+ if (pkey && cert) {
+ if (!X509_check_private_key(cert, pkey))
+ return NULL;
+ X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
+ }
+
+ if (cert) {
+ bag = PKCS12_add_cert(&bags, cert);
+ if (name && !PKCS12_add_friendlyname(bag, name, -1))
+ goto err;
+ if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+ goto err;
+ }
+
+ /* Add all other certificates */
+ for (i = 0; i < sk_X509_num(ca); i++) {
+ if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
+ goto err;
+ }
+
+ if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
+ goto err;
+
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ bags = NULL;
+
+ if (pkey) {
+ bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
+
+ if (!bag)
+ goto err;
+
+ if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
+ goto err;
+ if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
+ goto err;
+
+ if (name && !PKCS12_add_friendlyname(bag, name, -1))
+ goto err;
+ if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+ goto err;
+ }
+
+ if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
+ goto err;
+
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ bags = NULL;
+
+ p12 = PKCS12_add_safes(safes, 0);
+
+ if (!p12)
+ goto err;
+
+ sk_PKCS7_pop_free(safes, PKCS7_free);
+
+ safes = NULL;
+
+ if ((mac_iter != -1) &&
+ !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
+ goto err;
+
+ return p12;
+
+ err:
+
+ if (p12)
+ PKCS12_free(p12);
+ if (safes)
+ sk_PKCS7_pop_free(safes, PKCS7_free);
+ if (bags)
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ return NULL;
+
+}
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
+{
+ PKCS12_SAFEBAG *bag = NULL;
+ char *name;
+ int namelen = -1;
+ unsigned char *keyid;
+ int keyidlen = -1;
+
+ /* Add user certificate */
+ if (!(bag = PKCS12_x5092certbag(cert)))
+ goto err;
+
+ /*
+ * Use friendlyName and localKeyID in certificate. (if present)
+ */
+
+ name = (char *)X509_alias_get0(cert, &namelen);
+
+ if (name && !PKCS12_add_friendlyname(bag, name, namelen))
+ goto err;
+
+ keyid = X509_keyid_get0(cert, &keyidlen);
+
+ if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+ goto err;
+
+ if (!pkcs12_add_bag(pbags, bag))
+ goto err;
+
+ return bag;
+
+ err:
+
+ if (bag)
+ PKCS12_SAFEBAG_free(bag);
+
+ return NULL;
+
+}
+
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
+ EVP_PKEY *key, int key_usage, int iter,
+ int nid_key, char *pass)
+{
+
+ PKCS12_SAFEBAG *bag = NULL;
+ PKCS8_PRIV_KEY_INFO *p8 = NULL;
+
+ /* Make a PKCS#8 structure */
+ if (!(p8 = EVP_PKEY2PKCS8(key)))
+ goto err;
+ if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
+ goto err;
+ if (nid_key != -1) {
+ bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ } else
+ bag = PKCS12_MAKE_KEYBAG(p8);
+
+ if (!bag)
+ goto err;
+
+ if (!pkcs12_add_bag(pbags, bag))
+ goto err;
+
+ return bag;
+
+ err:
+
+ if (bag)
+ PKCS12_SAFEBAG_free(bag);
+
+ return NULL;
+
+}
+
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+ int nid_safe, int iter, char *pass)
+{
+ PKCS7 *p7 = NULL;
+ int free_safes = 0;
+
+ if (!*psafes) {
+ *psafes = sk_PKCS7_new_null();
+ if (!*psafes)
+ return 0;
+ free_safes = 1;
+ } else
+ free_safes = 0;
+
+ if (nid_safe == 0)
+#ifdef OPENSSL_NO_RC2
+ nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
+ nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
+
+ if (nid_safe == -1)
+ p7 = PKCS12_pack_p7data(bags);
+ else
+ p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
+ if (!p7)
+ goto err;
+
+ if (!sk_PKCS7_push(*psafes, p7))
+ goto err;
+
+ return 1;
+
+ err:
+ if (free_safes) {
+ sk_PKCS7_free(*psafes);
+ *psafes = NULL;
+ }
+
+ if (p7)
+ PKCS7_free(p7);
+
+ return 0;
+
+}
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+ PKCS12_SAFEBAG *bag)
+{
+ int free_bags;
+ if (!pbags)
+ return 1;
+ if (!*pbags) {
+ *pbags = sk_PKCS12_SAFEBAG_new_null();
+ if (!*pbags)
+ return 0;
+ free_bags = 1;
+ } else
+ free_bags = 0;
+
+ if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
+ if (free_bags) {
+ sk_PKCS12_SAFEBAG_free(*pbags);
+ *pbags = NULL;
+ }
+ return 0;
+ }
+
+ return 1;
+
+}
+
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
+{
+ PKCS12 *p12;
+ if (nid_p7 <= 0)
+ nid_p7 = NID_pkcs7_data;
+ p12 = PKCS12_init(nid_p7);
+
+ if (!p12)
+ return NULL;
+
+ if (!PKCS12_pack_authsafes(p12, safes)) {
+ PKCS12_free(p12);
+ return NULL;
+ }
+
+ return p12;
+
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_decr.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_decr.c
new file mode 100644
index 00000000..b40ea10c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_decr.c
@@ -0,0 +1,202 @@
+/* p12_decr.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Define this to dump decrypted output to files called DERnnn */
+/*
+ * #define DEBUG_DECRYPT
+ */
+
+/*
+ * Encrypt/Decrypt a buffer based on password and algor, result in a
+ * OPENSSL_malloc'ed buffer
+ */
+
+unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
+ int passlen, unsigned char *in, int inlen,
+ unsigned char **data, int *datalen, int en_de)
+{
+ unsigned char *out;
+ int outlen, i;
+ EVP_CIPHER_CTX ctx;
+
+ EVP_CIPHER_CTX_init(&ctx);
+ /* Decrypt data */
+ if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
+ algor->parameter, &ctx, en_de)) {
+ PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
+ PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
+ return NULL;
+ }
+
+ if (!(out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) {
+ PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) {
+ OPENSSL_free(out);
+ out = NULL;
+ PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ outlen = i;
+ if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) {
+ OPENSSL_free(out);
+ out = NULL;
+ PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
+ PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
+ goto err;
+ }
+ outlen += i;
+ if (datalen)
+ *datalen = outlen;
+ if (data)
+ *data = out;
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return out;
+
+}
+
+/*
+ * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer
+ * after use.
+ */
+
+void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+ const char *pass, int passlen,
+ ASN1_OCTET_STRING *oct, int zbuf)
+{
+ unsigned char *out;
+ const unsigned char *p;
+ void *ret;
+ int outlen;
+
+ if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
+ &out, &outlen, 0)) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
+ PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
+ return NULL;
+ }
+ p = out;
+#ifdef DEBUG_DECRYPT
+ {
+ FILE *op;
+
+ char fname[30];
+ static int fnm = 1;
+ sprintf(fname, "DER%d", fnm++);
+ op = fopen(fname, "wb");
+ fwrite(p, 1, outlen, op);
+ fclose(op);
+ }
+#endif
+ ret = ASN1_item_d2i(NULL, &p, outlen, it);
+ if (zbuf)
+ OPENSSL_cleanse(out, outlen);
+ if (!ret)
+ PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR);
+ OPENSSL_free(out);
+ return ret;
+}
+
+/*
+ * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero
+ * encoding.
+ */
+
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
+ const ASN1_ITEM *it,
+ const char *pass, int passlen,
+ void *obj, int zbuf)
+{
+ ASN1_OCTET_STRING *oct = NULL;
+ unsigned char *in = NULL;
+ int inlen;
+ if (!(oct = M_ASN1_OCTET_STRING_new())) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ inlen = ASN1_item_i2d(obj, &in, it);
+ if (!in) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR);
+ goto err;
+ }
+ if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
+ &oct->length, 1)) {
+ PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
+ OPENSSL_free(in);
+ goto err;
+ }
+ if (zbuf)
+ OPENSSL_cleanse(in, inlen);
+ OPENSSL_free(in);
+ return oct;
+ err:
+ if (oct)
+ ASN1_OCTET_STRING_free(oct);
+ return NULL;
+}
+
+IMPLEMENT_PKCS12_STACK_OF(PKCS7)
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_init.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_init.c
new file mode 100644
index 00000000..0322df94
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_init.c
@@ -0,0 +1,92 @@
+/* p12_init.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Initialise a PKCS12 structure to take data */
+
+PKCS12 *PKCS12_init(int mode)
+{
+ PKCS12 *pkcs12;
+ if (!(pkcs12 = PKCS12_new())) {
+ PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ASN1_INTEGER_set(pkcs12->version, 3);
+ pkcs12->authsafes->type = OBJ_nid2obj(mode);
+ switch (mode) {
+ case NID_pkcs7_data:
+ if (!(pkcs12->authsafes->d.data = M_ASN1_OCTET_STRING_new())) {
+ PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ default:
+ PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE);
+ goto err;
+ }
+
+ return pkcs12;
+ err:
+ if (pkcs12 != NULL)
+ PKCS12_free(pkcs12);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_key.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_key.c
new file mode 100644
index 00000000..99b8260c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_key.c
@@ -0,0 +1,238 @@
+/* p12_key.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+#include <openssl/bn.h>
+
+/* Uncomment out this line to get debugging info about key generation */
+/*
+ * #define DEBUG_KEYGEN
+ */
+#ifdef DEBUG_KEYGEN
+# include <openssl/bio.h>
+extern BIO *bio_err;
+void h__dump(unsigned char *p, int len);
+#endif
+
+/* PKCS12 compatible key/IV generation */
+#ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+ int saltlen, int id, int iter, int n,
+ unsigned char *out, const EVP_MD *md_type)
+{
+ int ret;
+ unsigned char *unipass;
+ int uniplen;
+
+ if (!pass) {
+ unipass = NULL;
+ uniplen = 0;
+ } 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);
+ }
+ return ret;
+}
+
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
+ int saltlen, int id, int iter, int n,
+ unsigned char *out, const EVP_MD *md_type)
+{
+ unsigned char *B, *D, *I, *p, *Ai;
+ int Slen, Plen, Ilen, Ijlen;
+ int i, j, u, v;
+ int ret = 0;
+ BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */
+ EVP_MD_CTX ctx;
+#ifdef DEBUG_KEYGEN
+ unsigned char *tmpout = out;
+ int tmpn = n;
+#endif
+
+#if 0
+ if (!pass) {
+ PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+#endif
+
+ EVP_MD_CTX_init(&ctx);
+#ifdef DEBUG_KEYGEN
+ fprintf(stderr, "KEYGEN DEBUG\n");
+ fprintf(stderr, "ID %d, ITER %d\n", id, iter);
+ fprintf(stderr, "Password (length %d):\n", passlen);
+ h__dump(pass, passlen);
+ fprintf(stderr, "Salt (length %d):\n", saltlen);
+ h__dump(salt, saltlen);
+#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);
+ Slen = v * ((saltlen + v - 1) / v);
+ if (passlen)
+ Plen = v * ((passlen + v - 1) / v);
+ else
+ Plen = 0;
+ Ilen = Slen + Plen;
+ I = OPENSSL_malloc(Ilen);
+ Ij = BN_new();
+ Bpl1 = BN_new();
+ if (!D || !Ai || !B || !I || !Ij || !Bpl1)
+ goto err;
+ for (i = 0; i < v; i++)
+ D[i] = id;
+ p = I;
+ for (i = 0; i < Slen; i++)
+ *p++ = salt[i % saltlen];
+ for (i = 0; i < Plen; i++)
+ *p++ = pass[i % passlen];
+ for (;;) {
+ if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
+ || !EVP_DigestUpdate(&ctx, D, v)
+ || !EVP_DigestUpdate(&ctx, I, Ilen)
+ || !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+ goto err;
+ for (j = 1; j < iter; j++) {
+ if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
+ || !EVP_DigestUpdate(&ctx, Ai, u)
+ || !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+ goto err;
+ }
+ memcpy(out, Ai, min(n, u));
+ if (u >= n) {
+#ifdef DEBUG_KEYGEN
+ fprintf(stderr, "Output KEY (length %d)\n", tmpn);
+ h__dump(tmpout, tmpn);
+#endif
+ ret = 1;
+ goto end;
+ }
+ n -= u;
+ out += u;
+ for (j = 0; j < v; j++)
+ B[j] = Ai[j % u];
+ /* Work out B + 1 first then can use B as tmp space */
+ if (!BN_bin2bn(B, v, Bpl1))
+ goto err;
+ if (!BN_add_word(Bpl1, 1))
+ goto err;
+ for (j = 0; j < Ilen; j += v) {
+ if (!BN_bin2bn(I + j, v, Ij))
+ goto err;
+ if (!BN_add(Ij, Ij, Bpl1))
+ goto err;
+ if (!BN_bn2bin(Ij, B))
+ goto err;
+ Ijlen = BN_num_bytes(Ij);
+ /* If more than 2^(v*8) - 1 cut off MSB */
+ if (Ijlen > v) {
+ if (!BN_bn2bin(Ij, B))
+ goto err;
+ memcpy(I + j, B + 1, v);
+#ifndef PKCS12_BROKEN_KEYGEN
+ /* If less than v bytes pad with zeroes */
+ } else if (Ijlen < v) {
+ memset(I + j, 0, v - Ijlen);
+ if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+ goto err;
+#endif
+ } else if (!BN_bn2bin(Ij, I + j))
+ goto err;
+ }
+ }
+
+ err:
+ PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);
+
+ end:
+ OPENSSL_free(Ai);
+ OPENSSL_free(B);
+ OPENSSL_free(D);
+ OPENSSL_free(I);
+ BN_free(Ij);
+ BN_free(Bpl1);
+ EVP_MD_CTX_cleanup(&ctx);
+ return ret;
+}
+
+#ifdef DEBUG_KEYGEN
+void h__dump(unsigned char *p, int len)
+{
+ for (; len--; p++)
+ fprintf(stderr, "%02X", *p);
+ fprintf(stderr, "\n");
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_kiss.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_kiss.c
new file mode 100644
index 00000000..9aa3c90c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_kiss.c
@@ -0,0 +1,299 @@
+/* p12_kiss.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Simplified PKCS#12 routines */
+
+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
+ EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+ int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+ 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, or it
+ * should point to a valid STACK structure. pkey and cert can be passed
+ * unitialised.
+ */
+
+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) {
+ PKCS12err(PKCS12_F_PKCS12_PARSE,
+ PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+ return 0;
+ }
+
+ if (pkey)
+ *pkey = NULL;
+ if (cert)
+ *cert = NULL;
+
+ /* Check the mac */
+
+ /*
+ * If password is zero length or NULL then try verifying both cases to
+ * determine which password is correct. The reason for this is that under
+ * PKCS#12 password based encryption no password and a zero length
+ * password are two different things...
+ */
+
+ if (!pass || !*pass) {
+ if (PKCS12_verify_mac(p12, NULL, 0))
+ pass = NULL;
+ else if (PKCS12_verify_mac(p12, "", 0))
+ pass = "";
+ else {
+ PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
+ goto err;
+ }
+ } else if (!PKCS12_verify_mac(p12, pass, -1)) {
+ PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
+ goto err;
+ }
+
+ /* 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) {
+ ERR_set_mark();
+ if (X509_check_private_key(x, *pkey)) {
+ *cert = x;
+ x = NULL;
+ }
+ ERR_pop_to_mark();
+ }
+
+ 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 (x)
+ X509_free(x);
+ if (ocerts)
+ sk_X509_pop_free(ocerts, X509_free);
+ return 0;
+
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
+ EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+ STACK_OF(PKCS7) *asafes;
+ STACK_OF(PKCS12_SAFEBAG) *bags;
+ int i, bagnid;
+ PKCS7 *p7;
+
+ if (!(asafes = PKCS12_unpack_authsafes(p12)))
+ return 0;
+ for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+ p7 = sk_PKCS7_value(asafes, i);
+ bagnid = OBJ_obj2nid(p7->type);
+ if (bagnid == NID_pkcs7_data) {
+ bags = PKCS12_unpack_p7data(p7);
+ } else if (bagnid == NID_pkcs7_encrypted) {
+ bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+ } else
+ continue;
+ if (!bags) {
+ sk_PKCS7_pop_free(asafes, PKCS7_free);
+ return 0;
+ }
+ 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;
+ }
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ }
+ sk_PKCS7_pop_free(asafes, PKCS7_free);
+ return 1;
+}
+
+static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+ 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, ocerts))
+ return 0;
+ }
+ return 1;
+}
+
+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+ EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+ PKCS8_PRIV_KEY_INFO *p8;
+ X509 *x509;
+ 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)))
+ lkid = attrib->value.octet_string;
+
+ switch (M_PKCS12_bag_type(bag)) {
+ case NID_keyBag:
+ if (!pkey || *pkey)
+ return 1;
+ if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
+ return 0;
+ break;
+
+ case NID_pkcs8ShroudedKeyBag:
+ 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;
+ break;
+
+ case NID_certBag:
+ if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
+ return 1;
+ if (!(x509 = PKCS12_certbag2x509(bag)))
+ return 0;
+ if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
+ X509_free(x509);
+ return 0;
+ }
+ if (fname) {
+ int len, r;
+ unsigned char *data;
+ len = ASN1_STRING_to_UTF8(&data, fname);
+ if (len >= 0) {
+ r = X509_alias_set1(x509, data, len);
+ OPENSSL_free(data);
+ if (!r) {
+ X509_free(x509);
+ return 0;
+ }
+ }
+ }
+
+ if (!sk_X509_push(ocerts, x509)) {
+ X509_free(x509);
+ return 0;
+ }
+
+ break;
+
+ case NID_safeContentsBag:
+ return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts);
+ break;
+
+ default:
+ return 1;
+ break;
+ }
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c
new file mode 100644
index 00000000..a9277827
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c
@@ -0,0 +1,195 @@
+/* p12_mutl.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 OPENSSL_NO_HMAC
+# include <stdio.h>
+# include "cryptlib.h"
+# include <openssl/crypto.h>
+# include <openssl/hmac.h>
+# include <openssl/rand.h>
+# include <openssl/pkcs12.h>
+
+/* Generate a MAC */
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+ unsigned char *mac, unsigned int *maclen)
+{
+ const EVP_MD *md_type;
+ HMAC_CTX hmac;
+ unsigned char key[EVP_MAX_MD_SIZE], *salt;
+ int saltlen, iter;
+ int md_size;
+
+ if (!PKCS7_type_is_data(p12->authsafes)) {
+ PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA);
+ return 0;
+ }
+
+ salt = p12->mac->salt->data;
+ saltlen = p12->mac->salt->length;
+ if (!p12->mac->iter)
+ iter = 1;
+ else
+ iter = ASN1_INTEGER_get(p12->mac->iter);
+ if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) {
+ 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,
+ md_size, key, md_type)) {
+ PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
+ return 0;
+ }
+ HMAC_CTX_init(&hmac);
+ if (!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)) {
+ HMAC_CTX_cleanup(&hmac);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hmac);
+ return 1;
+}
+
+/* Verify the mac */
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
+{
+ unsigned char mac[EVP_MAX_MD_SIZE];
+ unsigned int maclen;
+ if (p12->mac == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT);
+ return 0;
+ }
+ if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
+ PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR);
+ return 0;
+ }
+ if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
+ || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen))
+ return 0;
+ return 1;
+}
+
+/* Set a mac */
+
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+ unsigned char *salt, int saltlen, int iter,
+ const EVP_MD *md_type)
+{
+ unsigned char mac[EVP_MAX_MD_SIZE];
+ unsigned int maclen;
+
+ if (!md_type)
+ md_type = EVP_sha1();
+ if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) {
+ PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR);
+ return 0;
+ }
+ if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
+ PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR);
+ return 0;
+ }
+ if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) {
+ PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+/* Set up a mac structure */
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
+ const EVP_MD *md_type)
+{
+ if (!(p12->mac = PKCS12_MAC_DATA_new()))
+ return PKCS12_ERROR;
+ if (iter > 1) {
+ if (!(p12->mac->iter = M_ASN1_INTEGER_new())) {
+ PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
+ PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ if (!saltlen)
+ saltlen = PKCS12_SALT_LEN;
+ if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ p12->mac->salt->length = saltlen;
+ if (!salt) {
+ if (RAND_pseudo_bytes(p12->mac->salt->data, saltlen) < 0)
+ return 0;
+ } else
+ memcpy(p12->mac->salt->data, salt, saltlen);
+ p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
+ if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
+ PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;
+
+ return 1;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c
new file mode 100644
index 00000000..a89b61ab
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c
@@ -0,0 +1,235 @@
+/* p12_npas.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 password change routine */
+
+static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
+ char *newpass);
+static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
+static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
+
+/*
+ * Change the password on a PKCS#12 structure.
+ */
+
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
+{
+ /* Check for NULL PKCS12 structure */
+
+ if (!p12) {
+ PKCS12err(PKCS12_F_PKCS12_NEWPASS,
+ PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+ return 0;
+ }
+
+ /* Check the mac */
+
+ if (!PKCS12_verify_mac(p12, oldpass, -1)) {
+ PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE);
+ return 0;
+ }
+
+ if (!newpass_p12(p12, oldpass, newpass)) {
+ PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
+{
+ STACK_OF(PKCS7) *asafes, *newsafes;
+ STACK_OF(PKCS12_SAFEBAG) *bags;
+ int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
+ PKCS7 *p7, *p7new;
+ ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
+ unsigned char mac[EVP_MAX_MD_SIZE];
+ unsigned int maclen;
+
+ if (!(asafes = PKCS12_unpack_authsafes(p12)))
+ return 0;
+ if (!(newsafes = sk_PKCS7_new_null()))
+ return 0;
+ for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+ p7 = sk_PKCS7_value(asafes, i);
+ bagnid = OBJ_obj2nid(p7->type);
+ if (bagnid == NID_pkcs7_data) {
+ bags = PKCS12_unpack_p7data(p7);
+ } else if (bagnid == NID_pkcs7_encrypted) {
+ bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
+ 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);
+ return 0;
+ }
+ if (!newpass_bags(bags, oldpass, newpass)) {
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ sk_PKCS7_pop_free(asafes, PKCS7_free);
+ return 0;
+ }
+ /* Repack bag in same form with new password */
+ if (bagnid == NID_pkcs7_data)
+ p7new = PKCS12_pack_p7data(bags);
+ else
+ p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
+ pbe_saltlen, pbe_iter, bags);
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ if (!p7new) {
+ sk_PKCS7_pop_free(asafes, PKCS7_free);
+ return 0;
+ }
+ sk_PKCS7_push(newsafes, p7new);
+ }
+ sk_PKCS7_pop_free(asafes, PKCS7_free);
+
+ /* Repack safe: save old safe in case of error */
+
+ p12_data_tmp = p12->authsafes->d.data;
+ if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new()))
+ goto saferr;
+ if (!PKCS12_pack_authsafes(p12, newsafes))
+ goto saferr;
+
+ if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
+ goto saferr;
+ if (!(macnew = ASN1_OCTET_STRING_new()))
+ goto saferr;
+ if (!ASN1_OCTET_STRING_set(macnew, mac, maclen))
+ goto saferr;
+ ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
+ p12->mac->dinfo->digest = macnew;
+ ASN1_OCTET_STRING_free(p12_data_tmp);
+
+ return 1;
+
+ saferr:
+ /* Restore old safe */
+ ASN1_OCTET_STRING_free(p12->authsafes->d.data);
+ ASN1_OCTET_STRING_free(macnew);
+ p12->authsafes->d.data = p12_data_tmp;
+ return 0;
+
+}
+
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
+ char *newpass)
+{
+ int i;
+ for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+ if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass))
+ return 0;
+ }
+ return 1;
+}
+
+/* Change password of safebag: only needs handle shrouded keybags */
+
+static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
+{
+ PKCS8_PRIV_KEY_INFO *p8;
+ X509_SIG *p8new;
+ int p8_nid, p8_saltlen, p8_iter;
+
+ if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag)
+ return 1;
+
+ if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)))
+ return 0;
+ 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);
+ bag->value.shkeybag = p8new;
+ return 1;
+}
+
+static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
+{
+ PBEPARAM *pbe;
+ const unsigned char *p;
+
+ 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 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_p8d.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_p8d.c
new file mode 100644
index 00000000..3cc7a9f4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_p8d.c
@@ -0,0 +1,70 @@
+/* p12_p8d.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass,
+ int passlen)
+{
+ return PKCS12_item_decrypt_d2i(p8->algor,
+ ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
+ passlen, p8->digest, 1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_p8e.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_p8e.c
new file mode 100644
index 00000000..861a087f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_p8e.c
@@ -0,0 +1,105 @@
+/* p12_p8e.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
+ const char *pass, int passlen,
+ unsigned char *salt, int saltlen, int iter,
+ PKCS8_PRIV_KEY_INFO *p8inf)
+{
+ X509_SIG *p8 = NULL;
+ X509_ALGOR *pbe;
+
+ if (!(p8 = X509_SIG_new())) {
+ PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (pbe_nid == -1)
+ pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
+ else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
+ pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid);
+ else {
+ ERR_clear_error();
+ pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+ }
+ if (!pbe) {
+ PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ X509_ALGOR_free(p8->algor);
+ p8->algor = pbe;
+ M_ASN1_OCTET_STRING_free(p8->digest);
+ p8->digest =
+ PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
+ pass, passlen, p8inf, 1);
+ if (!p8->digest) {
+ PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
+ goto err;
+ }
+
+ return p8;
+
+ err:
+ X509_SIG_free(p8);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/p12_utl.c b/Cryptlib/OpenSSL/crypto/pkcs12/p12_utl.c
new file mode 100644
index 00000000..a0b992ea
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/p12_utl.c
@@ -0,0 +1,161 @@
+/* p12_utl.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Cheap and nasty Unicode stuff */
+
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
+ unsigned char **uni, int *unilen)
+{
+ int ulen, i;
+ unsigned char *unitmp;
+ if (asclen == -1)
+ asclen = strlen(asc);
+ ulen = asclen * 2 + 2;
+ if (!(unitmp = OPENSSL_malloc(ulen)))
+ return NULL;
+ for (i = 0; i < ulen - 2; i += 2) {
+ unitmp[i] = 0;
+ unitmp[i + 1] = asc[i >> 1];
+ }
+ /* Make result double null terminated */
+ unitmp[ulen - 2] = 0;
+ unitmp[ulen - 1] = 0;
+ if (unilen)
+ *unilen = ulen;
+ if (uni)
+ *uni = unitmp;
+ return unitmp;
+}
+
+char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
+{
+ int asclen, i;
+ char *asctmp;
+ asclen = unilen / 2;
+ /* If no terminating zero allow for one */
+ if (!unilen || uni[unilen - 1])
+ asclen++;
+ uni++;
+ if (!(asctmp = OPENSSL_malloc(asclen)))
+ return NULL;
+ for (i = 0; i < unilen; i += 2)
+ asctmp[i >> 1] = uni[i];
+ asctmp[asclen - 1] = 0;
+ return asctmp;
+}
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+#endif
+
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+#ifndef OPENSSL_NO_FP_API
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+#endif
+
+PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509)
+{
+ return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
+ NID_x509Certificate, NID_certBag);
+}
+
+PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl)
+{
+ return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
+ NID_x509Crl, NID_crlBag);
+}
+
+X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag)
+{
+ if (M_PKCS12_bag_type(bag) != NID_certBag)
+ return NULL;
+ if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
+ return NULL;
+ return ASN1_item_unpack(bag->value.bag->value.octet,
+ ASN1_ITEM_rptr(X509));
+}
+
+X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag)
+{
+ if (M_PKCS12_bag_type(bag) != NID_crlBag)
+ return NULL;
+ if (M_PKCS12_cert_bag_type(bag) != NID_x509Crl)
+ return NULL;
+ return ASN1_item_unpack(bag->value.bag->value.octet,
+ ASN1_ITEM_rptr(X509_CRL));
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs12/pk12err.c b/Cryptlib/OpenSSL/crypto/pkcs12/pk12err.c
new file mode 100644
index 00000000..e58710b2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs12/pk12err.c
@@ -0,0 +1,149 @@
+/* crypto/pkcs12/pk12err.c */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason)
+
+static ERR_STRING_DATA PKCS12_str_functs[] = {
+ {ERR_FUNC(PKCS12_F_PARSE_BAG), "PARSE_BAG"},
+ {ERR_FUNC(PKCS12_F_PARSE_BAGS), "PARSE_BAGS"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME), "PKCS12_ADD_FRIENDLYNAME"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC),
+ "PKCS12_add_friendlyname_asc"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI),
+ "PKCS12_add_friendlyname_uni"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID), "PKCS12_add_localkeyid"},
+ {ERR_FUNC(PKCS12_F_PKCS12_CREATE), "PKCS12_create"},
+ {ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC), "PKCS12_gen_mac"},
+ {ERR_FUNC(PKCS12_F_PKCS12_INIT), "PKCS12_init"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I), "PKCS12_item_decrypt_d2i"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT), "PKCS12_item_i2d_encrypt"},
+ {ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG), "PKCS12_item_pack_safebag"},
+ {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC), "PKCS12_key_gen_asc"},
+ {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI), "PKCS12_key_gen_uni"},
+ {ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG), "PKCS12_MAKE_KEYBAG"},
+ {ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG), "PKCS12_MAKE_SHKEYBAG"},
+ {ERR_FUNC(PKCS12_F_PKCS12_NEWPASS), "PKCS12_newpass"},
+ {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA), "PKCS12_pack_p7data"},
+ {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA), "PKCS12_pack_p7encdata"},
+ {ERR_FUNC(PKCS12_F_PKCS12_PARSE), "PKCS12_parse"},
+ {ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT), "PKCS12_pbe_crypt"},
+ {ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN), "PKCS12_PBE_keyivgen"},
+ {ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC), "PKCS12_setup_mac"},
+ {ERR_FUNC(PKCS12_F_PKCS12_SET_MAC), "PKCS12_set_mac"},
+ {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES), "PKCS12_unpack_authsafes"},
+ {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA), "PKCS12_unpack_p7data"},
+ {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
+ {ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"},
+ {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA PKCS12_str_reasons[] = {
+ {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"},
+ {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"},
+ {ERR_REASON(PKCS12_R_DECODE_ERROR), "decode error"},
+ {ERR_REASON(PKCS12_R_ENCODE_ERROR), "encode error"},
+ {ERR_REASON(PKCS12_R_ENCRYPT_ERROR), "encrypt error"},
+ {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE),
+ "error setting encrypted data type"},
+ {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
+ {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER),
+ "invalid null pkcs12 pointer"},
+ {ERR_REASON(PKCS12_R_IV_GEN_ERROR), "iv gen error"},
+ {ERR_REASON(PKCS12_R_KEY_GEN_ERROR), "key gen error"},
+ {ERR_REASON(PKCS12_R_MAC_ABSENT), "mac absent"},
+ {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"},
+ {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR), "mac setup error"},
+ {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"},
+ {ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR), "mac verify error"},
+ {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"},
+ {ERR_REASON(PKCS12_R_PARSE_ERROR), "parse error"},
+ {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR),
+ "pkcs12 algor cipherinit error"},
+ {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR),
+ "pkcs12 cipherfinal error"},
+ {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"},
+ {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM),
+ "unknown digest algorithm"},
+ {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_PKCS12_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, PKCS12_str_functs);
+ ERR_load_strings(0, PKCS12_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/bio_pk7.c b/Cryptlib/OpenSSL/crypto/pkcs7/bio_pk7.c
new file mode 100644
index 00000000..fae1c564
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/bio_pk7.c
@@ -0,0 +1,70 @@
+/* bio_pk7.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 <openssl/asn1.h>
+#include <openssl/pkcs7.h>
+#include <openssl/bio.h>
+
+#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS)
+# include <memory.h>
+#endif
+#include <stdio.h>
+
+/* Streaming encode support for PKCS#7 */
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7)
+{
+ return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_asn1.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_asn1.c
new file mode 100644
index 00000000..9c0a4398
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_asn1.c
@@ -0,0 +1,251 @@
+/* pk7_asn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+
+/* PKCS#7 ASN1 module */
+
+/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
+
+ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS7) = {
+ ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+ ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
+ ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
+ ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
+ ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
+ 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);
+
+/* 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_cb(PKCS7, PKCS7)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
+
+IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
+
+ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
+ ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
+ ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
+ ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
+ ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
+ ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
+ ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
+} ASN1_NDEF_SEQUENCE_END(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,
+ void *exarg)
+{
+ if (operation == ASN1_OP_FREE_POST) {
+ PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
+ EVP_PKEY_free(si->pkey);
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = {
+ ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
+ ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
+ /* NB this should be a SET OF but we use a SEQUENCE OF so the
+ * original order * is retained when the structure is reencoded.
+ * Since the attributes are implicitly tagged this will not affect
+ * the encoding.
+ */
+ ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
+ ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
+ ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
+ ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+
+ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
+ ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME),
+ ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
+ ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
+ ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
+ ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
+} ASN1_NDEF_SEQUENCE_END(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,
+ void *exarg)
+{
+ if (operation == ASN1_OP_FREE_POST) {
+ PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
+ X509_free(ri->cert);
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
+ ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
+ ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR),
+ ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO)
+
+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_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+
+ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
+ ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
+ ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
+ ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
+ ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT),
+ ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
+ ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
+ ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = {
+ ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
+ ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+
+ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = {
+ ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
+ ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
+ ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
+ ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
+
+/* Specials for authenticated attributes */
+
+/*
+ * When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN)
+
+/*
+ * When verifying attributes we need to use the received order. So we use
+ * SEQUENCE OF and tag it to SET OF
+ */
+
+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/Cryptlib/OpenSSL/crypto/pkcs7/pk7_attr.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_attr.c
new file mode 100644
index 00000000..88922efe
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_attr.c
@@ -0,0 +1,165 @@
+/* pk7_attr.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001-2004 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 <stdio.h>
+#include <stdlib.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+ STACK_OF(X509_ALGOR) *cap)
+{
+ ASN1_STRING *seq;
+ if (!(seq = ASN1_STRING_new())) {
+ PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ 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);
+}
+
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
+{
+ ASN1_TYPE *cap;
+ const unsigned char *p;
+
+ cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
+ if (!cap || (cap->type != V_ASN1_SEQUENCE))
+ return NULL;
+ p = cap->value.sequence->data;
+ 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 */
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+ X509_ALGOR *alg;
+
+ if (!(alg = X509_ALGOR_new())) {
+ PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ASN1_OBJECT_free(alg->algorithm);
+ alg->algorithm = OBJ_nid2obj(nid);
+ if (arg > 0) {
+ ASN1_INTEGER *nbit;
+ if (!(alg->parameter = ASN1_TYPE_new())) {
+ PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!(nbit = ASN1_INTEGER_new())) {
+ PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!ASN1_INTEGER_set(nbit, arg)) {
+ PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ alg->parameter->value.integer = nbit;
+ alg->parameter->type = V_ASN1_INTEGER;
+ }
+ 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/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c
new file mode 100644
index 00000000..946aaa65
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c
@@ -0,0 +1,1295 @@
+/* crypto/pkcs7/pk7_doit.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+ void *value);
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
+
+static int PKCS7_type_is_other(PKCS7 *p7)
+{
+ int isOther = 1;
+
+ int nid = OBJ_obj2nid(p7->type);
+
+ switch (nid) {
+ case NID_pkcs7_data:
+ case NID_pkcs7_signed:
+ case NID_pkcs7_enveloped:
+ case NID_pkcs7_signedAndEnveloped:
+ case NID_pkcs7_digest:
+ case NID_pkcs7_encrypted:
+ isOther = 0;
+ break;
+ default:
+ isOther = 1;
+ }
+
+ return isOther;
+
+}
+
+static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
+{
+ if (PKCS7_type_is_data(p7))
+ return p7->d.data;
+ if (PKCS7_type_is_other(p7) && p7->d.other
+ && (p7->d.other->type == V_ASN1_OCTET_STRING))
+ return p7->d.other->value.octet_string;
+ return NULL;
+}
+
+static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
+{
+ BIO *btmp;
+ const EVP_MD *md;
+ if ((btmp = BIO_new(BIO_f_md())) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
+ goto err;
+ }
+
+ md = EVP_get_digestbyobj(alg->algorithm);
+ if (md == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
+ goto err;
+ }
+
+ BIO_set_md(btmp, md);
+ if (*pbio == NULL)
+ *pbio = btmp;
+ else if (!BIO_push(*pbio, btmp)) {
+ PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
+ goto err;
+ }
+ btmp = NULL;
+
+ return 1;
+
+ err:
+ if (btmp)
+ BIO_free(btmp);
+ return 0;
+
+}
+
+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 = -1;
+
+ pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!pctx)
+ return -1;
+
+ 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) {
+ ret = 0;
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ ret = 1;
+
+ if (*pek) {
+ OPENSSL_cleanse(*pek, *peklen);
+ OPENSSL_free(*pek);
+ }
+
+ *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;
+ BIO *out = NULL, *btmp = NULL;
+ X509_ALGOR *xa = NULL;
+ const EVP_CIPHER *evp_cipher = NULL;
+ STACK_OF(X509_ALGOR) *md_sk = NULL;
+ STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
+ X509_ALGOR *xalg = NULL;
+ PKCS7_RECIP_INFO *ri = NULL;
+ ASN1_OCTET_STRING *os = NULL;
+
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+ /*
+ * The content field in the PKCS7 ContentInfo is optional, but that really
+ * only applies to inner content (precisely, detached signatures).
+ *
+ * When reading content, missing outer content is therefore treated as an
+ * error.
+ *
+ * When creating content, PKCS7_content_new() must be called before
+ * calling this method, so a NULL p7->d is always an error.
+ */
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
+ return NULL;
+ }
+
+ i = OBJ_obj2nid(p7->type);
+ p7->state = PKCS7_S_HEADER;
+
+ switch (i) {
+ case NID_pkcs7_signed:
+ md_sk = p7->d.sign->md_algs;
+ os = PKCS7_get_octet_string(p7->d.sign->contents);
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ rsk = p7->d.signed_and_enveloped->recipientinfo;
+ md_sk = p7->d.signed_and_enveloped->md_algs;
+ xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
+ evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
+ if (evp_cipher == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
+ goto err;
+ }
+ break;
+ case NID_pkcs7_enveloped:
+ rsk = p7->d.enveloped->recipientinfo;
+ xalg = p7->d.enveloped->enc_data->algorithm;
+ evp_cipher = p7->d.enveloped->enc_data->cipher;
+ if (evp_cipher == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
+ goto err;
+ }
+ break;
+ case NID_pkcs7_digest:
+ 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;
+ }
+
+ for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
+ if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
+ goto err;
+
+ if (xa && !PKCS7_bio_add_digest(&out, xa))
+ goto err;
+
+ if (evp_cipher != NULL) {
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ int keylen, ivlen;
+ EVP_CIPHER_CTX *ctx;
+
+ if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
+ goto err;
+ }
+ BIO_get_cipher_ctx(btmp, &ctx);
+ keylen = EVP_CIPHER_key_length(evp_cipher);
+ ivlen = EVP_CIPHER_iv_length(evp_cipher);
+ xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
+ if (ivlen > 0)
+ if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+ goto err;
+ if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
+ goto err;
+ if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+ goto err;
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
+ goto err;
+
+ if (ivlen > 0) {
+ if (xalg->parameter == NULL) {
+ xalg->parameter = ASN1_TYPE_new();
+ if (xalg->parameter == NULL)
+ goto err;
+ }
+ if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
+ goto err;
+ }
+
+ /* Lets do the pub key stuff :-) */
+ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+ ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+ if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
+ goto err;
+ }
+ OPENSSL_cleanse(key, keylen);
+
+ if (out == NULL)
+ out = btmp;
+ else
+ BIO_push(out, btmp);
+ btmp = NULL;
+ }
+
+ if (bio == NULL) {
+ if (PKCS7_is_detached(p7))
+ bio = BIO_new(BIO_s_null());
+ else if (os && os->length > 0)
+ bio = BIO_new_mem_buf(os->data, os->length);
+ if (bio == NULL) {
+ bio = BIO_new(BIO_s_mem());
+ if (bio == NULL)
+ goto err;
+ BIO_set_mem_eof_return(bio, 0);
+ }
+ }
+ if (out)
+ BIO_push(out, bio);
+ else
+ out = bio;
+ bio = NULL;
+ if (0) {
+ err:
+ if (out != NULL)
+ BIO_free_all(out);
+ if (btmp != NULL)
+ BIO_free_all(btmp);
+ out = NULL;
+ }
+ return (out);
+}
+
+static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
+{
+ int ret;
+ ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
+ pcert->cert_info->issuer);
+ if (ret)
+ return ret;
+ return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
+ ri->issuer_and_serial->serial);
+}
+
+/* int */
+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;
+ X509_ALGOR *xa;
+ ASN1_OCTET_STRING *data_body = NULL;
+ const EVP_MD *evp_md;
+ const EVP_CIPHER *evp_cipher = NULL;
+ EVP_CIPHER_CTX *evp_ctx = NULL;
+ X509_ALGOR *enc_alg = NULL;
+ STACK_OF(X509_ALGOR) *md_sk = NULL;
+ STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
+ PKCS7_RECIP_INFO *ri = NULL;
+ unsigned char *ek = NULL, *tkey = NULL;
+ int eklen = 0, tkeylen = 0;
+
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ return NULL;
+ }
+
+ i = OBJ_obj2nid(p7->type);
+ p7->state = PKCS7_S_HEADER;
+
+ switch (i) {
+ case NID_pkcs7_signed:
+ /*
+ * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
+ * field and optional content.
+ * data_body is NULL if that structure has no (=detached) content
+ * or if the contentType is wrong (i.e., not "data").
+ */
+ data_body = PKCS7_get_octet_string(p7->d.sign->contents);
+ if (!PKCS7_is_detached(p7) && data_body == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_INVALID_SIGNED_DATA_TYPE);
+ goto err;
+ }
+ md_sk = p7->d.sign->md_algs;
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ rsk = p7->d.signed_and_enveloped->recipientinfo;
+ md_sk = p7->d.signed_and_enveloped->md_algs;
+ /* data_body is NULL if the optional EncryptedContent is missing. */
+ data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
+ enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
+ evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+ if (evp_cipher == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ goto err;
+ }
+ break;
+ case NID_pkcs7_enveloped:
+ rsk = p7->d.enveloped->recipientinfo;
+ enc_alg = p7->d.enveloped->enc_data->algorithm;
+ /* data_body is NULL if the optional EncryptedContent is missing. */
+ data_body = p7->d.enveloped->enc_data->enc_data;
+ evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+ if (evp_cipher == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ goto err;
+ }
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+
+ /* Detached content must be supplied via in_bio instead. */
+ if (data_body == NULL && in_bio == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ goto err;
+ }
+
+ /* We will be checking the signature */
+ if (md_sk != NULL) {
+ for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
+ xa = sk_X509_ALGOR_value(md_sk, i);
+ if ((btmp = BIO_new(BIO_f_md())) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
+ goto err;
+ }
+
+ j = OBJ_obj2nid(xa->algorithm);
+ evp_md = EVP_get_digestbynid(j);
+ if (evp_md == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_UNKNOWN_DIGEST_TYPE);
+ goto err;
+ }
+
+ BIO_set_md(btmp, evp_md);
+ if (out == NULL)
+ out = btmp;
+ else
+ BIO_push(out, btmp);
+ btmp = NULL;
+ }
+ }
+
+ if (evp_cipher != NULL) {
+#if 0
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ unsigned char *p;
+ int keylen, ivlen;
+ int max;
+ X509_OBJECT ret;
+#endif
+
+ if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
+ goto err;
+ }
+
+ /*
+ * It was encrypted, we need to decrypt the secret key with the
+ * private key
+ */
+
+ /*
+ * Find the recipientInfo which matches the passed certificate (if
+ * any)
+ */
+
+ if (pcert) {
+ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+ ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+ if (!pkcs7_cmp_ri(ri, pcert))
+ break;
+ ri = NULL;
+ }
+ if (ri == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
+ goto err;
+ }
+ }
+
+ /* If we haven't got a certificate try each ri in turn */
+ if (pcert == NULL) {
+ /*
+ * Always attempt to decrypt all rinfo even after sucess as a
+ * defence against MMA timing attacks.
+ */
+ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+ ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+ goto err;
+ ERR_clear_error();
+ }
+ } else {
+ /* Only exit on fatal errors, not decrypt failure */
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+ goto err;
+ ERR_clear_error();
+ }
+
+ evp_ctx = NULL;
+ BIO_get_cipher_ctx(etmp, &evp_ctx);
+ if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
+ goto err;
+ /* Generate random key as MMA defence */
+ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
+ tkey = OPENSSL_malloc(tkeylen);
+ if (!tkey)
+ goto err;
+ if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
+ goto err;
+ if (ek == NULL) {
+ ek = tkey;
+ eklen = tkeylen;
+ tkey = NULL;
+ }
+
+ 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, eklen)) {
+ /* Use random key as MMA defence */
+ OPENSSL_cleanse(ek, eklen);
+ OPENSSL_free(ek);
+ ek = tkey;
+ eklen = tkeylen;
+ tkey = NULL;
+ }
+ }
+ /* Clear errors so we don't leak information useful in MMA */
+ ERR_clear_error();
+ if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
+ goto err;
+
+ if (ek) {
+ OPENSSL_cleanse(ek, eklen);
+ OPENSSL_free(ek);
+ ek = NULL;
+ }
+ if (tkey) {
+ OPENSSL_cleanse(tkey, tkeylen);
+ OPENSSL_free(tkey);
+ tkey = NULL;
+ }
+
+ if (out == NULL)
+ out = etmp;
+ else
+ BIO_push(out, etmp);
+ etmp = NULL;
+ }
+#if 1
+ if (in_bio != NULL) {
+ bio = in_bio;
+ } else {
+# if 0
+ bio = BIO_new(BIO_s_mem());
+ /*
+ * We need to set this so that when we have read all the data, the
+ * encrypt BIO, if present, will read EOF and encode the last few
+ * bytes
+ */
+ BIO_set_mem_eof_return(bio, 0);
+
+ if (data_body->length > 0)
+ BIO_write(bio, (char *)data_body->data, data_body->length);
+# else
+ if (data_body->length > 0)
+ bio = BIO_new_mem_buf(data_body->data, data_body->length);
+ else {
+ bio = BIO_new(BIO_s_mem());
+ if (bio == NULL)
+ goto err;
+ BIO_set_mem_eof_return(bio, 0);
+ }
+ if (bio == NULL)
+ goto err;
+# endif
+ }
+ BIO_push(out, bio);
+ bio = NULL;
+#endif
+ if (0) {
+ err:
+ if (ek) {
+ OPENSSL_cleanse(ek, eklen);
+ OPENSSL_free(ek);
+ }
+ if (tkey) {
+ OPENSSL_cleanse(tkey, tkeylen);
+ OPENSSL_free(tkey);
+ }
+ if (out != NULL)
+ BIO_free_all(out);
+ if (btmp != NULL)
+ BIO_free_all(btmp);
+ if (etmp != NULL)
+ BIO_free_all(etmp);
+ if (bio != NULL)
+ BIO_free_all(bio);
+ out = NULL;
+ }
+ return (out);
+}
+
+static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
+{
+ for (;;) {
+ bio = BIO_find_type(bio, BIO_TYPE_MD);
+ if (bio == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
+ PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+ return NULL;
+ }
+ BIO_get_md_ctx(bio, pmd);
+ if (*pmd == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+ if (EVP_MD_CTX_type(*pmd) == nid)
+ return bio;
+ bio = BIO_next(bio);
+ }
+ 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 */
+ if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
+ PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
+ return 0;
+ }
+ 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;
+ PKCS7_SIGNER_INFO *si;
+ EVP_MD_CTX *mdc, ctx_tmp;
+ STACK_OF(X509_ATTRIBUTE) *sk;
+ STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
+ ASN1_OCTET_STRING *os = NULL;
+
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+
+ EVP_MD_CTX_init(&ctx_tmp);
+ i = OBJ_obj2nid(p7->type);
+ p7->state = PKCS7_S_HEADER;
+
+ 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;
+ os = p7->d.signed_and_enveloped->enc_data->enc_data;
+ if (!os) {
+ 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;
+ }
+ break;
+ case NID_pkcs7_enveloped:
+ /* XXXXXXXXXXXXXXXX */
+ os = p7->d.enveloped->enc_data->enc_data;
+ if (!os) {
+ 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;
+ }
+ break;
+ case NID_pkcs7_signed:
+ si_sk = p7->d.sign->signer_info;
+ os = PKCS7_get_octet_string(p7->d.sign->contents);
+ /* If detached data then the content is excluded */
+ if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
+ M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
+ p7->d.sign->contents->d.data = NULL;
+ }
+ break;
+
+ case NID_pkcs7_digest:
+ os = PKCS7_get_octet_string(p7->d.digest->contents);
+ /* If detached data then the content is excluded */
+ if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
+ M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
+ p7->d.digest->contents->d.data = NULL;
+ }
+ break;
+
+ default:
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+
+ if (si_sk != NULL) {
+ for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
+ si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
+ if (si->pkey == NULL)
+ continue;
+
+ j = OBJ_obj2nid(si->digest_alg->algorithm);
+
+ btmp = bio;
+
+ btmp = PKCS7_find_digest(&mdc, btmp, j);
+
+ if (btmp == NULL)
+ goto err;
+
+ /*
+ * We now have the EVP_MD_CTX, lets do the signing.
+ */
+ if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
+ goto err;
+
+ sk = si->auth_attr;
+
+ /*
+ * If there are attributes, we add the digest attribute and only
+ * sign the attributes
+ */
+ if (sk_X509_ATTRIBUTE_num(sk) > 0) {
+ if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
+ goto err;
+ } else {
+ unsigned char *abuf = NULL;
+ unsigned int abuflen;
+ abuflen = EVP_PKEY_size(si->pkey);
+ abuf = OPENSSL_malloc(abuflen);
+ if (!abuf)
+ goto err;
+
+ if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
+ goto err;
+ }
+ ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
+ }
+ }
+ } else if (i == NID_pkcs7_digest) {
+ unsigned char md_data[EVP_MAX_MD_SIZE];
+ unsigned int md_len;
+ if (!PKCS7_find_digest(&mdc, bio,
+ OBJ_obj2nid(p7->d.digest->md->algorithm)))
+ goto err;
+ if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
+ goto err;
+ M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
+ }
+
+ if (!PKCS7_is_detached(p7)) {
+ /*
+ * NOTE(emilia): I think we only reach os == NULL here because detached
+ * digested data support is broken.
+ */
+ if (os == NULL)
+ goto err;
+ if (!(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;
+ }
+ 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);
+ ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
+ }
+ }
+ ret = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx_tmp);
+ 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);
+ abuf = NULL;
+ 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)
+{
+ PKCS7_ISSUER_AND_SERIAL *ias;
+ int ret = 0, i;
+ STACK_OF(X509) *cert;
+ X509 *x509;
+
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+
+ if (PKCS7_type_is_signed(p7)) {
+ cert = p7->d.sign->cert;
+ } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
+ cert = p7->d.signed_and_enveloped->cert;
+ } else {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
+ goto err;
+ }
+ /* XXXXXXXXXXXXXXXXXXXXXXX */
+ ias = si->issuer_and_serial;
+
+ x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
+
+ /* were we able to find the cert in passed to us */
+ if (x509 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
+ PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
+ goto err;
+ }
+
+ /* Lets verify */
+ if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
+ goto err;
+ }
+ X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
+ i = X509_verify_cert(ctx);
+ if (i <= 0) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
+ X509_STORE_CTX_cleanup(ctx);
+ goto err;
+ }
+ X509_STORE_CTX_cleanup(ctx);
+
+ return PKCS7_signatureVerify(bio, p7, si, x509);
+ err:
+ return ret;
+}
+
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+ X509 *x509)
+{
+ ASN1_OCTET_STRING *os;
+ EVP_MD_CTX mdc_tmp, *mdc;
+ int ret = 0, i;
+ int md_type;
+ STACK_OF(X509_ATTRIBUTE) *sk;
+ BIO *btmp;
+ EVP_PKEY *pkey;
+
+ EVP_MD_CTX_init(&mdc_tmp);
+
+ if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
+ goto err;
+ }
+
+ md_type = OBJ_obj2nid(si->digest_alg->algorithm);
+
+ btmp = bio;
+ for (;;) {
+ if ((btmp == NULL) ||
+ ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+ PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+ goto err;
+ }
+ BIO_get_md_ctx(btmp, &mdc);
+ if (mdc == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (EVP_MD_CTX_type(mdc) == md_type)
+ break;
+ /*
+ * Workaround for some broken clients that put the signature OID
+ * instead of the digest OID in digest_alg->algorithm
+ */
+ if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
+ break;
+ btmp = BIO_next(btmp);
+ }
+
+ /*
+ * mdc is the digest ctx that we want, unless there are attributes, in
+ * which case the digest is the signed attributes
+ */
+ if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc))
+ goto err;
+
+ sk = si->auth_attr;
+ if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
+ unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
+ unsigned int md_len;
+ int alen;
+ ASN1_OCTET_STRING *message_digest;
+
+ if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len))
+ goto err;
+ message_digest = PKCS7_digest_from_attributes(sk);
+ if (!message_digest) {
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+ PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+ goto err;
+ }
+ if ((message_digest->length != (int)md_len) ||
+ (memcmp(message_digest->data, md_dat, md_len))) {
+#if 0
+ {
+ int ii;
+ for (ii = 0; ii < message_digest->length; ii++)
+ printf("%02X", message_digest->data[ii]);
+ printf(" sent\n");
+ for (ii = 0; ii < md_len; ii++)
+ printf("%02X", md_dat[ii]);
+ printf(" calc\n");
+ }
+#endif
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
+ ret = -1;
+ goto err;
+ }
+
+ if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL))
+ goto err;
+
+ alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
+ ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
+ if (alen <= 0) {
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
+ ret = -1;
+ goto err;
+ }
+ if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
+ goto err;
+
+ OPENSSL_free(abuf);
+ }
+
+ os = si->enc_digest;
+ pkey = X509_get_pubkey(x509);
+ if (!pkey) {
+ ret = -1;
+ goto err;
+ }
+
+ i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
+ EVP_PKEY_free(pkey);
+ if (i <= 0) {
+ PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
+ ret = -1;
+ goto err;
+ } else
+ ret = 1;
+ err:
+ EVP_MD_CTX_cleanup(&mdc_tmp);
+ return (ret);
+}
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
+{
+ STACK_OF(PKCS7_RECIP_INFO) *rsk;
+ PKCS7_RECIP_INFO *ri;
+ int i;
+
+ i = OBJ_obj2nid(p7->type);
+ if (i != NID_pkcs7_signedAndEnveloped)
+ return NULL;
+ if (p7->d.signed_and_enveloped == NULL)
+ return NULL;
+ rsk = p7->d.signed_and_enveloped->recipientinfo;
+ if (rsk == NULL)
+ return NULL;
+ if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
+ return (NULL);
+ ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
+ return (ri->issuer_and_serial);
+}
+
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
+{
+ return (get_attribute(si->auth_attr, nid));
+}
+
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
+{
+ return (get_attribute(si->unauth_attr, nid));
+}
+
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
+{
+ int i;
+ X509_ATTRIBUTE *xa;
+ ASN1_OBJECT *o;
+
+ o = OBJ_nid2obj(nid);
+ if (!o || !sk)
+ return (NULL);
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+ xa = sk_X509_ATTRIBUTE_value(sk, i);
+ if (OBJ_cmp(xa->object, o) == 0) {
+ if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
+ return (sk_ASN1_TYPE_value(xa->value.set, 0));
+ else
+ return (NULL);
+ }
+ }
+ return (NULL);
+}
+
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
+{
+ ASN1_TYPE *astype;
+ if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest)))
+ return NULL;
+ return astype->value.octet_string;
+}
+
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+ STACK_OF(X509_ATTRIBUTE) *sk)
+{
+ int i;
+
+ if (p7si->auth_attr != NULL)
+ sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
+ p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
+ if (p7si->auth_attr == NULL)
+ return 0;
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+ if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
+ X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
+ (sk, i))))
+ == NULL)
+ return (0);
+ }
+ return (1);
+}
+
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
+ STACK_OF(X509_ATTRIBUTE) *sk)
+{
+ int i;
+
+ if (p7si->unauth_attr != NULL)
+ sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
+ p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
+ if (p7si->unauth_attr == NULL)
+ return 0;
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+ if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
+ X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
+ (sk, i))))
+ == NULL)
+ return (0);
+ }
+ return (1);
+}
+
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+ void *value)
+{
+ return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
+}
+
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+ void *value)
+{
+ return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
+}
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+ void *value)
+{
+ X509_ATTRIBUTE *attr = NULL;
+
+ if (*sk == NULL) {
+ *sk = sk_X509_ATTRIBUTE_new_null();
+ if (*sk == NULL)
+ return 0;
+ new_attrib:
+ if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value)))
+ return 0;
+ if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
+ X509_ATTRIBUTE_free(attr);
+ return 0;
+ }
+ } else {
+ int i;
+
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
+ attr = sk_X509_ATTRIBUTE_value(*sk, i);
+ if (OBJ_obj2nid(attr->object) == nid) {
+ X509_ATTRIBUTE_free(attr);
+ attr = X509_ATTRIBUTE_create(nid, atrtype, value);
+ if (attr == NULL)
+ return 0;
+ if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
+ X509_ATTRIBUTE_free(attr);
+ return 0;
+ }
+ goto end;
+ }
+ }
+ goto new_attrib;
+ }
+ end:
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_lib.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_lib.c
new file mode 100644
index 00000000..0c5fcaa6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_lib.c
@@ -0,0 +1,646 @@
+/* crypto/pkcs7/pk7_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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
+{
+ int nid;
+ long ret;
+
+ nid = OBJ_obj2nid(p7->type);
+
+ switch (cmd) {
+ /* NOTE(emilia): does not support detached digested data. */
+ case PKCS7_OP_SET_DETACHED_SIGNATURE:
+ if (nid == NID_pkcs7_signed) {
+ ret = p7->detached = (int)larg;
+ if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
+ ASN1_OCTET_STRING *os;
+ os = p7->d.sign->contents->d.data;
+ ASN1_OCTET_STRING_free(os);
+ p7->d.sign->contents->d.data = NULL;
+ }
+ } else {
+ PKCS7err(PKCS7_F_PKCS7_CTRL,
+ PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+ ret = 0;
+ }
+ break;
+ case PKCS7_OP_GET_DETACHED_SIGNATURE:
+ if (nid == NID_pkcs7_signed) {
+ if (!p7->d.sign || !p7->d.sign->contents->d.ptr)
+ ret = 1;
+ else
+ ret = 0;
+
+ p7->detached = ret;
+ } else {
+ PKCS7err(PKCS7_F_PKCS7_CTRL,
+ PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+ ret = 0;
+ }
+
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION);
+ ret = 0;
+ }
+ return (ret);
+}
+
+int PKCS7_content_new(PKCS7 *p7, int type)
+{
+ PKCS7 *ret = NULL;
+
+ if ((ret = PKCS7_new()) == NULL)
+ goto err;
+ if (!PKCS7_set_type(ret, type))
+ goto err;
+ if (!PKCS7_set_content(p7, ret))
+ goto err;
+
+ return (1);
+ err:
+ if (ret != NULL)
+ PKCS7_free(ret);
+ return (0);
+}
+
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
+{
+ int i;
+
+ i = OBJ_obj2nid(p7->type);
+ switch (i) {
+ case NID_pkcs7_signed:
+ if (p7->d.sign->contents != NULL)
+ PKCS7_free(p7->d.sign->contents);
+ p7->d.sign->contents = p7_data;
+ break;
+ case NID_pkcs7_digest:
+ if (p7->d.digest->contents != NULL)
+ PKCS7_free(p7->d.digest->contents);
+ p7->d.digest->contents = p7_data;
+ break;
+ case NID_pkcs7_data:
+ case NID_pkcs7_enveloped:
+ case NID_pkcs7_signedAndEnveloped:
+ case NID_pkcs7_encrypted:
+ default:
+ PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+ return (1);
+ err:
+ return (0);
+}
+
+int PKCS7_set_type(PKCS7 *p7, int type)
+{
+ ASN1_OBJECT *obj;
+
+ /*
+ * PKCS7_content_free(p7);
+ */
+ obj = OBJ_nid2obj(type); /* will not fail */
+
+ switch (type) {
+ case NID_pkcs7_signed:
+ p7->type = obj;
+ if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
+ goto err;
+ if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
+ PKCS7_SIGNED_free(p7->d.sign);
+ p7->d.sign = NULL;
+ goto err;
+ }
+ break;
+ case NID_pkcs7_data:
+ p7->type = obj;
+ if ((p7->d.data = M_ASN1_OCTET_STRING_new()) == NULL)
+ goto err;
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ p7->type = obj;
+ if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
+ == NULL)
+ goto err;
+ ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
+ if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
+ goto err;
+ p7->d.signed_and_enveloped->enc_data->content_type
+ = OBJ_nid2obj(NID_pkcs7_data);
+ break;
+ case NID_pkcs7_enveloped:
+ p7->type = obj;
+ if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
+ == NULL)
+ goto err;
+ if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
+ goto err;
+ p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
+ break;
+ case NID_pkcs7_encrypted:
+ p7->type = obj;
+ if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
+ == NULL)
+ goto err;
+ if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
+ goto err;
+ p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
+ break;
+
+ case NID_pkcs7_digest:
+ p7->type = obj;
+ if ((p7->d.digest = PKCS7_DIGEST_new())
+ == NULL)
+ goto err;
+ if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
+ goto err;
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+ return (1);
+ err:
+ return (0);
+}
+
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
+{
+ p7->type = OBJ_nid2obj(type);
+ p7->d.other = other;
+ return 1;
+}
+
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
+{
+ int i, j, nid;
+ X509_ALGOR *alg;
+ STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
+ STACK_OF(X509_ALGOR) *md_sk;
+
+ i = OBJ_obj2nid(p7->type);
+ switch (i) {
+ case NID_pkcs7_signed:
+ signer_sk = p7->d.sign->signer_info;
+ md_sk = p7->d.sign->md_algs;
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ signer_sk = p7->d.signed_and_enveloped->signer_info;
+ md_sk = p7->d.signed_and_enveloped->md_algs;
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE);
+ return (0);
+ }
+
+ nid = OBJ_obj2nid(psi->digest_alg->algorithm);
+
+ /* If the digest is not currently listed, add it */
+ j = 0;
+ for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
+ alg = sk_X509_ALGOR_value(md_sk, i);
+ if (OBJ_obj2nid(alg->algorithm) == nid) {
+ j = 1;
+ break;
+ }
+ }
+ if (!j) { /* we need to add another algorithm */
+ if (!(alg = X509_ALGOR_new())
+ || !(alg->parameter = ASN1_TYPE_new())) {
+ X509_ALGOR_free(alg);
+ PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ alg->algorithm = OBJ_nid2obj(nid);
+ alg->parameter->type = V_ASN1_NULL;
+ if (!sk_X509_ALGOR_push(md_sk, alg)) {
+ X509_ALGOR_free(alg);
+ return 0;
+ }
+ }
+
+ if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
+ return 0;
+ return (1);
+}
+
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
+{
+ int i;
+ STACK_OF(X509) **sk;
+
+ i = OBJ_obj2nid(p7->type);
+ switch (i) {
+ case NID_pkcs7_signed:
+ sk = &(p7->d.sign->cert);
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ sk = &(p7->d.signed_and_enveloped->cert);
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE);
+ return (0);
+ }
+
+ if (*sk == NULL)
+ *sk = sk_X509_new_null();
+ if (*sk == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
+ if (!sk_X509_push(*sk, x509)) {
+ X509_free(x509);
+ return 0;
+ }
+ return (1);
+}
+
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
+{
+ int i;
+ STACK_OF(X509_CRL) **sk;
+
+ i = OBJ_obj2nid(p7->type);
+ switch (i) {
+ case NID_pkcs7_signed:
+ sk = &(p7->d.sign->crl);
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ sk = &(p7->d.signed_and_enveloped->crl);
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE);
+ return (0);
+ }
+
+ if (*sk == NULL)
+ *sk = sk_X509_CRL_new_null();
+ if (*sk == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+ if (!sk_X509_CRL_push(*sk, crl)) {
+ X509_CRL_free(crl);
+ return 0;
+ }
+ return (1);
+}
+
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+ const EVP_MD *dgst)
+{
+ int ret;
+
+ /* We now need to add another PKCS7_SIGNER_INFO entry */
+ if (!ASN1_INTEGER_set(p7i->version, 1))
+ goto err;
+ if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+ X509_get_issuer_name(x509)))
+ goto err;
+
+ /*
+ * because ASN1_INTEGER_set is used to set a 'long' we will do things the
+ * ugly way.
+ */
+ M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+ if (!(p7i->issuer_and_serial->serial =
+ M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
+ goto err;
+
+ /* lets keep the pkey around for a while */
+ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ p7i->pkey = pkey;
+
+ /* Set the algorithms */
+
+ X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
+ V_ASN1_NULL, NULL);
+
+ if (pkey->ameth && pkey->ameth->pkey_ctrl) {
+ 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;
+ }
+ }
+ PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+ PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ err:
+ return 0;
+}
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
+ const EVP_MD *dgst)
+{
+ 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:
+ if (si)
+ PKCS7_SIGNER_INFO_free(si);
+ return (NULL);
+}
+
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
+{
+ if (PKCS7_type_is_digest(p7)) {
+ if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) {
+ PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ p7->d.digest->md->parameter->type = V_ASN1_NULL;
+ p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
+ return 1;
+ }
+
+ PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE);
+ return 1;
+}
+
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
+{
+ if (p7 == NULL || p7->d.ptr == NULL)
+ return NULL;
+ if (PKCS7_type_is_signed(p7)) {
+ return (p7->d.sign->signer_info);
+ } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
+ return (p7->d.signed_and_enveloped->signer_info);
+ } else
+ 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;
+
+ 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;
+ err:
+ if (ri)
+ PKCS7_RECIP_INFO_free(ri);
+ return NULL;
+}
+
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
+{
+ int i;
+ STACK_OF(PKCS7_RECIP_INFO) *sk;
+
+ i = OBJ_obj2nid(p7->type);
+ switch (i) {
+ case NID_pkcs7_signedAndEnveloped:
+ sk = p7->d.signed_and_enveloped->recipientinfo;
+ break;
+ case NID_pkcs7_enveloped:
+ sk = p7->d.enveloped->recipientinfo;
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
+ PKCS7_R_WRONG_CONTENT_TYPE);
+ return (0);
+ }
+
+ if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
+ return 0;
+ return (1);
+}
+
+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,
+ X509_get_issuer_name(x509)))
+ return 0;
+
+ M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+ if (!(p7i->issuer_and_serial->serial =
+ M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
+ 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;
+
+ err:
+ if (pkey)
+ EVP_PKEY_free(pkey);
+ return 0;
+}
+
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+ if (PKCS7_type_is_signed(p7))
+ return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
+ si->issuer_and_serial->issuer,
+ si->
+ issuer_and_serial->serial));
+ else
+ return (NULL);
+}
+
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
+{
+ int i;
+ PKCS7_ENC_CONTENT *ec;
+
+ i = OBJ_obj2nid(p7->type);
+ switch (i) {
+ case NID_pkcs7_signedAndEnveloped:
+ ec = p7->d.signed_and_enveloped->enc_data;
+ break;
+ case NID_pkcs7_enveloped:
+ ec = p7->d.enveloped->enc_data;
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE);
+ return (0);
+ }
+
+ /* Check cipher OID exists and has data in it */
+ i = EVP_CIPHER_type(cipher);
+ if (i == NID_undef) {
+ PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,
+ PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+ return (0);
+ }
+
+ ec->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/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c
new file mode 100644
index 00000000..62fb2997
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c
@@ -0,0 +1,96 @@
+/* pk7_mime.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+/* PKCS#7 wrappers round generalised stream and MIME routines */
+
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+{
+ return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
+ ASN1_ITEM_rptr(PKCS7));
+}
+
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+{
+ 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)
+{
+ STACK_OF(X509_ALGOR) *mdalgs;
+ int ctype_nid = OBJ_obj2nid(p7->type);
+ if (ctype_nid == NID_pkcs7_signed)
+ mdalgs = p7->d.sign->md_algs;
+ else
+ mdalgs = NULL;
+
+ flags ^= SMIME_OLDMIME;
+
+ return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
+ ctype_nid, NID_undef, mdalgs,
+ 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/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c
new file mode 100644
index 00000000..e75c4b23
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c
@@ -0,0 +1,603 @@
+/* pk7_smime.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 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).
+ *
+ */
+
+/* Simple PKCS#7 processing functions */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#define BUFFERSIZE 4096
+
+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;
+ int i;
+
+ 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;
+
+ if (!PKCS7_content_new(p7, NID_pkcs7_data))
+ goto err;
+
+ 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)) {
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
+ goto err;
+ }
+ }
+
+ 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))) {
+ PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ SMIME_crlf_copy(data, p7bio, flags);
+
+ (void)BIO_flush(p7bio);
+
+ 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;
+
+}
+
+/* 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;
+}
+
+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;
+}
+
+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)
+{
+ STACK_OF(X509) *signers;
+ X509 *signer;
+ STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+ PKCS7_SIGNER_INFO *si;
+ X509_STORE_CTX cert_ctx;
+ char *buf = NULL;
+ int i, j = 0, k, ret = 0;
+ BIO *p7bio = NULL;
+ BIO *tmpin = NULL, *tmpout = NULL;
+
+ if (!p7) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (!PKCS7_type_is_signed(p7)) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE);
+ return 0;
+ }
+
+ /* Check for no data and no content: no data to verify signature */
+ if (PKCS7_get_detached(p7) && !indata) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+#if 0
+ /*
+ * NB: this test commented out because some versions of Netscape
+ * illegally include zero length content when signing data. Also
+ * Microsoft Authenticode includes a SpcIndirectDataContent data
+ * structure which describes the content to be protected by the
+ * signature, rather than directly embedding that content. So
+ * Authenticode implementations are also expected to use
+ * PKCS7_verify() with explicit external data, on non-detached
+ * PKCS#7 signatures.
+ *
+ * In OpenSSL 1.1 a new flag PKCS7_NO_DUAL_CONTENT has been
+ * introduced to disable this sanity check. For the 1.0.2 branch
+ * this change is not acceptable, so the check remains completely
+ * commented out (as it has been for a long time).
+ */
+
+ /* Check for data and content: two sets of data */
+ if (!PKCS7_get_detached(p7) && indata) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT);
+ return 0;
+ }
+#endif
+
+ sinfos = PKCS7_get_signer_info(p7);
+
+ if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA);
+ return 0;
+ }
+
+ signers = PKCS7_get0_signers(p7, certs, flags);
+ if (!signers)
+ return 0;
+
+ /* Now verify the certificates */
+
+ if (!(flags & PKCS7_NOVERIFY))
+ for (k = 0; k < sk_X509_num(signers); k++) {
+ signer = sk_X509_value(signers, k);
+ if (!(flags & PKCS7_NOCHAIN)) {
+ if (!X509_STORE_CTX_init(&cert_ctx, store, signer,
+ p7->d.sign->cert)) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+ goto err;
+ }
+ X509_STORE_CTX_set_default(&cert_ctx, "smime_sign");
+ } else if (!X509_STORE_CTX_init(&cert_ctx, store, signer, NULL)) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+ goto err;
+ }
+ if (!(flags & PKCS7_NOCRL))
+ X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl);
+ i = X509_verify_cert(&cert_ctx);
+ if (i <= 0)
+ j = X509_STORE_CTX_get_error(&cert_ctx);
+ X509_STORE_CTX_cleanup(&cert_ctx);
+ if (i <= 0) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY,
+ PKCS7_R_CERTIFICATE_VERIFY_ERROR);
+ ERR_add_error_data(2, "Verify error:",
+ X509_verify_cert_error_string(j));
+ goto err;
+ }
+ /* Check for revocation status here */
+ }
+
+ /*
+ * Performance optimization: if the content is a memory BIO then store
+ * its contents in a temporary read only memory BIO. This avoids
+ * potentially large numbers of slow copies of data which will occur when
+ * reading from a read write memory BIO when signatures are calculated.
+ */
+
+ if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
+ char *ptr;
+ long len;
+ len = BIO_get_mem_data(indata, &ptr);
+ tmpin = BIO_new_mem_buf(ptr, len);
+ if (tmpin == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else
+ tmpin = indata;
+
+ if (!(p7bio = PKCS7_dataInit(p7, tmpin)))
+ goto err;
+
+ if (flags & PKCS7_TEXT) {
+ if (!(tmpout = BIO_new(BIO_s_mem()))) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ BIO_set_mem_eof_return(tmpout, 0);
+ } else
+ tmpout = out;
+
+ /* We now have to 'read' from p7bio to calculate digests etc. */
+ if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ for (;;) {
+ i = BIO_read(p7bio, buf, BUFFERSIZE);
+ if (i <= 0)
+ break;
+ if (tmpout)
+ BIO_write(tmpout, buf, i);
+ }
+
+ if (flags & PKCS7_TEXT) {
+ if (!SMIME_text(tmpout, out)) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR);
+ BIO_free(tmpout);
+ goto err;
+ }
+ BIO_free(tmpout);
+ }
+
+ /* Now Verify All Signatures */
+ if (!(flags & PKCS7_NOSIGS))
+ for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+ si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+ signer = sk_X509_value(signers, i);
+ j = PKCS7_signatureVerify(p7bio, p7, si, signer);
+ if (j <= 0) {
+ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE);
+ goto err;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ OPENSSL_free(buf);
+ if (tmpin == indata) {
+ if (indata)
+ BIO_pop(p7bio);
+ }
+ BIO_free_all(p7bio);
+ sk_X509_free(signers);
+ return ret;
+}
+
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
+ int flags)
+{
+ STACK_OF(X509) *signers;
+ STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+ PKCS7_SIGNER_INFO *si;
+ PKCS7_ISSUER_AND_SERIAL *ias;
+ X509 *signer;
+ int i;
+
+ if (!p7) {
+ PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+
+ if (!PKCS7_type_is_signed(p7)) {
+ PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE);
+ return NULL;
+ }
+
+ /* Collect all the signers together */
+
+ sinfos = PKCS7_get_signer_info(p7);
+
+ if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
+ PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS);
+ return 0;
+ }
+
+ if (!(signers = sk_X509_new_null())) {
+ PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+ si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+ ias = si->issuer_and_serial;
+ signer = NULL;
+ /* If any certificates passed they take priority */
+ if (certs)
+ signer = X509_find_by_issuer_and_serial(certs,
+ ias->issuer, ias->serial);
+ if (!signer && !(flags & PKCS7_NOINTERN)
+ && p7->d.sign->cert)
+ signer =
+ X509_find_by_issuer_and_serial(p7->d.sign->cert,
+ ias->issuer, ias->serial);
+ if (!signer) {
+ PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
+ PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
+ sk_X509_free(signers);
+ return 0;
+ }
+
+ if (!sk_X509_push(signers, signer)) {
+ sk_X509_free(signers);
+ return NULL;
+ }
+ }
+ return signers;
+}
+
+/* Build a complete PKCS#7 enveloped data */
+
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+ int flags)
+{
+ PKCS7 *p7;
+ BIO *p7bio = NULL;
+ int i;
+ X509 *x509;
+ if (!(p7 = PKCS7_new())) {
+ PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
+ goto err;
+ if (!PKCS7_set_cipher(p7, cipher)) {
+ PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER);
+ goto err;
+ }
+
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ x509 = sk_X509_value(certs, i);
+ if (!PKCS7_add_recipient(p7, x509)) {
+ PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT);
+ goto err;
+ }
+ }
+
+ if (flags & PKCS7_STREAM)
+ return p7;
+
+ if (PKCS7_final(p7, in, flags))
+ return p7;
+
+ err:
+
+ BIO_free_all(p7bio);
+ PKCS7_free(p7);
+ return NULL;
+
+}
+
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
+{
+ BIO *tmpmem;
+ int ret, i;
+ char *buf = NULL;
+
+ if (!p7) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (!PKCS7_type_is_enveloped(p7)) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE);
+ return 0;
+ }
+
+ if (cert && !X509_check_private_key(cert, pkey)) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT,
+ PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+ return 0;
+ }
+
+ if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
+ return 0;
+ }
+
+ if (flags & PKCS7_TEXT) {
+ BIO *tmpbuf, *bread;
+ /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
+ if (!(tmpbuf = BIO_new(BIO_f_buffer()))) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+ BIO_free_all(tmpmem);
+ return 0;
+ }
+ if (!(bread = BIO_push(tmpbuf, tmpmem))) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+ BIO_free_all(tmpbuf);
+ BIO_free_all(tmpmem);
+ return 0;
+ }
+ ret = SMIME_text(bread, data);
+ if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
+ if (!BIO_get_cipher_status(tmpmem))
+ ret = 0;
+ }
+ BIO_free_all(bread);
+ return ret;
+ }
+ if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ for (;;) {
+ i = BIO_read(tmpmem, buf, BUFFERSIZE);
+ if (i <= 0) {
+ ret = 1;
+ if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
+ if (!BIO_get_cipher_status(tmpmem))
+ ret = 0;
+ }
+
+ break;
+ }
+ if (BIO_write(data, buf, i) != i) {
+ ret = 0;
+ break;
+ }
+ }
+
+err:
+ OPENSSL_free(buf);
+ BIO_free_all(tmpmem);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/pkcs7err.c b/Cryptlib/OpenSSL/crypto/pkcs7/pkcs7err.c
new file mode 100644
index 00000000..323513fe
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pkcs7err.c
@@ -0,0 +1,207 @@
+/* crypto/pkcs7/pkcs7err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2014 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs7.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
+
+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"},
+ {ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"},
+ {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"},
+ {ERR_FUNC(PKCS7_F_SMIME_TEXT), "SMIME_text"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA PKCS7_str_reasons[] = {
+ {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR),
+ "certificate verify error"},
+ {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"},
+ {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"},
+ {ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE),
+ "invalid signed data type"},
+ {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
+ {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR), "mime parse error"},
+ {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
+ {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"},
+ {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY),
+ "no recipient matches key"},
+ {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"},
+ {ERR_REASON(PKCS7_R_NO_SIGNERS), "no signers"},
+ {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"},
+ {ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR), "pkcs7 parse error"},
+ {ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"},
+ {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"},
+ {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"},
+ {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST),
+ "unable to find message digest"},
+ {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE), "unknown digest type"},
+ {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION), "unknown operation"},
+ {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"},
+ {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE),
+ "unsupported content type"},
+ {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE), "wrong content type"},
+ {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_PKCS7_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, PKCS7_str_functs);
+ ERR_load_strings(0, PKCS7_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/rand/md_rand.c b/Cryptlib/OpenSSL/crypto/rand/md_rand.c
new file mode 100644
index 00000000..5c13d577
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rand/md_rand.c
@@ -0,0 +1,592 @@
+/* crypto/rand/md_rand.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).
+ *
+ */
+
+#define OPENSSL_FIPSEVP
+
+#ifdef MD_RAND_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#include <openssl/err.h>
+
+#ifdef BN_DEBUG
+# define PREDICT
+#endif
+
+/* #define PREDICT 1 */
+
+#define STATE_SIZE 1023
+static int state_num = 0, state_index = 0;
+static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH];
+static unsigned char md[MD_DIGEST_LENGTH];
+static long md_count[2] = { 0, 0 };
+
+static double entropy = 0;
+static int initialized = 0;
+
+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 */
+/* valid iff crypto_lock_rand is set */
+static CRYPTO_THREADID locking_threadid;
+
+#ifdef PREDICT
+int rand_predictable = 0;
+#endif
+
+const char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT;
+
+static void ssleay_rand_cleanup(void);
+static void ssleay_rand_seed(const void *buf, int num);
+static void ssleay_rand_add(const void *buf, int num, double add_entropy);
+static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
+static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
+static int ssleay_rand_status(void);
+
+RAND_METHOD rand_ssleay_meth = {
+ ssleay_rand_seed,
+ ssleay_rand_nopseudo_bytes,
+ ssleay_rand_cleanup,
+ ssleay_rand_add,
+ ssleay_rand_pseudo_bytes,
+ ssleay_rand_status
+};
+
+RAND_METHOD *RAND_SSLeay(void)
+{
+ return (&rand_ssleay_meth);
+}
+
+static void ssleay_rand_cleanup(void)
+{
+ OPENSSL_cleanse(state, sizeof(state));
+ state_num = 0;
+ state_index = 0;
+ OPENSSL_cleanse(md, MD_DIGEST_LENGTH);
+ md_count[0] = 0;
+ md_count[1] = 0;
+ entropy = 0;
+ initialized = 0;
+}
+
+static void ssleay_rand_add(const void *buf, int num, double add)
+{
+ int i, j, k, st_idx;
+ long md_c[2];
+ unsigned char local_md[MD_DIGEST_LENGTH];
+ EVP_MD_CTX m;
+ int do_not_lock;
+
+ if (!num)
+ return;
+
+ /*
+ * (Based on the rand(3) manpage)
+ *
+ * The input is chopped up into units of 20 bytes (or less for
+ * the last block). Each of these blocks is run through the hash
+ * function as follows: The data passed to the hash function
+ * is the current 'md', the same number of bytes from the 'state'
+ * (the location determined by in incremented looping index) as
+ * the current 'block', the new key data 'block', and 'count'
+ * (which is incremented after each use).
+ * The result of this is kept in 'md' and also xored into the
+ * 'state' at the same locations that were used as input into the
+ * hash function.
+ */
+
+ /* 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 = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
+ } else
+ do_not_lock = 0;
+
+ if (!do_not_lock)
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ st_idx = state_index;
+
+ /*
+ * use our own copies of the counters so that even if a concurrent thread
+ * seeds with exactly the same data and uses the same subarray there's
+ * _some_ difference
+ */
+ md_c[0] = md_count[0];
+ md_c[1] = md_count[1];
+
+ memcpy(local_md, md, sizeof md);
+
+ /* state_index <= state_num <= STATE_SIZE */
+ state_index += num;
+ if (state_index >= STATE_SIZE) {
+ state_index %= STATE_SIZE;
+ state_num = STATE_SIZE;
+ } else if (state_num < STATE_SIZE) {
+ if (state_index > state_num)
+ state_num = state_index;
+ }
+ /* state_index <= state_num <= STATE_SIZE */
+
+ /*
+ * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we
+ * will use now, but other threads may use them as well
+ */
+
+ md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
+
+ if (!do_not_lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ EVP_MD_CTX_init(&m);
+ for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
+ j = (num - i);
+ j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
+
+ MD_Init(&m);
+ MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ k = (st_idx + j) - STATE_SIZE;
+ if (k > 0) {
+ MD_Update(&m, &(state[st_idx]), j - k);
+ MD_Update(&m, &(state[0]), k);
+ } 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]++;
+
+ buf = (const char *)buf + j;
+
+ for (k = 0; k < j; k++) {
+ /*
+ * Parallel threads may interfere with this, but always each byte
+ * of the new state is the XOR of some previous value of its and
+ * local_md (itermediate values may be lost). Alway using locking
+ * could hurt performance more than necessary given that
+ * conflicts occur only when the total seeding is longer than the
+ * random state.
+ */
+ state[st_idx++] ^= local_md[k];
+ if (st_idx >= STATE_SIZE)
+ st_idx = 0;
+ }
+ }
+ EVP_MD_CTX_cleanup(&m);
+
+ if (!do_not_lock)
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ /*
+ * Don't just copy back local_md into md -- this could mean that other
+ * thread's seeding remains without effect (except for the incremented
+ * counter). By XORing it we keep at least as much entropy as fits into
+ * md.
+ */
+ for (k = 0; k < (int)sizeof(md); k++) {
+ md[k] ^= local_md[k];
+ }
+ if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
+ entropy += add;
+ if (!do_not_lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
+ assert(md_c[1] == md_count[1]);
+#endif
+}
+
+static void ssleay_rand_seed(const void *buf, int num)
+{
+ ssleay_rand_add(buf, num, (double)num);
+}
+
+int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
+{
+ static volatile int stirred_pool = 0;
+ int i, j, k, st_num, st_idx;
+ int num_ceil;
+ int ok;
+ long md_c[2];
+ unsigned char local_md[MD_DIGEST_LENGTH];
+ EVP_MD_CTX m;
+#ifndef GETPID_IS_MEANINGLESS
+ pid_t curr_pid = getpid();
+#endif
+ int do_stir_pool = 0;
+
+#ifdef PREDICT
+ if (rand_predictable) {
+ static unsigned char val = 0;
+
+ for (i = 0; i < num; i++)
+ buf[i] = val++;
+ return (1);
+ }
+#endif
+
+ if (num <= 0)
+ return 1;
+
+ EVP_MD_CTX_init(&m);
+ /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
+ num_ceil =
+ (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
+
+ /*
+ * (Based on the rand(3) manpage:)
+ *
+ * For each group of 10 bytes (or less), we do the following:
+ *
+ * Input into the hash function the local 'md' (which is initialized from
+ * the global 'md' before any bytes are generated), the bytes that are to
+ * be overwritten by the random bytes, and bytes from the 'state'
+ * (incrementing looping index). From this digest output (which is kept
+ * in 'md'), the top (up to) 10 bytes are returned to the caller and the
+ * bottom 10 bytes are xored into the 'state'.
+ *
+ * Finally, after we have finished 'num' random bytes for the
+ * caller, 'count' (which is incremented) and the local and global 'md'
+ * are fed into the hash function and the results are kept in the
+ * global 'md'.
+ */
+ if (lock)
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
+ CRYPTO_THREADID_current(&locking_threadid);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
+ crypto_lock_rand = 1;
+
+ if (!initialized) {
+ RAND_poll();
+ initialized = 1;
+ }
+
+ if (!stirred_pool)
+ do_stir_pool = 1;
+
+ ok = (entropy >= ENTROPY_NEEDED);
+ if (!ok) {
+ /*
+ * If the PRNG state is not yet unpredictable, then seeing the PRNG
+ * output may help attackers to determine the new state; thus we have
+ * to decrease the entropy estimate. Once we've had enough initial
+ * seeding we don't bother to adjust the entropy count, though,
+ * because we're not ambitious to provide *information-theoretic*
+ * randomness. NOTE: This approach fails if the program forks before
+ * we have enough entropy. Entropy should be collected in a separate
+ * input pool and be transferred to the output pool only when the
+ * entropy limit has been reached.
+ */
+ entropy -= num;
+ if (entropy < 0)
+ entropy = 0;
+ }
+
+ if (do_stir_pool) {
+ /*
+ * In the output function only half of 'md' remains secret, so we
+ * better make sure that the required entropy gets 'evenly
+ * distributed' through 'state', our randomness pool. The input
+ * function (ssleay_rand_add) chains all of 'md', which makes it more
+ * suitable for this purpose.
+ */
+
+ int n = STATE_SIZE; /* so that the complete pool gets accessed */
+ while (n > 0) {
+#if MD_DIGEST_LENGTH > 20
+# error "Please adjust DUMMY_SEED."
+#endif
+#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
+ /*
+ * Note that the seed does not matter, it's just that
+ * ssleay_rand_add expects to have something to hash.
+ */
+ ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
+ n -= MD_DIGEST_LENGTH;
+ }
+ if (ok)
+ stirred_pool = 1;
+ }
+
+ st_idx = state_index;
+ st_num = state_num;
+ md_c[0] = md_count[0];
+ md_c[1] = md_count[1];
+ memcpy(local_md, md, sizeof md);
+
+ state_index += num_ceil;
+ if (state_index > state_num)
+ state_index %= state_num;
+
+ /*
+ * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now
+ * ours (but other threads may use them too)
+ */
+
+ md_count[0] += 1;
+
+ /* before unlocking, we must clear 'crypto_lock_rand' */
+ crypto_lock_rand = 0;
+ if (lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ while (num > 0) {
+ /* num_ceil -= MD_DIGEST_LENGTH/2 */
+ j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
+ num -= j;
+ MD_Init(&m);
+#ifndef GETPID_IS_MEANINGLESS
+ if (curr_pid) { /* just in the first iteration to save time */
+ MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid);
+ curr_pid = 0;
+ }
+#endif
+ MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
+
+#ifndef PURIFY /* purify complains */
+ /*
+ * The following line uses the supplied buffer as a small source of
+ * entropy: since this buffer is often uninitialised it may cause
+ * programs such as purify or valgrind to complain. So for those
+ * builds it is not used: the removal of such a small source of
+ * entropy has negligible impact on security.
+ */
+ MD_Update(&m, buf, j);
+#endif
+
+ k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
+ if (k > 0) {
+ MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k);
+ MD_Update(&m, &(state[0]), k);
+ } else
+ MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2);
+ MD_Final(&m, local_md);
+
+ for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
+ /* may compete with other threads */
+ state[st_idx++] ^= local_md[i];
+ if (st_idx >= st_num)
+ st_idx = 0;
+ if (i < j)
+ *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2];
+ }
+ }
+
+ MD_Init(&m);
+ MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
+ MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ if (lock)
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ MD_Update(&m, md, MD_DIGEST_LENGTH);
+ MD_Final(&m, md);
+ if (lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ EVP_MD_CTX_cleanup(&m);
+ if (ok)
+ return (1);
+ else if (pseudo)
+ return 0;
+ else {
+ RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
+ ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
+ "http://www.openssl.org/support/faq.html");
+ return (0);
+ }
+}
+
+static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
+{
+ return ssleay_rand_bytes(buf, num, 0, 1);
+}
+
+/*
+ * pseudo-random bytes that are guaranteed to be unique but not unpredictable
+ */
+static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
+{
+ return ssleay_rand_bytes(buf, num, 1, 1);
+}
+
+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 = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
+ } else
+ do_not_lock = 0;
+
+ if (!do_not_lock) {
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ /*
+ * prevent ssleay_rand_bytes() from trying to obtain the lock again
+ */
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
+ CRYPTO_THREADID_cpy(&locking_threadid, &cur);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
+ crypto_lock_rand = 1;
+ }
+
+ if (!initialized) {
+ RAND_poll();
+ initialized = 1;
+ }
+
+ ret = entropy >= ENTROPY_NEEDED;
+
+ if (!do_not_lock) {
+ /* before unlocking, we must clear 'crypto_lock_rand' */
+ crypto_lock_rand = 0;
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ }
+
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/rand/rand_err.c b/Cryptlib/OpenSSL/crypto/rand/rand_err.c
new file mode 100644
index 00000000..55d86ea8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rand/rand_err.c
@@ -0,0 +1,100 @@
+/* crypto/rand/rand_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
+
+static ERR_STRING_DATA RAND_str_functs[] = {
+ {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
+ {ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"},
+ {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA RAND_str_reasons[] = {
+ {ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"},
+ {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"},
+ {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"},
+ {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),
+ "no fips random method set"},
+ {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_RAND_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, RAND_str_functs);
+ ERR_load_strings(0, RAND_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/rand/rand_lcl.h b/Cryptlib/OpenSSL/crypto/rand/rand_lcl.h
new file mode 100644
index 00000000..f9fda3eb
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rand/rand_lcl.h
@@ -0,0 +1,158 @@
+/* crypto/rand/rand_lcl.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.]
+ */
+/* ====================================================================
+ * 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_RAND_LCL_H
+# define HEADER_RAND_LCL_H
+
+# define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */
+
+# if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+# define USE_SHA1_RAND
+# elif !defined(OPENSSL_NO_MD5)
+# define USE_MD5_RAND
+# elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
+# define USE_MDC2_RAND
+# elif !defined(OPENSSL_NO_MD2)
+# define USE_MD2_RAND
+# else
+# error No message digest algorithm available
+# endif
+# endif
+
+# include <openssl/evp.h>
+# define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c)
+# define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL)
+# if defined(USE_MD5_RAND)
+# include <openssl/md5.h>
+# define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH
+# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL)
+# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
+# elif defined(USE_SHA1_RAND)
+# include <openssl/sha.h>
+# define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH
+# define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL)
+# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
+# elif defined(USE_MDC2_RAND)
+# include <openssl/mdc2.h>
+# define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH
+# define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
+# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
+# elif defined(USE_MD2_RAND)
+# include <openssl/md2.h>
+# define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH
+# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL)
+# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
+# endif
+
+int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock);
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rand/rand_lib.c b/Cryptlib/OpenSSL/crypto/rand/rand_lib.c
new file mode 100644
index 00000000..88a78d35
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rand/rand_lib.c
@@ -0,0 +1,300 @@
+/* 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 <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include <openssl/fips_rand.h>
+# include "rand_lcl.h"
+#endif
+
+#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)
+{
+#ifndef OPENSSL_NO_ENGINE
+ if (funct_ref) {
+ ENGINE_finish(funct_ref);
+ funct_ref = NULL;
+ }
+#endif
+ default_RAND_meth = meth;
+ return 1;
+}
+
+const RAND_METHOD *RAND_get_rand_method(void)
+{
+ if (!default_RAND_meth) {
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = ENGINE_get_default_RAND();
+ if (e) {
+ default_RAND_meth = ENGINE_get_RAND(e);
+ if (!default_RAND_meth) {
+ ENGINE_finish(e);
+ e = NULL;
+ }
+ }
+ if (e)
+ funct_ref = e;
+ else
+#endif
+ default_RAND_meth = RAND_SSLeay();
+ }
+ return default_RAND_meth;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+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;
+}
+#endif
+
+void RAND_cleanup(void)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->cleanup)
+ meth->cleanup();
+ RAND_set_rand_method(NULL);
+}
+
+void RAND_seed(const void *buf, int num)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->seed)
+ meth->seed(buf, num);
+}
+
+void RAND_add(const void *buf, int num, double entropy)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->add)
+ meth->add(buf, num, entropy);
+}
+
+int RAND_bytes(unsigned char *buf, int num)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->bytes)
+ return meth->bytes(buf, num);
+ return (-1);
+}
+
+int RAND_pseudo_bytes(unsigned char *buf, int num)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->pseudorand)
+ return meth->pseudorand(buf, num);
+ return (-1);
+}
+
+int RAND_status(void)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->status)
+ return meth->status();
+ return 0;
+}
+
+#ifdef OPENSSL_FIPS
+
+/*
+ * FIPS DRBG initialisation code. This sets up the DRBG for use by the rest
+ * of OpenSSL.
+ */
+
+/*
+ * Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
+ * entropy internally through RAND_poll().
+ */
+
+static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
+ int entropy, size_t min_len, size_t max_len)
+{
+ /* Round up request to multiple of block size */
+ min_len = ((min_len + 19) / 20) * 20;
+ *pout = OPENSSL_malloc(min_len);
+ if (!*pout)
+ return 0;
+ if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) {
+ OPENSSL_free(*pout);
+ *pout = NULL;
+ return 0;
+ }
+ return min_len;
+}
+
+static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
+{
+ if (out) {
+ OPENSSL_cleanse(out, olen);
+ OPENSSL_free(out);
+ }
+}
+
+/*
+ * Set "additional input" when generating random data. This uses the current
+ * PID, a time value and a counter.
+ */
+
+static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
+{
+ /* Use of static variables is OK as this happens under a lock */
+ static unsigned char buf[16];
+ static unsigned long counter;
+ FIPS_get_timevec(buf, &counter);
+ *pout = buf;
+ return sizeof(buf);
+}
+
+/*
+ * RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
+ * correctly seeded by RAND_poll().
+ */
+
+static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
+ double entropy)
+{
+ RAND_SSLeay()->add(in, inlen, entropy);
+ return 1;
+}
+
+static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
+{
+ RAND_SSLeay()->seed(in, inlen);
+ return 1;
+}
+
+# ifndef OPENSSL_DRBG_DEFAULT_TYPE
+# define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
+# endif
+# ifndef OPENSSL_DRBG_DEFAULT_FLAGS
+# define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
+# endif
+
+static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
+static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
+
+void RAND_set_fips_drbg_type(int type, int flags)
+{
+ fips_drbg_type = type;
+ fips_drbg_flags = flags;
+}
+
+int RAND_init_fips(void)
+{
+ DRBG_CTX *dctx;
+ size_t plen;
+ unsigned char pers[32], *p;
+# ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
+ if (fips_drbg_type >> 16) {
+ RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
+ return 0;
+ }
+# endif
+
+ dctx = FIPS_get_default_drbg();
+ if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) {
+ RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
+ return 0;
+ }
+
+ FIPS_drbg_set_callbacks(dctx,
+ drbg_get_entropy, drbg_free_entropy, 20,
+ drbg_get_entropy, drbg_free_entropy);
+ FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
+ drbg_rand_seed, drbg_rand_add);
+ /* Personalisation string: a string followed by date time vector */
+ strcpy((char *)pers, "OpenSSL DRBG2.0");
+ plen = drbg_get_adin(dctx, &p);
+ memcpy(pers + 16, p, plen);
+
+ if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) {
+ RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
+ return 0;
+ }
+ FIPS_rand_set_method(FIPS_drbg_method());
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rand/rand_unix.c b/Cryptlib/OpenSSL/crypto/rand/rand_unix.c
new file mode 100644
index 00000000..f60fac6c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rand/rand_unix.c
@@ -0,0 +1,447 @@
+/* crypto/rand/rand_unix.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-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 <stdio.h>
+
+#define USE_SOCKETS
+#include "e_os.h"
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_UEFI))
+
+# include <sys/types.h>
+# include <sys/time.h>
+# include <sys/times.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+# include <time.h>
+# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
+ * everywhere */
+# include <poll.h>
+# endif
+# include <limits.h>
+# ifndef FD_SETSIZE
+# define FD_SETSIZE (8*sizeof(fd_set))
+# endif
+
+# if defined(OPENSSL_SYS_VOS)
+
+/*
+ * The following algorithm repeatedly samples the real-time clock (RTC) to
+ * generate a sequence of unpredictable data. The algorithm relies upon the
+ * uneven execution speed of the code (due to factors such as cache misses,
+ * interrupts, bus activity, and scheduling) and upon the rather large
+ * relative difference between the speed of the clock and the rate at which
+ * it can be read.
+ *
+ * If this code is ported to an environment where execution speed is more
+ * constant or where the RTC ticks at a much slower rate, or the clock can be
+ * read with fewer instructions, it is likely that the results would be far
+ * more predictable.
+ *
+ * As a precaution, we generate 4 times the minimum required amount of seed
+ * data.
+ */
+
+int RAND_poll(void)
+{
+ short int code;
+ gid_t curr_gid;
+ pid_t curr_pid;
+ uid_t curr_uid;
+ int i, k;
+ struct timespec ts;
+ unsigned char v;
+
+# ifdef OPENSSL_SYS_VOS_HPPA
+ long duration;
+ extern void s$sleep(long *_duration, short int *_code);
+# else
+# ifdef OPENSSL_SYS_VOS_IA32
+ long long duration;
+ extern void s$sleep2(long long *_duration, short int *_code);
+# else
+# error "Unsupported Platform."
+# endif /* OPENSSL_SYS_VOS_IA32 */
+# endif /* OPENSSL_SYS_VOS_HPPA */
+
+ /*
+ * Seed with the gid, pid, and uid, to ensure *some* variation between
+ * different processes.
+ */
+
+ curr_gid = getgid();
+ RAND_add(&curr_gid, sizeof curr_gid, 1);
+ curr_gid = 0;
+
+ curr_pid = getpid();
+ RAND_add(&curr_pid, sizeof curr_pid, 1);
+ curr_pid = 0;
+
+ curr_uid = getuid();
+ RAND_add(&curr_uid, sizeof curr_uid, 1);
+ curr_uid = 0;
+
+ for (i = 0; i < (ENTROPY_NEEDED * 4); i++) {
+ /*
+ * burn some cpu; hope for interrupts, cache collisions, bus
+ * interference, etc.
+ */
+ for (k = 0; k < 99; k++)
+ ts.tv_nsec = random();
+
+# ifdef OPENSSL_SYS_VOS_HPPA
+ /* sleep for 1/1024 of a second (976 us). */
+ duration = 1;
+ s$sleep(&duration, &code);
+# else
+# ifdef OPENSSL_SYS_VOS_IA32
+ /* sleep for 1/65536 of a second (15 us). */
+ duration = 1;
+ s$sleep2(&duration, &code);
+# endif /* OPENSSL_SYS_VOS_IA32 */
+# endif /* OPENSSL_SYS_VOS_HPPA */
+
+ /* get wall clock time. */
+ clock_gettime(CLOCK_REALTIME, &ts);
+
+ /* take 8 bits */
+ v = (unsigned char)(ts.tv_nsec % 256);
+ RAND_add(&v, sizeof v, 1);
+ v = 0;
+ }
+ return 1;
+}
+# elif defined __OpenBSD__
+int RAND_poll(void)
+{
+ u_int32_t rnd = 0, i;
+ unsigned char buf[ENTROPY_NEEDED];
+
+ for (i = 0; i < sizeof(buf); i++) {
+ if (i % 4 == 0)
+ rnd = arc4random();
+ buf[i] = rnd;
+ rnd >>= 8;
+ }
+ RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
+ memset(buf, 0, sizeof(buf));
+
+ return 1;
+}
+# else /* !defined(__OpenBSD__) */
+int RAND_poll(void)
+{
+ unsigned long l;
+ pid_t curr_pid = getpid();
+# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
+ unsigned char tmpbuf[ENTROPY_NEEDED];
+ int n = 0;
+# endif
+# ifdef DEVRANDOM
+ static const char *randomfiles[] = { DEVRANDOM };
+ struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])];
+ int fd;
+ unsigned int i;
+# endif
+# ifdef DEVRANDOM_EGD
+ static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
+ const char **egdsocket = NULL;
+# endif
+
+# ifdef DEVRANDOM
+ memset(randomstats, 0, sizeof(randomstats));
+ /*
+ * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
+ * this. Use /dev/urandom if you can as /dev/random may block if it runs
+ * out of random entries.
+ */
+
+ for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) &&
+ (n < ENTROPY_NEEDED); i++) {
+ if ((fd = open(randomfiles[i], O_RDONLY
+# ifdef O_NONBLOCK
+ | O_NONBLOCK
+# endif
+# ifdef O_BINARY
+ | O_BINARY
+# endif
+# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do
+ * not make it our controlling tty */
+ | O_NOCTTY
+# endif
+ )) >= 0) {
+ int usec = 10 * 1000; /* spend 10ms on each file */
+ int r;
+ unsigned int j;
+ struct stat *st = &randomstats[i];
+
+ /*
+ * Avoid using same input... Used to be O_NOFOLLOW above, but
+ * it's not universally appropriate...
+ */
+ if (fstat(fd, st) != 0) {
+ close(fd);
+ continue;
+ }
+ for (j = 0; j < i; j++) {
+ if (randomstats[j].st_ino == st->st_ino &&
+ randomstats[j].st_dev == st->st_dev)
+ break;
+ }
+ if (j < i) {
+ close(fd);
+ continue;
+ }
+
+ do {
+ int try_read = 0;
+
+# if defined(OPENSSL_SYS_BEOS_R5)
+ /*
+ * select() is broken in BeOS R5, so we simply try to read
+ * something and snooze if we couldn't
+ */
+ try_read = 1;
+
+# elif defined(OPENSSL_SYS_LINUX)
+ /* use poll() */
+ struct pollfd pset;
+
+ pset.fd = fd;
+ pset.events = POLLIN;
+ pset.revents = 0;
+
+ if (poll(&pset, 1, usec / 1000) < 0)
+ usec = 0;
+ else
+ try_read = (pset.revents & POLLIN) != 0;
+
+# else
+ /* use select() */
+ fd_set fset;
+ struct timeval t;
+
+ t.tv_sec = 0;
+ t.tv_usec = usec;
+
+ if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
+ /*
+ * can't use select, so just try to read once anyway
+ */
+ try_read = 1;
+ } else {
+ FD_ZERO(&fset);
+ FD_SET(fd, &fset);
+
+ if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
+ usec = t.tv_usec;
+ if (FD_ISSET(fd, &fset))
+ try_read = 1;
+ } else
+ usec = 0;
+ }
+# endif
+
+ if (try_read) {
+ r = read(fd, (unsigned char *)tmpbuf + n,
+ ENTROPY_NEEDED - n);
+ if (r > 0)
+ n += r;
+# if defined(OPENSSL_SYS_BEOS_R5)
+ if (r == 0)
+ snooze(t.tv_usec);
+# endif
+ } else
+ r = -1;
+
+ /*
+ * Some Unixen will update t in select(), some won't. For
+ * those who won't, or if we didn't use select() in the first
+ * place, give up here, otherwise, we will do this once again
+ * for the remaining time.
+ */
+ if (usec == 10 * 1000)
+ usec = 0;
+ }
+ while ((r > 0 ||
+ (errno == EINTR || errno == EAGAIN)) && usec != 0
+ && n < ENTROPY_NEEDED);
+
+ close(fd);
+ }
+ }
+# endif /* defined(DEVRANDOM) */
+
+# ifdef DEVRANDOM_EGD
+ /*
+ * Use an EGD socket to read entropy from an EGD or PRNGD entropy
+ * collecting daemon.
+ */
+
+ for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
+ egdsocket++) {
+ int r;
+
+ r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
+ ENTROPY_NEEDED - n);
+ if (r > 0)
+ n += r;
+ }
+# endif /* defined(DEVRANDOM_EGD) */
+
+# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
+ if (n > 0) {
+ RAND_add(tmpbuf, sizeof tmpbuf, (double)n);
+ OPENSSL_cleanse(tmpbuf, n);
+ }
+# endif
+
+ /* put in some default random data, we need more than just this */
+ l = curr_pid;
+ RAND_add(&l, sizeof(l), 0.0);
+ l = getuid();
+ RAND_add(&l, sizeof(l), 0.0);
+
+ 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
+ return 0;
+# endif
+}
+
+# endif /* defined(__OpenBSD__) */
+#endif /* !(defined(OPENSSL_SYS_WINDOWS) ||
+ * defined(OPENSSL_SYS_WIN32) ||
+ * defined(OPENSSL_SYS_VMS) ||
+ * defined(OPENSSL_SYS_OS2) ||
+ * defined(OPENSSL_SYS_VXWORKS) ||
+ * defined(OPENSSL_SYS_NETWARE)) */
+
+#if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
+int RAND_poll(void)
+{
+ return 0;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rand/randfile.c b/Cryptlib/OpenSSL/crypto/rand/randfile.c
new file mode 100644
index 00000000..9537c56a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rand/randfile.c
@@ -0,0 +1,337 @@
+/* crypto/rand/randfile.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.]
+ */
+
+/* We need to define this to get macros like S_IFBLK and S_IFCHR */
+#if !defined(OPENSSL_SYS_VXWORKS)
+# define _XOPEN_SOURCE 500
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+
+#ifdef OPENSSL_SYS_VMS
+# include <unixio.h>
+#endif
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifndef OPENSSL_NO_POSIX_IO
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
+#ifdef _WIN32
+# define stat _stat
+# define chmod _chmod
+# define open _open
+# define fdopen _fdopen
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE 1024
+#define RAND_DATA 1024
+
+#ifdef OPENSSL_SYS_VMS
+/*
+ * This declaration is a nasty hack to get around vms' extension to fopen for
+ * passing in sharing options being disabled by our /STANDARD=ANSI89
+ */
+static FILE *(*const vms_fopen)(const char *, const char *, ...) =
+ (FILE *(*)(const char *, const char *, ...))fopen;
+# define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
+#endif
+
+/* #define RFILE ".rnd" - defined in ../../e_os.h */
+
+/*
+ * Note that these functions are intended for seed files only. Entropy
+ * devices and EGD sockets are handled in rand_unix.c
+ */
+
+int RAND_load_file(const char *file, long bytes)
+{
+ /*-
+ * If bytes >= 0, read up to 'bytes' 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
+ * structure before calling RAND_add() to avoid complaints from
+ * applications such as Valgrind.
+ */
+ 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
+ in = vms_fopen(file, "rb", VMS_OPEN_ATTRS);
+#else
+ in = fopen(file, "rb");
+#endif
+ if (in == NULL)
+ goto err;
+#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_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.
+ */
+ bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+ setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+ }
+#endif
+ for (;;) {
+ if (bytes > 0)
+ n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE;
+ else
+ n = BUFSIZE;
+ i = fread(buf, 1, n, in);
+ if (i <= 0)
+ break;
+#ifdef PURIFY
+ RAND_add(buf, i, (double)i);
+#else
+ /* even if n != i, use the full array */
+ RAND_add(buf, n, (double)i);
+#endif
+ ret += i;
+ if (bytes > 0) {
+ bytes -= n;
+ if (bytes <= 0)
+ break;
+ }
+ }
+ fclose(in);
+ OPENSSL_cleanse(buf, BUFSIZE);
+ err:
+ return (ret);
+}
+
+int RAND_write_file(const char *file)
+{
+ unsigned char buf[BUFSIZE];
+ int i, ret = 0, rand_err = 0;
+ FILE *out = NULL;
+ int n;
+#ifndef OPENSSL_NO_POSIX_IO
+ struct stat sb;
+
+ i = stat(file, &sb);
+ if (i != -1) {
+# if defined(S_ISBLK) && defined(S_ISCHR)
+ if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
+ /*
+ * this file is a device. we don't write back to it. we
+ * "succeed" on the assumption this is some sort of random
+ * device. Otherwise attempting to write to and chmod the device
+ * causes problems.
+ */
+ return (1);
+ }
+# endif
+ }
+#endif
+
+#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
+ {
+# 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_WRONLY | O_CREAT | O_BINARY, 0600);
+ if (fd != -1)
+ out = fdopen(fd, "wb");
+ }
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+ /*
+ * VMS NOTE: Prior versions of this routine created a _new_ version of
+ * the rand file for each call into this routine, then deleted all
+ * existing versions named ;-1, and finally renamed the current version
+ * as ';1'. Under concurrent usage, this resulted in an RMS race
+ * condition in rename() which could orphan files (see vms message help
+ * for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares
+ * the top-level version of the rand file. Note that there may still be
+ * conditions where the top-level rand file is locked. If so, this code
+ * will then create a new version of the rand file. Without the delete
+ * and rename code, this can result in ascending file versions that stop
+ * at version 32767, and this routine will then return an error. The
+ * remedy for this is to recode the calling application to avoid
+ * concurrent use of the rand file, or synchronize usage at the
+ * application level. Also consider whether or not you NEED a persistent
+ * rand file in a concurrent use situation.
+ */
+
+ out = vms_fopen(file, "rb+", VMS_OPEN_ATTRS);
+ if (out == NULL)
+ out = vms_fopen(file, "wb", VMS_OPEN_ATTRS);
+#else
+ if (out == NULL)
+ out = fopen(file, "wb");
+#endif
+ if (out == NULL)
+ goto err;
+
+#ifndef NO_CHMOD
+ chmod(file, 0600);
+#endif
+ n = RAND_DATA;
+ for (;;) {
+ i = (n > BUFSIZE) ? BUFSIZE : n;
+ n -= BUFSIZE;
+ if (RAND_bytes(buf, i) <= 0)
+ rand_err = 1;
+ i = fwrite(buf, 1, i, out);
+ if (i <= 0) {
+ ret = 0;
+ break;
+ }
+ ret += i;
+ if (n <= 0)
+ break;
+ }
+
+ fclose(out);
+ OPENSSL_cleanse(buf, BUFSIZE);
+ err:
+ return (rand_err ? -1 : ret);
+}
+
+const char *RAND_file_name(char *buf, size_t size)
+{
+ char *s = NULL;
+#ifdef __OpenBSD__
+ struct stat sb;
+#endif
+
+ if (OPENSSL_issetugid() == 0)
+ s = getenv("RANDFILE");
+ if (s != NULL && *s && strlen(s) + 1 < size) {
+ if (BUF_strlcpy(buf, s, size) >= size)
+ return NULL;
+ } else {
+ if (OPENSSL_issetugid() == 0)
+ s = getenv("HOME");
+#ifdef DEFAULT_HOME
+ if (s == NULL) {
+ s = DEFAULT_HOME;
+ }
+#endif
+ if (s && *s && strlen(s) + strlen(RFILE) + 2 < size) {
+ BUF_strlcpy(buf, s, size);
+#ifndef OPENSSL_SYS_VMS
+ BUF_strlcat(buf, "/", size);
+#endif
+ BUF_strlcat(buf, RFILE, size);
+ } else
+ buf[0] = '\0'; /* no file name */
+ }
+
+#ifdef __OpenBSD__
+ /*
+ * given that all random loads just fail if the file can't be seen on a
+ * stat, we stat the file we're returning, if it fails, use /dev/arandom
+ * instead. this allows the user to use their own source for good random
+ * data, but defaults to something hopefully decent if that isn't
+ * available.
+ */
+
+ if (!buf[0])
+ if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) {
+ return (NULL);
+ }
+ if (stat(buf, &sb) == -1)
+ if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) {
+ return (NULL);
+ }
+#endif
+ return (buf);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rc4/rc4_enc.c b/Cryptlib/OpenSSL/crypto/rc4/rc4_enc.c
new file mode 100644
index 00000000..0f0a2487
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rc4/rc4_enc.c
@@ -0,0 +1,334 @@
+/* crypto/rc4/rc4_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 <openssl/rc4.h>
+#include "rc4_locl.h"
+
+/*-
+ * RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+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;
+ size_t i;
+
+ x = key->x;
+ y = key->y;
+ d = key->data;
+
+#if defined(RC4_CHUNK) && !defined(PEDANTIC)
+ /*-
+ * The original reason for implementing this(*) was the fact that
+ * pre-21164a Alpha CPUs don't have byte load/store instructions
+ * and e.g. a byte store has to be done with 64-bit load, shift,
+ * and, or and finally 64-bit store. Peaking data and operating
+ * at natural word size made it possible to reduce amount of
+ * instructions as well as to perform early read-ahead without
+ * suffering from RAW (read-after-write) hazard. This resulted
+ * in ~40%(**) performance improvement on 21064 box with gcc.
+ * But it's not only Alpha users who win here:-) Thanks to the
+ * early-n-wide read-ahead this implementation also exhibits
+ * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
+ * on sizeof(RC4_INT)).
+ *
+ * (*) "this" means code which recognizes the case when input
+ * and output pointers appear to be aligned at natural CPU
+ * word boundary
+ * (**) i.e. according to 'apps/openssl speed rc4' benchmark,
+ * crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
+ *
+ * Cavets.
+ *
+ * - RC4_CHUNK="unsigned long long" should be a #1 choice for
+ * UltraSPARC. Unfortunately gcc generates very slow code
+ * (2.5-3 times slower than one generated by Sun's WorkShop
+ * C) and therefore gcc (at least 2.95 and earlier) should
+ * always be told that RC4_CHUNK="unsigned long".
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+# define RC4_STEP ( \
+ x=(x+1) &0xff, \
+ tx=d[x], \
+ y=(tx+y)&0xff, \
+ ty=d[y], \
+ d[y]=tx, \
+ d[x]=ty, \
+ (RC4_CHUNK)d[(tx+ty)&0xff]\
+ )
+
+ 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
+ };
+
+ /*-
+ * I reckon we can afford to implement both endian
+ * cases and to decide which way to take at run-time
+ * because the machine code appears to be very compact
+ * and redundant 1-2KB is perfectly tolerable (i.e.
+ * in case the compiler fails to eliminate it:-). By
+ * suggestion from Terrel Larson <terr@terralogic.net>
+ * who also stands for the is_endian union:-)
+ *
+ * Special notes.
+ *
+ * - is_endian is declared automatic as doing otherwise
+ * (declaring static) prevents gcc from eliminating
+ * the redundant code;
+ * - compilers (those I've tried) don't seem to have
+ * problems eliminating either the operators guarded
+ * by "if (sizeof(RC4_CHUNK)==8)" or the condition
+ * expressions themselves so I've got 'em to replace
+ * corresponding #ifdefs from the previous version;
+ * - I chose to let the redundant switch cases when
+ * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
+ * before);
+ * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
+ * [LB]ESHFT guards against "shift is out of range"
+ * warnings when sizeof(RC4_CHUNK)!=8
+ *
+ * <appro@fy.chalmers.se>
+ */
+ if (!is_endian.little) { /* BIG-ENDIAN CASE */
+# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
+ for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
+ ichunk = *(RC4_CHUNK *) indata;
+ otp = RC4_STEP << BESHFT(0);
+ otp |= RC4_STEP << BESHFT(1);
+ otp |= RC4_STEP << BESHFT(2);
+ otp |= RC4_STEP << BESHFT(3);
+ if (sizeof(RC4_CHUNK) == 8) {
+ otp |= RC4_STEP << BESHFT(4);
+ otp |= RC4_STEP << BESHFT(5);
+ otp |= RC4_STEP << BESHFT(6);
+ otp |= RC4_STEP << BESHFT(7);
+ }
+ *(RC4_CHUNK *) outdata = otp ^ ichunk;
+ indata += sizeof(RC4_CHUNK);
+ outdata += sizeof(RC4_CHUNK);
+ }
+ if (len) {
+ RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk;
+
+ ichunk = *(RC4_CHUNK *) indata;
+ ochunk = *(RC4_CHUNK *) outdata;
+ otp = 0;
+ i = BESHFT(0);
+ mask <<= (sizeof(RC4_CHUNK) - len) << 3;
+ switch (len & (sizeof(RC4_CHUNK) - 1)) {
+ case 7:
+ otp = RC4_STEP << i, i -= 8;
+ case 6:
+ otp |= RC4_STEP << i, i -= 8;
+ case 5:
+ otp |= RC4_STEP << i, i -= 8;
+ case 4:
+ otp |= RC4_STEP << i, i -= 8;
+ case 3:
+ otp |= RC4_STEP << i, i -= 8;
+ case 2:
+ otp |= RC4_STEP << i, i -= 8;
+ case 1:
+ otp |= RC4_STEP << i, i -= 8;
+ case 0:; /*
+ * it's never the case,
+ * but it has to be here
+ * for ultrix?
+ */
+ }
+ ochunk &= ~mask;
+ ochunk |= (otp ^ ichunk) & mask;
+ *(RC4_CHUNK *) outdata = ochunk;
+ }
+ key->x = x;
+ key->y = y;
+ return;
+ } else { /* LITTLE-ENDIAN CASE */
+# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1))
+ for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
+ ichunk = *(RC4_CHUNK *) indata;
+ otp = RC4_STEP;
+ otp |= RC4_STEP << 8;
+ otp |= RC4_STEP << 16;
+ otp |= RC4_STEP << 24;
+ if (sizeof(RC4_CHUNK) == 8) {
+ otp |= RC4_STEP << LESHFT(4);
+ otp |= RC4_STEP << LESHFT(5);
+ otp |= RC4_STEP << LESHFT(6);
+ otp |= RC4_STEP << LESHFT(7);
+ }
+ *(RC4_CHUNK *) outdata = otp ^ ichunk;
+ indata += sizeof(RC4_CHUNK);
+ outdata += sizeof(RC4_CHUNK);
+ }
+ if (len) {
+ RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk;
+
+ ichunk = *(RC4_CHUNK *) indata;
+ ochunk = *(RC4_CHUNK *) outdata;
+ otp = 0;
+ i = 0;
+ mask >>= (sizeof(RC4_CHUNK) - len) << 3;
+ switch (len & (sizeof(RC4_CHUNK) - 1)) {
+ case 7:
+ otp = RC4_STEP, i += 8;
+ case 6:
+ otp |= RC4_STEP << i, i += 8;
+ case 5:
+ otp |= RC4_STEP << i, i += 8;
+ case 4:
+ otp |= RC4_STEP << i, i += 8;
+ case 3:
+ otp |= RC4_STEP << i, i += 8;
+ case 2:
+ otp |= RC4_STEP << i, i += 8;
+ case 1:
+ otp |= RC4_STEP << i, i += 8;
+ case 0:; /*
+ * it's never the case,
+ * but it has to be here
+ * for ultrix?
+ */
+ }
+ ochunk &= ~mask;
+ ochunk |= (otp ^ ichunk) & mask;
+ *(RC4_CHUNK *) outdata = ochunk;
+ }
+ key->x = x;
+ key->y = y;
+ return;
+ }
+ }
+#endif
+#define LOOP(in,out) \
+ x=((x+1)&0xff); \
+ tx=d[x]; \
+ y=(tx+y)&0xff; \
+ d[x]=ty=d[y]; \
+ d[y]=tx; \
+ (out) = d[(tx+ty)&0xff]^ (in);
+
+#ifndef RC4_INDEX
+# define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++))
+#else
+# define RC4_LOOP(a,b,i) LOOP(a[i],b[i])
+#endif
+
+ i = len >> 3;
+ if (i) {
+ for (;;) {
+ RC4_LOOP(indata, outdata, 0);
+ RC4_LOOP(indata, outdata, 1);
+ RC4_LOOP(indata, outdata, 2);
+ RC4_LOOP(indata, outdata, 3);
+ RC4_LOOP(indata, outdata, 4);
+ RC4_LOOP(indata, outdata, 5);
+ RC4_LOOP(indata, outdata, 6);
+ RC4_LOOP(indata, outdata, 7);
+#ifdef RC4_INDEX
+ indata += 8;
+ outdata += 8;
+#endif
+ if (--i == 0)
+ break;
+ }
+ }
+ i = len & 0x07;
+ if (i) {
+ for (;;) {
+ RC4_LOOP(indata, outdata, 0);
+ if (--i == 0)
+ break;
+ RC4_LOOP(indata, outdata, 1);
+ if (--i == 0)
+ break;
+ RC4_LOOP(indata, outdata, 2);
+ if (--i == 0)
+ break;
+ RC4_LOOP(indata, outdata, 3);
+ if (--i == 0)
+ break;
+ RC4_LOOP(indata, outdata, 4);
+ if (--i == 0)
+ break;
+ RC4_LOOP(indata, outdata, 5);
+ if (--i == 0)
+ break;
+ RC4_LOOP(indata, outdata, 6);
+ if (--i == 0)
+ break;
+ }
+ }
+ key->x = x;
+ key->y = y;
+}
diff --git a/Cryptlib/OpenSSL/crypto/rc4/rc4_locl.h b/Cryptlib/OpenSSL/crypto/rc4/rc4_locl.h
new file mode 100644
index 00000000..faf8742f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rc4/rc4_locl.h
@@ -0,0 +1,5 @@
+#ifndef HEADER_RC4_LOCL_H
+# define HEADER_RC4_LOCL_H
+# include <openssl/opensslconf.h>
+# include <cryptlib.h>
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rc4/rc4_skey.c b/Cryptlib/OpenSSL/crypto/rc4/rc4_skey.c
new file mode 100644
index 00000000..06890d16
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rc4/rc4_skey.c
@@ -0,0 +1,116 @@
+/* crypto/rc4/rc4_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 <openssl/rc4.h>
+#include "rc4_locl.h"
+#include <openssl/opensslv.h>
+
+const char RC4_version[] = "RC4" OPENSSL_VERSION_PTEXT;
+
+const char *RC4_options(void)
+{
+#ifdef RC4_INDEX
+ if (sizeof(RC4_INT) == 1)
+ return ("rc4(idx,char)");
+ else
+ return ("rc4(idx,int)");
+#else
+ if (sizeof(RC4_INT) == 1)
+ return ("rc4(ptr,char)");
+ else
+ return ("rc4(ptr,int)");
+#endif
+}
+
+/*-
+ * RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+{
+ register RC4_INT tmp;
+ register int id1, id2;
+ register RC4_INT *d;
+ unsigned int i;
+
+ d = &(key->data[0]);
+ key->x = 0;
+ key->y = 0;
+ id1 = id2 = 0;
+
+#define SK_LOOP(d,n) { \
+ tmp=d[(n)]; \
+ id2 = (data[id1] + tmp + id2) & 0xff; \
+ if (++id1 == len) id1=0; \
+ d[(n)]=d[id2]; \
+ d[id2]=tmp; }
+
+ for (i = 0; i < 256; i++)
+ d[i] = i;
+ for (i = 0; i < 256; i += 4) {
+ SK_LOOP(d, i + 0);
+ SK_LOOP(d, i + 1);
+ SK_LOOP(d, i + 2);
+ SK_LOOP(d, i + 3);
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/rc4/rc4_utl.c b/Cryptlib/OpenSSL/crypto/rc4/rc4_utl.c
new file mode 100644
index 00000000..cbd4a24e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rc4/rc4_utl.c
@@ -0,0 +1,62 @@
+/* crypto/rc4/rc4_utl.c */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <openssl/rc4.h>
+
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+{
+#ifdef OPENSSL_FIPS
+ fips_cipher_abort(RC4);
+#endif
+ private_RC4_set_key(key, len, data);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_ameth.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_ameth.c
new file mode 100644
index 00000000..ddead3d7
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_ameth.c
@@ -0,0 +1,967 @@
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+# include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+#ifndef OPENSSL_NO_CMS
+static int rsa_cms_sign(CMS_SignerInfo *si);
+static int rsa_cms_verify(CMS_SignerInfo *si);
+static int rsa_cms_decrypt(CMS_RecipientInfo *ri);
+static int rsa_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+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);
+}
+
+/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
+static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg)
+{
+ const unsigned char *p;
+ int plen;
+ if (alg == NULL || alg->parameter == NULL)
+ return NULL;
+ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
+ return NULL;
+ if (alg->parameter->type != V_ASN1_SEQUENCE)
+ return NULL;
+
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ return d2i_X509_ALGOR(NULL, &p, plen);
+}
+
+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
+ X509_ALGOR **pmaskHash)
+{
+ const unsigned char *p;
+ int plen;
+ RSA_PSS_PARAMS *pss;
+
+ *pmaskHash = NULL;
+
+ if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
+ return NULL;
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
+
+ if (!pss)
+ return NULL;
+
+ *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
+
+ return pss;
+}
+
+static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
+ X509_ALGOR *maskHash, int indent)
+{
+ int rv = 0;
+ if (!pss) {
+ if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
+ return 0;
+ return 1;
+ }
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+ if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
+ goto err;
+
+ if (pss->hashAlgorithm) {
+ if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
+ goto err;
+ } else if (BIO_puts(bp, "sha1 (default)") <= 0)
+ goto err;
+
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+
+ if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
+ goto err;
+ if (pss->maskGenAlgorithm) {
+ if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, " with ") <= 0)
+ goto err;
+ if (maskHash) {
+ if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
+ goto err;
+ } else if (BIO_puts(bp, "INVALID") <= 0)
+ goto err;
+ } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
+ goto err;
+ BIO_puts(bp, "\n");
+
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+ if (BIO_puts(bp, "Salt Length: 0x") <= 0)
+ goto err;
+ if (pss->saltLength) {
+ if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
+ goto err;
+ } else if (BIO_puts(bp, "14 (default)") <= 0)
+ goto err;
+ BIO_puts(bp, "\n");
+
+ if (!BIO_indent(bp, indent, 128))
+ goto err;
+ if (BIO_puts(bp, "Trailer Field: 0x") <= 0)
+ goto err;
+ if (pss->trailerField) {
+ if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
+ goto err;
+ } else if (BIO_puts(bp, "BC (default)") <= 0)
+ goto err;
+ BIO_puts(bp, "\n");
+
+ rv = 1;
+
+ err:
+ return rv;
+
+}
+
+static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
+{
+ if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
+ int rv;
+ RSA_PSS_PARAMS *pss;
+ X509_ALGOR *maskHash;
+ pss = rsa_pss_decode(sigalg, &maskHash);
+ rv = rsa_pss_param_print(bp, pss, maskHash, indent);
+ if (pss)
+ RSA_PSS_PARAMS_free(pss);
+ if (maskHash)
+ X509_ALGOR_free(maskHash);
+ if (!rv)
+ return 0;
+ } else if (!sig && BIO_puts(bp, "\n") <= 0)
+ return 0;
+ if (sig)
+ return X509_signature_dump(bp, sig, indent);
+ return 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)
+ return rsa_cms_sign(arg2);
+ else if (arg1 == 1)
+ return rsa_cms_verify(arg2);
+ break;
+
+ case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+ if (arg1 == 0)
+ return rsa_cms_encrypt(arg2);
+ else if (arg1 == 1)
+ return rsa_cms_decrypt(arg2);
+ break;
+
+ case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+ *(int *)arg2 = CMS_RECIPINFO_TRANS;
+ return 1;
+#endif
+
+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+ *(int *)arg2 = NID_sha256;
+ return 1;
+
+ default:
+ return -2;
+
+ }
+
+ if (alg)
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+
+ return 1;
+
+}
+
+/* allocate and set algorithm ID from EVP_MD, default SHA1 */
+static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md)
+{
+ if (EVP_MD_type(md) == NID_sha1)
+ return 1;
+ *palg = X509_ALGOR_new();
+ if (!*palg)
+ return 0;
+ X509_ALGOR_set_md(*palg, md);
+ return 1;
+}
+
+/* Allocate and set MGF1 algorithm ID from EVP_MD */
+static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
+{
+ X509_ALGOR *algtmp = NULL;
+ ASN1_STRING *stmp = NULL;
+ *palg = NULL;
+ if (EVP_MD_type(mgf1md) == NID_sha1)
+ return 1;
+ /* need to embed algorithm ID inside another */
+ if (!rsa_md_to_algor(&algtmp, mgf1md))
+ goto err;
+ if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp))
+ goto err;
+ *palg = X509_ALGOR_new();
+ if (!*palg)
+ goto err;
+ X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+ stmp = NULL;
+ err:
+ if (stmp)
+ ASN1_STRING_free(stmp);
+ if (algtmp)
+ X509_ALGOR_free(algtmp);
+ if (*palg)
+ return 1;
+ return 0;
+}
+
+/* convert algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg)
+{
+ const EVP_MD *md;
+ if (!alg)
+ return EVP_sha1();
+ md = EVP_get_digestbyobj(alg->algorithm);
+ if (md == NULL)
+ RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST);
+ return md;
+}
+
+/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash)
+{
+ const EVP_MD *md;
+ if (!alg)
+ return EVP_sha1();
+ /* Check mask and lookup mask hash algorithm */
+ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
+ RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
+ return NULL;
+ }
+ if (!maskHash) {
+ RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_PARAMETER);
+ return NULL;
+ }
+ md = EVP_get_digestbyobj(maskHash->algorithm);
+ if (md == NULL) {
+ RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNKNOWN_MASK_DIGEST);
+ return NULL;
+ }
+ return md;
+}
+
+/*
+ * Convert EVP_PKEY_CTX is PSS mode into corresponding algorithm parameter,
+ * suitable for setting an AlgorithmIdentifier.
+ */
+
+static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
+{
+ const EVP_MD *sigmd, *mgf1md;
+ RSA_PSS_PARAMS *pss = NULL;
+ ASN1_STRING *os = NULL;
+ EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
+ int saltlen, rv = 0;
+ if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+ goto err;
+ if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
+ goto err;
+ if (saltlen == -1)
+ saltlen = EVP_MD_size(sigmd);
+ else if (saltlen == -2) {
+ saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+ if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
+ saltlen--;
+ }
+ pss = RSA_PSS_PARAMS_new();
+ if (!pss)
+ goto err;
+ if (saltlen != 20) {
+ pss->saltLength = ASN1_INTEGER_new();
+ if (!pss->saltLength)
+ goto err;
+ if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
+ goto err;
+ }
+ if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd))
+ goto err;
+ if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
+ goto err;
+ /* Finally create string with pss parameter encoding. */
+ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os))
+ goto err;
+ rv = 1;
+ err:
+ if (pss)
+ RSA_PSS_PARAMS_free(pss);
+ if (rv)
+ return os;
+ if (os)
+ ASN1_STRING_free(os);
+ return NULL;
+}
+
+/*
+ * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL
+ * then the EVP_MD_CTX is setup and initalised. If it is NULL parameters are
+ * passed to pkctx instead.
+ */
+
+static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
+ X509_ALGOR *sigalg, EVP_PKEY *pkey)
+{
+ int rv = -1;
+ int saltlen;
+ const EVP_MD *mgf1md = NULL, *md = NULL;
+ RSA_PSS_PARAMS *pss;
+ X509_ALGOR *maskHash;
+ /* Sanity check: make sure it is PSS */
+ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
+ RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+ return -1;
+ }
+ /* Decode PSS parameters */
+ pss = rsa_pss_decode(sigalg, &maskHash);
+
+ if (pss == NULL) {
+ RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS);
+ goto err;
+ }
+ mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
+ if (!mgf1md)
+ goto err;
+ md = rsa_algor_to_md(pss->hashAlgorithm);
+ if (!md)
+ goto err;
+
+ if (pss->saltLength) {
+ saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+ /*
+ * Could perform more salt length sanity checks but the main RSA
+ * routines will trap other invalid values anyway.
+ */
+ if (saltlen < 0) {
+ RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH);
+ goto err;
+ }
+ } else
+ saltlen = 20;
+
+ /*
+ * low-level routines support only trailer field 0xbc (value 1) and
+ * PKCS#1 says we should reject any other value anyway.
+ */
+ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
+ RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER);
+ goto err;
+ }
+
+ /* We have all parameters now set up context */
+
+ if (pkey) {
+ if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
+ goto err;
+ } else {
+ const EVP_MD *checkmd;
+ if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0)
+ goto err;
+ if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
+ RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH);
+ goto err;
+ }
+ }
+
+ if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+ goto err;
+ /* Carry on */
+ rv = 1;
+
+ err:
+ RSA_PSS_PARAMS_free(pss);
+ if (maskHash)
+ X509_ALGOR_free(maskHash);
+ return rv;
+}
+
+#ifndef OPENSSL_NO_CMS
+static int rsa_cms_verify(CMS_SignerInfo *si)
+{
+ int nid, nid2;
+ X509_ALGOR *alg;
+ EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
+ CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
+ nid = OBJ_obj2nid(alg->algorithm);
+ if (nid == NID_rsaEncryption)
+ return 1;
+ if (nid == NID_rsassaPss)
+ return rsa_pss_to_ctx(NULL, pkctx, alg, NULL);
+ /* Workaround for some implementation that use a signature OID */
+ if (OBJ_find_sigid_algs(nid, NULL, &nid2)) {
+ if (nid2 == NID_rsaEncryption)
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+/*
+ * Customised RSA item verification routine. This is called when a signature
+ * is encountered requiring special handling. We currently only handle PSS.
+ */
+
+static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
+ EVP_PKEY *pkey)
+{
+ /* Sanity check: make sure it is PSS */
+ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
+ RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+ return -1;
+ }
+ if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) {
+ /* Carry on */
+ return 2;
+ }
+ return -1;
+}
+
+#ifndef OPENSSL_NO_CMS
+static int rsa_cms_sign(CMS_SignerInfo *si)
+{
+ int pad_mode = RSA_PKCS1_PADDING;
+ X509_ALGOR *alg;
+ EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
+ ASN1_STRING *os = NULL;
+ CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
+ if (pkctx) {
+ if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+ return 0;
+ }
+ if (pad_mode == RSA_PKCS1_PADDING) {
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+ return 1;
+ }
+ /* We don't support it */
+ if (pad_mode != RSA_PKCS1_PSS_PADDING)
+ return 0;
+ os = rsa_ctx_to_pss(pkctx);
+ if (!os)
+ return 0;
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
+ return 1;
+}
+#endif
+
+static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *alg1, X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig)
+{
+ int pad_mode;
+ EVP_PKEY_CTX *pkctx = ctx->pctx;
+ if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+ return 0;
+ if (pad_mode == RSA_PKCS1_PADDING)
+ return 2;
+ if (pad_mode == RSA_PKCS1_PSS_PADDING) {
+ ASN1_STRING *os1 = NULL;
+ os1 = rsa_ctx_to_pss(pkctx);
+ if (!os1)
+ return 0;
+ /* Duplicate parameters if we have to */
+ if (alg2) {
+ ASN1_STRING *os2 = ASN1_STRING_dup(os1);
+ if (!os2) {
+ ASN1_STRING_free(os1);
+ return 0;
+ }
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
+ V_ASN1_SEQUENCE, os2);
+ }
+ X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
+ V_ASN1_SEQUENCE, os1);
+ return 3;
+ }
+ return 2;
+}
+
+#ifndef OPENSSL_NO_CMS
+static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg,
+ X509_ALGOR **pmaskHash)
+{
+ const unsigned char *p;
+ int plen;
+ RSA_OAEP_PARAMS *pss;
+
+ *pmaskHash = NULL;
+
+ if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
+ return NULL;
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ pss = d2i_RSA_OAEP_PARAMS(NULL, &p, plen);
+
+ if (!pss)
+ return NULL;
+
+ *pmaskHash = rsa_mgf1_decode(pss->maskGenFunc);
+
+ return pss;
+}
+
+static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pkctx;
+ X509_ALGOR *cmsalg;
+ int nid;
+ int rv = -1;
+ unsigned char *label = NULL;
+ int labellen = 0;
+ const EVP_MD *mgf1md = NULL, *md = NULL;
+ RSA_OAEP_PARAMS *oaep;
+ X509_ALGOR *maskHash;
+ pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (!pkctx)
+ return 0;
+ if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
+ return -1;
+ nid = OBJ_obj2nid(cmsalg->algorithm);
+ if (nid == NID_rsaEncryption)
+ return 1;
+ if (nid != NID_rsaesOaep) {
+ RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE);
+ return -1;
+ }
+ /* Decode OAEP parameters */
+ oaep = rsa_oaep_decode(cmsalg, &maskHash);
+
+ if (oaep == NULL) {
+ RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS);
+ goto err;
+ }
+
+ mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash);
+ if (!mgf1md)
+ goto err;
+ md = rsa_algor_to_md(oaep->hashFunc);
+ if (!md)
+ goto err;
+
+ if (oaep->pSourceFunc) {
+ X509_ALGOR *plab = oaep->pSourceFunc;
+ if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
+ RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE);
+ goto err;
+ }
+ if (plab->parameter->type != V_ASN1_OCTET_STRING) {
+ RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL);
+ goto err;
+ }
+
+ label = plab->parameter->value.octet_string->data;
+ /* Stop label being freed when OAEP parameters are freed */
+ plab->parameter->value.octet_string->data = NULL;
+ labellen = plab->parameter->value.octet_string->length;
+ }
+
+ if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
+ goto err;
+ /* Carry on */
+ rv = 1;
+
+ err:
+ RSA_OAEP_PARAMS_free(oaep);
+ if (maskHash)
+ X509_ALGOR_free(maskHash);
+ return rv;
+}
+
+static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ const EVP_MD *md, *mgf1md;
+ RSA_OAEP_PARAMS *oaep = NULL;
+ ASN1_STRING *os = NULL;
+ X509_ALGOR *alg;
+ EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
+ unsigned char *label;
+ CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg);
+ if (pkctx) {
+ if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+ return 0;
+ }
+ if (pad_mode == RSA_PKCS1_PADDING) {
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+ return 1;
+ }
+ /* Not supported */
+ if (pad_mode != RSA_PKCS1_OAEP_PADDING)
+ return 0;
+ if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+ goto err;
+ labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label);
+ if (labellen < 0)
+ goto err;
+ oaep = RSA_OAEP_PARAMS_new();
+ if (!oaep)
+ goto err;
+ if (!rsa_md_to_algor(&oaep->hashFunc, md))
+ goto err;
+ if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
+ goto err;
+ if (labellen > 0) {
+ ASN1_OCTET_STRING *los = ASN1_OCTET_STRING_new();
+ oaep->pSourceFunc = X509_ALGOR_new();
+ if (!oaep->pSourceFunc)
+ goto err;
+ if (!los)
+ goto err;
+ if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
+ ASN1_OCTET_STRING_free(los);
+ goto err;
+ }
+ X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
+ V_ASN1_OCTET_STRING, los);
+ }
+ /* create string with pss parameter encoding. */
+ if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
+ goto err;
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
+ os = NULL;
+ rv = 1;
+ err:
+ if (oaep)
+ RSA_OAEP_PARAMS_free(oaep);
+ if (os)
+ ASN1_STRING_free(os);
+ return rv;
+}
+#endif
+
+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,
+
+ rsa_sig_print,
+ int_rsa_free,
+ rsa_pkey_ctrl,
+ old_rsa_priv_decode,
+ old_rsa_priv_encode,
+ rsa_item_verify,
+ rsa_item_sign},
+
+ {
+ EVP_PKEY_RSA2,
+ EVP_PKEY_RSA,
+ ASN1_PKEY_ALIAS}
+};
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_asn1.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_asn1.c
new file mode 100644
index 00000000..aff8b583
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_asn1.c
@@ -0,0 +1,131 @@
+/* rsa_asn1.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+#include <openssl/asn1t.h>
+
+/* Override the default free and new methods */
+static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ if (operation == ASN1_OP_NEW_PRE) {
+ *pval = (ASN1_VALUE *)RSA_new();
+ if (*pval)
+ return 2;
+ return 0;
+ } else if (operation == ASN1_OP_FREE_PRE) {
+ RSA_free((RSA *)*pval);
+ *pval = NULL;
+ return 2;
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
+ ASN1_SIMPLE(RSA, version, LONG),
+ ASN1_SIMPLE(RSA, n, BIGNUM),
+ ASN1_SIMPLE(RSA, e, BIGNUM),
+ ASN1_SIMPLE(RSA, d, BIGNUM),
+ ASN1_SIMPLE(RSA, p, BIGNUM),
+ ASN1_SIMPLE(RSA, q, BIGNUM),
+ ASN1_SIMPLE(RSA, dmp1, BIGNUM),
+ ASN1_SIMPLE(RSA, dmq1, BIGNUM),
+ ASN1_SIMPLE(RSA, iqmp, BIGNUM)
+} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
+
+
+ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
+ ASN1_SIMPLE(RSA, n, BIGNUM),
+ ASN1_SIMPLE(RSA, e, BIGNUM),
+} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
+
+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3)
+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
+ASN1_SEQUENCE(RSA_OAEP_PARAMS) = {
+ ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0),
+ ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1),
+ ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2),
+} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
+
+RSA *RSAPublicKey_dup(RSA *rsa)
+{
+ return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
+}
+
+RSA *RSAPrivateKey_dup(RSA *rsa)
+{
+ return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_chk.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_chk.c
new file mode 100644
index 00000000..607faa00
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_chk.c
@@ -0,0 +1,214 @@
+/* crypto/rsa/rsa_chk.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+int RSA_check_key(const RSA *key)
+{
+ BIGNUM *i, *j, *k, *l, *m;
+ BN_CTX *ctx;
+ int r;
+ int ret = 1;
+
+ if (!key->p || !key->q || !key->n || !key->e || !key->d) {
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING);
+ return 0;
+ }
+
+ i = BN_new();
+ j = BN_new();
+ k = BN_new();
+ l = BN_new();
+ m = BN_new();
+ ctx = BN_CTX_new();
+ if (i == NULL || j == NULL || k == NULL || l == NULL ||
+ m == NULL || ctx == NULL) {
+ ret = -1;
+ RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* p prime? */
+ r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
+ if (r != 1) {
+ ret = r;
+ if (r != 0)
+ goto err;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
+ }
+
+ /* q prime? */
+ r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
+ if (r != 1) {
+ ret = r;
+ if (r != 0)
+ goto err;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
+ }
+
+ /* n = p*q? */
+ r = BN_mul(i, key->p, key->q, ctx);
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ if (BN_cmp(i, key->n) != 0) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
+ }
+
+ /* d*e = 1 mod lcm(p-1,q-1)? */
+
+ r = BN_sub(i, key->p, BN_value_one());
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+ r = BN_sub(j, key->q, BN_value_one());
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ /* now compute k = lcm(i,j) */
+ r = BN_mul(l, i, j, ctx);
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+ r = BN_gcd(m, i, j, ctx);
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+ r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ r = BN_mod_mul(i, key->d, key->e, k, ctx);
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ if (!BN_is_one(i)) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+ }
+
+ if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
+ /* dmp1 = d mod (p-1)? */
+ r = BN_sub(i, key->p, BN_value_one());
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ r = BN_mod(j, key->d, i, ctx);
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ if (BN_cmp(j, key->dmp1) != 0) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D);
+ }
+
+ /* dmq1 = d mod (q-1)? */
+ r = BN_sub(i, key->q, BN_value_one());
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ r = BN_mod(j, key->d, i, ctx);
+ if (!r) {
+ ret = -1;
+ goto err;
+ }
+
+ if (BN_cmp(j, key->dmq1) != 0) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
+ }
+
+ /* iqmp = q^-1 mod p? */
+ if (!BN_mod_inverse(i, key->q, key->p, ctx)) {
+ ret = -1;
+ goto err;
+ }
+
+ if (BN_cmp(i, key->iqmp) != 0) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q);
+ }
+ }
+
+ err:
+ if (i != NULL)
+ BN_free(i);
+ if (j != NULL)
+ BN_free(j);
+ if (k != NULL)
+ BN_free(k);
+ if (l != NULL)
+ BN_free(l);
+ if (m != NULL)
+ BN_free(m);
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_crpt.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_crpt.c
new file mode 100644
index 00000000..5c416b53
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_crpt.c
@@ -0,0 +1,247 @@
+/* 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 <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+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)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
+}
+
+int RSA_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
+}
+
+int RSA_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
+}
+
+int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+ RSA *rsa, int padding)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+ return -1;
+ }
+#endif
+ return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+}
+
+int RSA_flags(const RSA *r)
+{
+ return ((r == NULL) ? 0 : r->meth->flags);
+}
+
+void RSA_blinding_off(RSA *rsa)
+{
+ if (rsa->blinding != NULL) {
+ BN_BLINDING_free(rsa->blinding);
+ rsa->blinding = NULL;
+ }
+ rsa->flags &= ~RSA_FLAG_BLINDING;
+ rsa->flags |= RSA_FLAG_NO_BLINDING;
+}
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
+{
+ int ret = 0;
+
+ if (rsa->blinding != NULL)
+ RSA_blinding_off(rsa);
+
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ if (rsa->blinding == NULL)
+ goto err;
+
+ rsa->flags |= RSA_FLAG_BLINDING;
+ rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+ ret = 1;
+ err:
+ return (ret);
+}
+
+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
+ const BIGNUM *q, BN_CTX *ctx)
+{
+ BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+ if (d == NULL || p == NULL || q == NULL)
+ return NULL;
+
+ BN_CTX_start(ctx);
+ r0 = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ r2 = BN_CTX_get(ctx);
+ if (r2 == NULL)
+ goto err;
+
+ if (!BN_sub(r1, p, BN_value_one()))
+ goto err;
+ if (!BN_sub(r2, q, BN_value_one()))
+ goto err;
+ if (!BN_mul(r0, r1, r2, ctx))
+ goto err;
+
+ ret = BN_mod_inverse(NULL, d, r0, ctx);
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+ BIGNUM local_n;
+ BIGNUM *e, *n;
+ BN_CTX *ctx;
+ BN_BLINDING *ret = NULL;
+
+ if (in_ctx == NULL) {
+ if ((ctx = BN_CTX_new()) == NULL)
+ return 0;
+ } else
+ ctx = in_ctx;
+
+ BN_CTX_start(ctx);
+ e = BN_CTX_get(ctx);
+ if (e == NULL) {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (rsa->e == NULL) {
+ e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+ if (e == NULL) {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
+ goto err;
+ }
+ } else
+ e = rsa->e;
+
+ if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) {
+ /*
+ * if PRNG is not properly seeded, resort to secret exponent as
+ * unpredictable seed
+ */
+ RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
+ }
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ /* Set BN_FLG_CONSTTIME flag */
+ n = &local_n;
+ BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
+ } else
+ n = rsa->n;
+
+ ret = BN_BLINDING_create_param(NULL, e, n, ctx,
+ rsa->meth->bn_mod_exp, rsa->_method_mod_n);
+ if (ret == NULL) {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
+ goto err;
+ }
+ CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
+ err:
+ BN_CTX_end(ctx);
+ if (in_ctx == NULL)
+ BN_CTX_free(ctx);
+ if (rsa->e == NULL)
+ BN_free(e);
+
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_depr.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_depr.c
new file mode 100644
index 00000000..32f0c888
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_depr.c
@@ -0,0 +1,107 @@
+/* crypto/rsa/rsa_depr.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/*
+ * NB: This file contains deprecated functions (compatibility wrappers to the
+ * "new" versions).
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#ifdef OPENSSL_NO_DEPRECATED
+
+static void *dummy = &dummy;
+
+#else
+
+RSA *RSA_generate_key(int bits, unsigned long e_value,
+ void (*callback) (int, int, void *), void *cb_arg)
+{
+ BN_GENCB cb;
+ int i;
+ RSA *rsa = RSA_new();
+ BIGNUM *e = BN_new();
+
+ if (!rsa || !e)
+ goto err;
+
+ /*
+ * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long
+ * can be larger
+ */
+ for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) {
+ if (e_value & (1UL << i))
+ if (BN_set_bit(e, i) == 0)
+ goto err;
+ }
+
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+
+ if (RSA_generate_key_ex(rsa, bits, e, &cb)) {
+ BN_free(e);
+ return rsa;
+ }
+ err:
+ if (e)
+ BN_free(e);
+ if (rsa)
+ RSA_free(rsa);
+ return 0;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_eay.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_eay.c
new file mode 100644
index 00000000..b147fff8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_eay.c
@@ -0,0 +1,904 @@
+/* crypto/rsa/rsa_eay.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-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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+#ifndef RSA_NULL
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa,
+ BN_CTX *ctx);
+static int RSA_eay_init(RSA *rsa);
+static int RSA_eay_finish(RSA *rsa);
+static RSA_METHOD rsa_pkcs1_eay_meth = {
+ "Eric Young's PKCS#1 RSA",
+ RSA_eay_public_encrypt,
+ RSA_eay_public_decrypt, /* signature verification */
+ RSA_eay_private_encrypt, /* signing */
+ RSA_eay_private_decrypt,
+ RSA_eay_mod_exp,
+ BN_mod_exp_mont, /* XXX probably we should not use Montgomery
+ * if e == 3 */
+ RSA_eay_init,
+ RSA_eay_finish,
+ 0, /* flags */
+ NULL,
+ 0, /* rsa_sign */
+ 0, /* rsa_verify */
+ NULL /* rsa_keygen */
+};
+
+const RSA_METHOD *RSA_PKCS1_SSLeay(void)
+{
+ return (&rsa_pkcs1_eay_meth);
+}
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ BIGNUM *f, *ret;
+ int i, j, k, num = 0, r = -1;
+ unsigned char *buf = NULL;
+ BN_CTX *ctx = NULL;
+
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (BN_ucmp(rsa->n, rsa->e) <= 0) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+
+ /* for large moduli, enforce exponent limit */
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
+ if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+ }
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if (!f || !ret || !buf) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+ i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
+ break;
+# ifndef OPENSSL_NO_SHA
+ case RSA_PKCS1_OAEP_PADDING:
+ i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
+ break;
+# endif
+ case RSA_SSLV23_PADDING:
+ i = RSA_padding_add_SSLv23(buf, num, from, flen);
+ break;
+ case RSA_NO_PADDING:
+ i = RSA_padding_add_none(buf, num, from, flen);
+ break;
+ default:
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (i <= 0)
+ goto err;
+
+ if (BN_bin2bn(buf, num, f) == NULL)
+ goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0) {
+ /* usually the padding functions would catch this */
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,
+ RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+
+ if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
+ rsa->_method_mod_n))
+ goto err;
+
+ /*
+ * put in leading 0 bytes if the number is less than the length of the
+ * modulus
+ */
+ j = BN_num_bytes(ret);
+ i = BN_bn2bin(ret, &(to[num - j]));
+ for (k = 0; k < (num - i); k++)
+ to[k] = 0;
+
+ r = num;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL) {
+ OPENSSL_cleanse(buf, num);
+ OPENSSL_free(buf);
+ }
+ return (r);
+}
+
+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);
+
+ if (rsa->blinding == NULL) {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+
+ if (rsa->blinding == NULL)
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ }
+
+ ret = rsa->blinding;
+ if (ret == NULL)
+ goto err;
+
+ CRYPTO_THREADID_current(&cur);
+ if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) {
+ /* rsa->blinding is ours! */
+
+ *local = 1;
+ } else {
+ /* resort to rsa->mt_blinding instead */
+
+ /*
+ * instructs rsa_blinding_convert(), rsa_blinding_invert() that the
+ * BN_BLINDING is shared, meaning that accesses require locks, and
+ * that the blinding factor must be stored outside the BN_BLINDING
+ */
+ *local = 0;
+
+ if (rsa->mt_blinding == NULL) {
+ if (!got_write_lock) {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+ }
+
+ if (rsa->mt_blinding == NULL)
+ rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
+ }
+ ret = rsa->mt_blinding;
+ }
+
+ err:
+ if (got_write_lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+ else
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ return ret;
+}
+
+static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+ BN_CTX *ctx)
+{
+ if (unblind == NULL)
+ /*
+ * Local blinding: store the unblinding factor in BN_BLINDING.
+ */
+ return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+ else {
+ /*
+ * Shared blinding: store the unblinding factor outside BN_BLINDING.
+ */
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
+ }
+}
+
+static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+ BN_CTX *ctx)
+{
+ /*
+ * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
+ * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING
+ * is shared between threads, unblind must be non-null:
+ * BN_BLINDING_invert_ex will then use the local unblinding factor, and
+ * will only read the modulus from BN_BLINDING. In both cases it's safe
+ * to access the blinding without a lock.
+ */
+ return BN_BLINDING_invert_ex(f, unblind, b, ctx);
+}
+
+/* signing */
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ BIGNUM *f, *ret, *res;
+ int i, j, k, num = 0, r = -1;
+ unsigned char *buf = NULL;
+ BN_CTX *ctx = NULL;
+ int local_blinding = 0;
+ /*
+ * Used only if the blinding structure is shared. A non-NULL unblind
+ * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+ * the unblinding factor outside the blinding structure.
+ */
+ BIGNUM *unblind = NULL;
+ BN_BLINDING *blinding = NULL;
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if (!f || !ret || !buf) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+ i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
+ break;
+ case RSA_X931_PADDING:
+ i = RSA_padding_add_X931(buf, num, from, flen);
+ break;
+ case RSA_NO_PADDING:
+ i = RSA_padding_add_none(buf, num, from, flen);
+ break;
+ case RSA_SSLV23_PADDING:
+ default:
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (i <= 0)
+ goto err;
+
+ if (BN_bin2bn(buf, num, f) == NULL)
+ goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0) {
+ /* usually the padding functions would catch this */
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
+ RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+ if (blinding == NULL) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (blinding != NULL) {
+ if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+ goto err;
+ }
+
+ if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
+ ((rsa->p != NULL) &&
+ (rsa->q != NULL) &&
+ (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
+ if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
+ goto err;
+ } else {
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ BN_init(&local_d);
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ } else
+ d = rsa->d;
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+
+ if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
+ rsa->_method_mod_n))
+ goto err;
+ }
+
+ if (blinding)
+ if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+ goto err;
+
+ if (padding == RSA_X931_PADDING) {
+ BN_sub(f, rsa->n, ret);
+ if (BN_cmp(ret, f) > 0)
+ res = f;
+ else
+ res = ret;
+ } else
+ res = ret;
+
+ /*
+ * put in leading 0 bytes if the number is less than the length of the
+ * modulus
+ */
+ j = BN_num_bytes(res);
+ i = BN_bn2bin(res, &(to[num - j]));
+ for (k = 0; k < (num - i); k++)
+ to[k] = 0;
+
+ r = num;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL) {
+ OPENSSL_cleanse(buf, num);
+ OPENSSL_free(buf);
+ }
+ return (r);
+}
+
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ BIGNUM *f, *ret;
+ int j, num = 0, r = -1;
+ unsigned char *p;
+ unsigned char *buf = NULL;
+ BN_CTX *ctx = NULL;
+ int local_blinding = 0;
+ /*
+ * Used only if the blinding structure is shared. A non-NULL unblind
+ * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+ * the unblinding factor outside the blinding structure.
+ */
+ BIGNUM *unblind = NULL;
+ BN_BLINDING *blinding = NULL;
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if (!f || !ret || !buf) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * This check was for equality but PGP does evil things and chops off the
+ * top '0' bytes
+ */
+ if (flen > num) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+ RSA_R_DATA_GREATER_THAN_MOD_LEN);
+ goto err;
+ }
+
+ /* make data into a big number */
+ if (BN_bin2bn(from, (int)flen, f) == NULL)
+ goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+ RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+ if (blinding == NULL) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (blinding != NULL) {
+ if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+ goto err;
+ }
+
+ /* do the decrypt */
+ if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
+ ((rsa->p != NULL) &&
+ (rsa->q != NULL) &&
+ (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
+ if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
+ goto err;
+ } else {
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ } else
+ d = rsa->d;
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+ if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
+ rsa->_method_mod_n))
+ goto err;
+ }
+
+ if (blinding)
+ if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+ goto err;
+
+ p = buf;
+ j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */
+
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+ r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num);
+ break;
+# ifndef OPENSSL_NO_SHA
+ case RSA_PKCS1_OAEP_PADDING:
+ r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0);
+ break;
+# endif
+ case RSA_SSLV23_PADDING:
+ r = RSA_padding_check_SSLv23(to, num, buf, j, num);
+ break;
+ case RSA_NO_PADDING:
+ r = RSA_padding_check_none(to, num, buf, j, num);
+ break;
+ default:
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (r < 0)
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
+
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL) {
+ OPENSSL_cleanse(buf, num);
+ OPENSSL_free(buf);
+ }
+ return (r);
+}
+
+/* signature verification */
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ BIGNUM *f, *ret;
+ int i, num = 0, r = -1;
+ unsigned char *p;
+ unsigned char *buf = NULL;
+ BN_CTX *ctx = NULL;
+
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (BN_ucmp(rsa->n, rsa->e) <= 0) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+
+ /* for large moduli, enforce exponent limit */
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
+ if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+ }
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if (!f || !ret || !buf) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * This check was for equality but PGP does evil things and chops off the
+ * top '0' bytes
+ */
+ if (flen > num) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN);
+ goto err;
+ }
+
+ if (BN_bin2bn(from, flen, f) == NULL)
+ goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0) {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,
+ RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+
+ if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
+ rsa->_method_mod_n))
+ goto err;
+
+ if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
+ if (!BN_sub(ret, rsa->n, ret))
+ goto err;
+
+ p = buf;
+ i = BN_bn2bin(ret, p);
+
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+ r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num);
+ break;
+ case RSA_X931_PADDING:
+ r = RSA_padding_check_X931(to, num, buf, i, num);
+ break;
+ case RSA_NO_PADDING:
+ r = RSA_padding_check_none(to, num, buf, i, num);
+ break;
+ default:
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (r < 0)
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
+
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL) {
+ OPENSSL_cleanse(buf, num);
+ OPENSSL_free(buf);
+ }
+ return (r);
+}
+
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+ BIGNUM *r1, *m1, *vrfy;
+ BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
+ BIGNUM *dmp1, *dmq1, *c, *pr1;
+ int ret = 0;
+
+ BN_CTX_start(ctx);
+ r1 = BN_CTX_get(ctx);
+ m1 = BN_CTX_get(ctx);
+ vrfy = BN_CTX_get(ctx);
+
+ {
+ BIGNUM local_p, local_q;
+ BIGNUM *p = NULL, *q = NULL;
+
+ /*
+ * Make sure BN_mod_inverse in Montgomery intialization uses the
+ * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set)
+ */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ BN_init(&local_p);
+ p = &local_p;
+ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+
+ BN_init(&local_q);
+ q = &local_q;
+ BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
+ } else {
+ p = rsa->p;
+ q = rsa->q;
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
+ goto err;
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
+ goto err;
+ }
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked
+ (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+
+ /* compute I mod q */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ c = &local_c;
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
+ if (!BN_mod(r1, c, rsa->q, ctx))
+ goto err;
+ } else {
+ if (!BN_mod(r1, I, rsa->q, ctx))
+ goto err;
+ }
+
+ /* compute r1^dmq1 mod q */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ dmq1 = &local_dmq1;
+ BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
+ } else
+ dmq1 = rsa->dmq1;
+ if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q))
+ goto err;
+
+ /* compute I mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ c = &local_c;
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
+ if (!BN_mod(r1, c, rsa->p, ctx))
+ goto err;
+ } else {
+ if (!BN_mod(r1, I, rsa->p, ctx))
+ goto err;
+ }
+
+ /* compute r1^dmp1 mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ dmp1 = &local_dmp1;
+ BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
+ } else
+ dmp1 = rsa->dmp1;
+ if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p))
+ goto err;
+
+ if (!BN_sub(r0, r0, m1))
+ goto err;
+ /*
+ * This will help stop the size of r0 increasing, which does affect the
+ * multiply if it optimised for a power of 2 size
+ */
+ if (BN_is_negative(r0))
+ if (!BN_add(r0, r0, rsa->p))
+ goto err;
+
+ if (!BN_mul(r1, r0, rsa->iqmp, ctx))
+ goto err;
+
+ /* Turn BN_FLG_CONSTTIME flag on before division operation */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ pr1 = &local_r1;
+ BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
+ } else
+ pr1 = r1;
+ if (!BN_mod(r0, pr1, rsa->p, ctx))
+ goto err;
+
+ /*
+ * If p < q it is occasionally possible for the correction of adding 'p'
+ * if r0 is negative above to leave the result still negative. This can
+ * break the private key operations: the following second correction
+ * should *always* correct this rare occurrence. This will *never* happen
+ * with OpenSSL generated keys because they ensure p > q [steve]
+ */
+ if (BN_is_negative(r0))
+ if (!BN_add(r0, r0, rsa->p))
+ goto err;
+ if (!BN_mul(r1, r0, rsa->q, ctx))
+ goto err;
+ if (!BN_add(r0, r1, m1))
+ goto err;
+
+ if (rsa->e && rsa->n) {
+ if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
+ rsa->_method_mod_n))
+ goto err;
+ /*
+ * If 'I' was greater than (or equal to) rsa->n, the operation will
+ * be equivalent to using 'I mod n'. However, the result of the
+ * verify will *always* be less than 'n' so we don't check for
+ * absolute equality, just congruency.
+ */
+ if (!BN_sub(vrfy, vrfy, I))
+ goto err;
+ if (!BN_mod(vrfy, vrfy, rsa->n, ctx))
+ goto err;
+ if (BN_is_negative(vrfy))
+ if (!BN_add(vrfy, vrfy, rsa->n))
+ goto err;
+ if (!BN_is_zero(vrfy)) {
+ /*
+ * 'I' and 'vrfy' aren't congruent mod n. Don't leak
+ * miscalculated CRT output, just do a raw (slower) mod_exp and
+ * return that instead.
+ */
+
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ } else
+ d = rsa->d;
+ if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx,
+ rsa->_method_mod_n))
+ goto err;
+ }
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+static int RSA_eay_init(RSA *rsa)
+{
+ rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE;
+ return (1);
+}
+
+static int RSA_eay_finish(RSA *rsa)
+{
+ if (rsa->_method_mod_n != NULL)
+ BN_MONT_CTX_free(rsa->_method_mod_n);
+ if (rsa->_method_mod_p != NULL)
+ BN_MONT_CTX_free(rsa->_method_mod_p);
+ if (rsa->_method_mod_q != NULL)
+ BN_MONT_CTX_free(rsa->_method_mod_q);
+ return (1);
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_err.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_err.c
new file mode 100644
index 00000000..0bab05ef
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_err.c
@@ -0,0 +1,247 @@
+/* crypto/rsa/rsa_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2014 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
+
+static ERR_STRING_DATA RSA_str_functs[] = {
+ {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_VERIFY), "PKEY_RSA_VERIFY"},
+ {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
+ {ERR_FUNC(RSA_F_RSA_ALGOR_TO_MD), "RSA_ALGOR_TO_MD"},
+ {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_CMS_DECRYPT), "RSA_CMS_DECRYPT"},
+ {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
+ {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"},
+ {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"},
+ {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
+ {ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"},
+ {ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX), "RSA_generate_key_ex"},
+ {ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "RSA_ITEM_VERIFY"},
+ {ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"},
+ {ERR_FUNC(RSA_F_RSA_MGF1_TO_MD), "RSA_MGF1_TO_MD"},
+ {ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
+ {ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
+ {ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"},
+ {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"},
+ {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"},
+ {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"},
+ {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP),
+ "RSA_padding_add_PKCS1_OAEP"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1),
+ "RSA_padding_add_PKCS1_OAEP_mgf1"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1),
+ "RSA_padding_add_PKCS1_PSS_mgf1"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1),
+ "RSA_padding_add_PKCS1_type_1"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2),
+ "RSA_padding_add_PKCS1_type_2"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP),
+ "RSA_padding_check_PKCS1_OAEP"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1),
+ "RSA_padding_check_PKCS1_OAEP_mgf1"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1),
+ "RSA_padding_check_PKCS1_type_1"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2),
+ "RSA_padding_check_PKCS1_type_2"},
+ {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
+ {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_DECRYPT), "RSA_private_decrypt"},
+ {ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"},
+ {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_PSS_TO_CTX), "RSA_PSS_TO_CTX"},
+ {ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"},
+ {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"},
+ {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_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"},
+ {ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING),
+ "RSA_verify_ASN1_OCTET_STRING"},
+ {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"},
+ {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA RSA_str_reasons[] = {
+ {ERR_REASON(RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"},
+ {ERR_REASON(RSA_R_BAD_E_VALUE), "bad e value"},
+ {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"},
+ {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"},
+ {ERR_REASON(RSA_R_BAD_SIGNATURE), "bad signature"},
+ {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01), "block type is not 01"},
+ {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02), "block type is not 02"},
+ {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN),
+ "data greater than mod len"},
+ {ERR_REASON(RSA_R_DATA_TOO_LARGE), "data too large"},
+ {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),
+ "data too large for key size"},
+ {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS),
+ "data too large for modulus"},
+ {ERR_REASON(RSA_R_DATA_TOO_SMALL), "data too small"},
+ {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE),
+ "data too small for key size"},
+ {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH), "digest does not match"},
+ {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY),
+ "digest too big for rsa key"},
+ {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"},
+ {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), "invalid digest"},
+ {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_LABEL), "invalid label"},
+ {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"},
+ {ERR_REASON(RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"},
+ {ERR_REASON(RSA_R_INVALID_OAEP_PARAMETERS), "invalid oaep parameters"},
+ {ERR_REASON(RSA_R_INVALID_PADDING), "invalid padding"},
+ {ERR_REASON(RSA_R_INVALID_PADDING_MODE), "invalid padding mode"},
+ {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"},
+ {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"},
+ {ERR_REASON(RSA_R_INVALID_SALT_LENGTH), "invalid salt length"},
+ {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_RSA_METHOD), "non fips rsa 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_PKCS_DECODING_ERROR), "pkcs decoding error"},
+ {ERR_REASON(RSA_R_P_NOT_PRIME), "p not prime"},
+ {ERR_REASON(RSA_R_Q_NOT_PRIME), "q not prime"},
+ {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),
+ "rsa operations not supported"},
+ {ERR_REASON(RSA_R_SLEN_CHECK_FAILED), "salt length check failed"},
+ {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED), "salt length recovery failed"},
+ {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK), "sslv3 rollback attack"},
+ {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_DIGEST), "unknown digest"},
+ {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST), "unknown mask digest"},
+ {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE), "unknown padding type"},
+ {ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST), "unknown pss digest"},
+ {ERR_REASON(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE),
+ "unsupported encryption type"},
+ {ERR_REASON(RSA_R_UNSUPPORTED_LABEL_SOURCE), "unsupported label source"},
+ {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM),
+ "unsupported mask algorithm"},
+ {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER),
+ "unsupported mask parameter"},
+ {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE),
+ "unsupported signature type"},
+ {ERR_REASON(RSA_R_VALUE_MISSING), "value missing"},
+ {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_RSA_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, RSA_str_functs);
+ ERR_load_strings(0, RSA_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
new file mode 100644
index 00000000..7f7dca39
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
@@ -0,0 +1,250 @@
+/* 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.]
+ */
+
+/*
+ * NB: these functions have been "upgraded", the deprecated versions (which
+ * are compatibility wrappers using these functions) are in rsa_depr.c. -
+ * Geoff
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
+ BN_GENCB *cb);
+#endif
+
+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
+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here
+ * so that we don't introduce a new linker dependency. Eg. any application
+ * that wasn't previously linking object code related to key-generation won't
+ * have to now just because key-generation is part of RSA_METHOD.
+ */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD);
+ return 0;
+ }
+#endif
+ if (rsa->meth->rsa_keygen)
+ return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_rsa_x931_generate_key_ex(rsa, bits, e_value, cb);
+#endif
+ return rsa_builtin_keygen(rsa, bits, e_value, cb);
+}
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
+ BN_GENCB *cb)
+{
+ BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
+ BIGNUM local_r0, local_d, local_p;
+ BIGNUM *pr0, *d, *p;
+ int bitsp, bitsq, ok = -1, n = 0;
+ BN_CTX *ctx = NULL;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ 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;
+
+ bitsp = (bits + 1) / 2;
+ bitsq = bits - bitsp;
+
+ /* We need the RSA components non-NULL */
+ if (!rsa->n && ((rsa->n = BN_new()) == NULL))
+ goto err;
+ if (!rsa->d && ((rsa->d = BN_new()) == NULL))
+ goto err;
+ if (!rsa->e && ((rsa->e = BN_new()) == NULL))
+ goto err;
+ if (!rsa->p && ((rsa->p = BN_new()) == NULL))
+ goto err;
+ if (!rsa->q && ((rsa->q = BN_new()) == NULL))
+ goto err;
+ if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL))
+ goto err;
+ if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL))
+ goto err;
+ if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL))
+ goto err;
+
+ BN_copy(rsa->e, e_value);
+
+ /* generate p and q */
+ for (;;) {
+ if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
+ goto err;
+ if (!BN_sub(r2, rsa->p, BN_value_one()))
+ goto err;
+ if (!BN_gcd(r1, r2, rsa->e, ctx))
+ goto err;
+ if (BN_is_one(r1))
+ break;
+ if (!BN_GENCB_call(cb, 2, n++))
+ goto err;
+ }
+ if (!BN_GENCB_call(cb, 3, 0))
+ goto err;
+ for (;;) {
+ /*
+ * When generating ridiculously small keys, we can get stuck
+ * continually regenerating the same prime values. Check for this and
+ * bail if it happens 3 times.
+ */
+ unsigned int degenerate = 0;
+ do {
+ if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
+ goto err;
+ } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
+ if (degenerate == 3) {
+ ok = 0; /* we set our own err */
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+ if (!BN_sub(r2, rsa->q, BN_value_one()))
+ goto err;
+ if (!BN_gcd(r1, r2, rsa->e, ctx))
+ goto err;
+ if (BN_is_one(r1))
+ break;
+ if (!BN_GENCB_call(cb, 2, n++))
+ goto err;
+ }
+ if (!BN_GENCB_call(cb, 3, 1))
+ goto err;
+ if (BN_cmp(rsa->p, rsa->q) < 0) {
+ tmp = rsa->p;
+ rsa->p = rsa->q;
+ rsa->q = tmp;
+ }
+
+ /* calculate n */
+ if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
+ goto err;
+
+ /* calculate d */
+ if (!BN_sub(r1, rsa->p, BN_value_one()))
+ goto err; /* p-1 */
+ 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 (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ pr0 = &local_r0;
+ BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
+ } else
+ pr0 = r0;
+ if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx))
+ goto err; /* d */
+
+ /* set up d for correct BN_FLG_CONSTTIME flag */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ } else
+ d = rsa->d;
+
+ /* calculate d mod (p-1) */
+ if (!BN_mod(rsa->dmp1, d, r1, ctx))
+ goto err;
+
+ /* calculate d mod (q-1) */
+ if (!BN_mod(rsa->dmq1, d, r2, ctx))
+ goto err;
+
+ /* calculate inverse of q mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
+ p = &local_p;
+ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+ } else
+ p = rsa->p;
+ if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx))
+ goto err;
+
+ ok = 1;
+ err:
+ if (ok == -1) {
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
+ ok = 0;
+ }
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ return ok;
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_lib.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_lib.c
new file mode 100644
index 00000000..a6805deb
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_lib.c
@@ -0,0 +1,336 @@
+/* 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 <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#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 OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_rsa_pkcs1_ssleay();
+ else
+ return RSA_PKCS1_SSLeay();
+#else
+# ifdef RSA_NULL
+ default_RSA_meth = RSA_null_method();
+# 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 & ~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_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/Cryptlib/OpenSSL/crypto/rsa/rsa_locl.h b/Cryptlib/OpenSSL/crypto/rsa/rsa_locl.h
new file mode 100644
index 00000000..3e88187d
--- /dev/null
+++ b/Cryptlib/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/Cryptlib/OpenSSL/crypto/rsa/rsa_none.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_none.c
new file mode 100644
index 00000000..982b31f2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_none.c
@@ -0,0 +1,94 @@
+/* crypto/rsa/rsa_none.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_none(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+{
+ if (flen > tlen) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return (0);
+ }
+
+ if (flen < tlen) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+ return (0);
+ }
+
+ memcpy(to, from, (unsigned int)flen);
+ return (1);
+}
+
+int RSA_padding_check_none(unsigned char *to, int tlen,
+ const unsigned char *from, int flen, int num)
+{
+
+ if (flen > tlen) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE);
+ return (-1);
+ }
+
+ memset(to, 0, tlen - flen);
+ memcpy(to + tlen - flen, from, flen);
+ return (tlen);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_null.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_null.c
new file mode 100644
index 00000000..241b431a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_null.c
@@ -0,0 +1,155 @@
+/* rsa_null.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+/*
+ * This is a dummy RSA implementation that just returns errors when called.
+ * It is designed to allow some RSA functions to work while stopping those
+ * covered by the RSA patent. That is RSA, encryption, decryption, signing
+ * and verify is not allowed but RSA key generation, key checking and other
+ * operations (like storing RSA keys) are permitted.
+ */
+
+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+#if 0 /* not currently used */
+static int RSA_null_mod_exp(const BIGNUM *r0, const BIGNUM *i, RSA *rsa);
+#endif
+static int RSA_null_init(RSA *rsa);
+static int RSA_null_finish(RSA *rsa);
+static RSA_METHOD rsa_null_meth = {
+ "Null RSA",
+ RSA_null_public_encrypt,
+ RSA_null_public_decrypt,
+ RSA_null_private_encrypt,
+ RSA_null_private_decrypt,
+ NULL,
+ NULL,
+ RSA_null_init,
+ RSA_null_finish,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const RSA_METHOD *RSA_null_method(void)
+{
+ return (&rsa_null_meth);
+}
+
+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ return -1;
+}
+
+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT,
+ RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ return -1;
+}
+
+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT,
+ RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ return -1;
+}
+
+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+{
+ RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ return -1;
+}
+
+#if 0 /* not currently used */
+static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+{
+ ... err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ return -1;
+}
+#endif
+
+static int RSA_null_init(RSA *rsa)
+{
+ return (1);
+}
+
+static int RSA_null_finish(RSA *rsa)
+{
+ return (1);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_oaep.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_oaep.c
new file mode 100644
index 00000000..9c2a943c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_oaep.c
@@ -0,0 +1,283 @@
+/* crypto/rsa/rsa_oaep.c */
+/*
+ * Written by Ulf Moeller. This software is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ */
+
+/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
+
+/*
+ * See Victor Shoup, "OAEP reconsidered," Nov. 2000, <URL:
+ * http://www.shoup.net/papers/oaep.ps.Z> for problems with the security
+ * proof for the original OAEP scheme, which EME-OAEP is based on. A new
+ * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern,
+ * "RSA-OEAP is Still Alive!", Dec. 2000, <URL:
+ * http://eprint.iacr.org/2000/061/>. The new proof has stronger requirements
+ * for the underlying permutation: "partial-one-wayness" instead of
+ * one-wayness. For the RSA function, this is an equivalent notion.
+ */
+
+#include "constant_time_locl.h"
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+# include <stdio.h>
+# include "cryptlib.h"
+# include <openssl/bn.h>
+# include <openssl/rsa.h>
+# include <openssl/evp.h>
+# include <openssl/rand.h>
+# include <openssl/sha.h>
+
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+ const unsigned char *from, int flen,
+ const unsigned char *param, int plen)
+{
+ return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
+ param, plen, NULL, NULL);
+}
+
+int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+ const unsigned char *from, int flen,
+ const unsigned char *param, int plen,
+ const EVP_MD *md, const EVP_MD *mgf1md)
+{
+ int i, emlen = tlen - 1;
+ unsigned char *db, *seed;
+ unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
+ int mdlen;
+
+ if (md == NULL)
+ md = EVP_sha1();
+ if (mgf1md == NULL)
+ mgf1md = md;
+
+ mdlen = EVP_MD_size(md);
+
+ if (flen > emlen - 2 * mdlen - 1) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return 0;
+ }
+
+ if (emlen < 2 * mdlen + 1) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
+ RSA_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+
+ to[0] = 0;
+ seed = to + 1;
+ db = to + mdlen + 1;
+
+ if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
+ return 0;
+ memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
+ db[emlen - flen - mdlen - 1] = 0x01;
+ memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
+ if (RAND_bytes(seed, mdlen) <= 0)
+ return 0;
+# ifdef PKCS_TESTVECT
+ memcpy(seed,
+ "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
+ 20);
+# endif
+
+ dbmask = OPENSSL_malloc(emlen - mdlen);
+ if (dbmask == NULL) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
+ return 0;
+ for (i = 0; i < emlen - mdlen; i++)
+ db[i] ^= dbmask[i];
+
+ if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
+ return 0;
+ for (i = 0; i < mdlen; i++)
+ seed[i] ^= seedmask[i];
+
+ OPENSSL_free(dbmask);
+ return 1;
+}
+
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+ const unsigned char *from, int flen, int num,
+ const unsigned char *param, int plen)
+{
+ return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num,
+ param, plen, NULL, NULL);
+}
+
+int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+ const unsigned char *from, int flen,
+ int num, const unsigned char *param,
+ int plen, const EVP_MD *md,
+ const EVP_MD *mgf1md)
+{
+ int i, dblen, mlen = -1, one_index = 0, msg_index;
+ unsigned int good, found_one_byte;
+ const unsigned char *maskedseed, *maskeddb;
+ /*
+ * |em| is the encoded message, zero-padded to exactly |num| bytes: em =
+ * Y || maskedSeed || maskedDB
+ */
+ unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
+ phash[EVP_MAX_MD_SIZE];
+ int mdlen;
+
+ if (md == NULL)
+ md = EVP_sha1();
+ if (mgf1md == NULL)
+ mgf1md = md;
+
+ mdlen = EVP_MD_size(md);
+
+ if (tlen <= 0 || flen <= 0)
+ return -1;
+ /*
+ * |num| is the length of the modulus; |flen| is the length of the
+ * encoded message. Therefore, for any |from| that was obtained by
+ * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
+ * num < 2 * mdlen + 2 must hold for the modulus irrespective of
+ * the ciphertext, see PKCS #1 v2.2, section 7.1.2.
+ * This does not leak any side-channel information.
+ */
+ if (num < flen || num < 2 * mdlen + 2)
+ goto decoding_err;
+
+ dblen = num - mdlen - 1;
+ db = OPENSSL_malloc(dblen);
+ em = OPENSSL_malloc(num);
+ if (db == NULL || em == NULL) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+ goto cleanup;
+ }
+
+ /*
+ * Always do this zero-padding copy (even when num == flen) to avoid
+ * leaking that information. The copy still leaks some side-channel
+ * information, but it's impossible to have a fixed memory access
+ * pattern since we can't read out of the bounds of |from|.
+ *
+ * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+ */
+ memset(em, 0, num);
+ memcpy(em + num - flen, from, flen);
+
+ /*
+ * The first byte must be zero, however we must not leak if this is
+ * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA
+ * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
+ */
+ good = constant_time_is_zero(em[0]);
+
+ maskedseed = em + 1;
+ maskeddb = em + 1 + mdlen;
+
+ if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
+ goto cleanup;
+ for (i = 0; i < mdlen; i++)
+ seed[i] ^= maskedseed[i];
+
+ if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
+ goto cleanup;
+ for (i = 0; i < dblen; i++)
+ db[i] ^= maskeddb[i];
+
+ if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
+ goto cleanup;
+
+ good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
+
+ found_one_byte = 0;
+ for (i = mdlen; i < dblen; i++) {
+ /*
+ * Padding consists of a number of 0-bytes, followed by a 1.
+ */
+ unsigned int equals1 = constant_time_eq(db[i], 1);
+ unsigned int equals0 = constant_time_is_zero(db[i]);
+ one_index = constant_time_select_int(~found_one_byte & equals1,
+ i, one_index);
+ found_one_byte |= equals1;
+ good &= (found_one_byte | equals0);
+ }
+
+ good &= found_one_byte;
+
+ /*
+ * At this point |good| is zero unless the plaintext was valid,
+ * so plaintext-awareness ensures timing side-channels are no longer a
+ * concern.
+ */
+ if (!good)
+ goto decoding_err;
+
+ msg_index = one_index + 1;
+ mlen = dblen - msg_index;
+
+ if (tlen < mlen) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
+ mlen = -1;
+ } else {
+ memcpy(to, db + msg_index, mlen);
+ goto cleanup;
+ }
+
+ decoding_err:
+ /*
+ * To avoid chosen ciphertext attacks, the error message should not
+ * reveal which kind of decoding error happened.
+ */
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,
+ RSA_R_OAEP_DECODING_ERROR);
+ cleanup:
+ if (db != NULL)
+ OPENSSL_free(db);
+ if (em != NULL)
+ OPENSSL_free(em);
+ return mlen;
+}
+
+int PKCS1_MGF1(unsigned char *mask, long len,
+ const unsigned char *seed, long seedlen, const EVP_MD *dgst)
+{
+ long i, outlen = 0;
+ unsigned char cnt[4];
+ EVP_MD_CTX c;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ int mdlen;
+ int rv = -1;
+
+ EVP_MD_CTX_init(&c);
+ mdlen = EVP_MD_size(dgst);
+ if (mdlen < 0)
+ goto err;
+ for (i = 0; outlen < len; i++) {
+ cnt[0] = (unsigned char)((i >> 24) & 255);
+ cnt[1] = (unsigned char)((i >> 16) & 255);
+ cnt[2] = (unsigned char)((i >> 8)) & 255;
+ cnt[3] = (unsigned char)(i & 255);
+ if (!EVP_DigestInit_ex(&c, dgst, NULL)
+ || !EVP_DigestUpdate(&c, seed, seedlen)
+ || !EVP_DigestUpdate(&c, cnt, 4))
+ goto err;
+ if (outlen + mdlen <= len) {
+ if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
+ goto err;
+ outlen += mdlen;
+ } else {
+ if (!EVP_DigestFinal_ex(&c, md, NULL))
+ goto err;
+ memcpy(mask + outlen, md, len - outlen);
+ outlen = len;
+ }
+ }
+ rv = 0;
+ err:
+ EVP_MD_CTX_cleanup(&c);
+ return rv;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_pk1.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_pk1.c
new file mode 100644
index 00000000..efa1fd3e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_pk1.c
@@ -0,0 +1,275 @@
+/* crypto/rsa/rsa_pk1.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 "constant_time_locl.h"
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+{
+ int j;
+ unsigned char *p;
+
+ if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return (0);
+ }
+
+ p = (unsigned char *)to;
+
+ *(p++) = 0;
+ *(p++) = 1; /* Private Key BT (Block Type) */
+
+ /* pad out with 0xff data */
+ j = tlen - 3 - flen;
+ memset(p, 0xff, j);
+ p += j;
+ *(p++) = '\0';
+ memcpy(p, from, (unsigned int)flen);
+ return (1);
+}
+
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+ const unsigned char *from, int flen,
+ int num)
+{
+ int i, j;
+ const unsigned char *p;
+
+ p = from;
+ if ((num != (flen + 1)) || (*(p++) != 01)) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+ RSA_R_BLOCK_TYPE_IS_NOT_01);
+ return (-1);
+ }
+
+ /* scan over padding data */
+ j = flen - 1; /* one for type. */
+ for (i = 0; i < j; i++) {
+ if (*p != 0xff) { /* should decrypt to 0xff */
+ if (*p == 0) {
+ p++;
+ break;
+ } else {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+ RSA_R_BAD_FIXED_HEADER_DECRYPT);
+ return (-1);
+ }
+ }
+ p++;
+ }
+
+ if (i == j) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+ RSA_R_NULL_BEFORE_BLOCK_MISSING);
+ return (-1);
+ }
+
+ if (i < 8) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+ RSA_R_BAD_PAD_BYTE_COUNT);
+ return (-1);
+ }
+ i++; /* Skip over the '\0' */
+ j -= i;
+ if (j > tlen) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE);
+ return (-1);
+ }
+ memcpy(to, p, (unsigned int)j);
+
+ return (j);
+}
+
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+{
+ int i, j;
+ unsigned char *p;
+
+ if (flen > (tlen - 11)) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return (0);
+ }
+
+ p = (unsigned char *)to;
+
+ *(p++) = 0;
+ *(p++) = 2; /* Public Key BT (Block Type) */
+
+ /* pad out with non-zero random data */
+ j = tlen - 3 - flen;
+
+ if (RAND_bytes(p, j) <= 0)
+ return (0);
+ for (i = 0; i < j; i++) {
+ if (*p == '\0')
+ do {
+ if (RAND_bytes(p, 1) <= 0)
+ return (0);
+ } while (*p == '\0');
+ p++;
+ }
+
+ *(p++) = '\0';
+
+ memcpy(p, from, (unsigned int)flen);
+ return (1);
+}
+
+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+ const unsigned char *from, int flen,
+ int num)
+{
+ int i;
+ /* |em| is the encoded message, zero-padded to exactly |num| bytes */
+ unsigned char *em = NULL;
+ unsigned int good, found_zero_byte;
+ int zero_index = 0, msg_index, mlen = -1;
+
+ if (tlen < 0 || flen < 0)
+ return -1;
+
+ /*
+ * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
+ * section 7.2.2.
+ */
+
+ if (flen > num)
+ goto err;
+
+ if (num < 11)
+ goto err;
+
+ em = OPENSSL_malloc(num);
+ if (em == NULL) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ memset(em, 0, num);
+ /*
+ * Always do this zero-padding copy (even when num == flen) to avoid
+ * leaking that information. The copy still leaks some side-channel
+ * information, but it's impossible to have a fixed memory access
+ * pattern since we can't read out of the bounds of |from|.
+ *
+ * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+ */
+ memcpy(em + num - flen, from, flen);
+
+ good = constant_time_is_zero(em[0]);
+ good &= constant_time_eq(em[1], 2);
+
+ found_zero_byte = 0;
+ for (i = 2; i < num; i++) {
+ unsigned int equals0 = constant_time_is_zero(em[i]);
+ zero_index =
+ constant_time_select_int(~found_zero_byte & equals0, i,
+ zero_index);
+ found_zero_byte |= equals0;
+ }
+
+ /*
+ * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+ * If we never found a 0-byte, then |zero_index| is 0 and the check
+ * also fails.
+ */
+ good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);
+
+ /*
+ * Skip the zero byte. This is incorrect if we never found a zero-byte
+ * but in this case we also do not copy the message out.
+ */
+ msg_index = zero_index + 1;
+ mlen = num - msg_index;
+
+ /*
+ * For good measure, do this check in constant time as well; it could
+ * leak something if |tlen| was assuming valid padding.
+ */
+ good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));
+
+ /*
+ * We can't continue in constant-time because we need to copy the result
+ * and we cannot fake its length. This unavoidably leaks timing
+ * information at the API boundary.
+ * TODO(emilia): this could be addressed at the call site,
+ * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
+ */
+ if (!good) {
+ mlen = -1;
+ goto err;
+ }
+
+ memcpy(to, em + msg_index, mlen);
+
+ err:
+ if (em != NULL)
+ OPENSSL_free(em);
+ if (mlen == -1)
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
+ RSA_R_PKCS_DECODING_ERROR);
+ return mlen;
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c
new file mode 100644
index 00000000..20363559
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c
@@ -0,0 +1,784 @@
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_CMS
+# include <openssl/cms.h>
+#endif
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#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;
+ /* message digest for MGF1 */
+ const EVP_MD *mgf1md;
+ /* PSS salt length */
+ int saltlen;
+ /* Temp buffer */
+ unsigned char *tbuf;
+ /* OAEP label */
+ unsigned char *oaep_label;
+ size_t oaep_labellen;
+} 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->mgf1md = NULL;
+ rctx->tbuf = NULL;
+
+ rctx->saltlen = -2;
+
+ rctx->oaep_label = NULL;
+ rctx->oaep_labellen = 0;
+
+ 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;
+ dctx->mgf1md = sctx->mgf1md;
+ if (sctx->oaep_label) {
+ if (dctx->oaep_label)
+ OPENSSL_free(dctx->oaep_label);
+ dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
+ if (!dctx->oaep_label)
+ return 0;
+ dctx->oaep_labellen = sctx->oaep_labellen;
+ }
+ 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);
+ if (rctx->oaep_label)
+ OPENSSL_free(rctx->oaep_label);
+ OPENSSL_free(rctx);
+ }
+}
+
+#ifdef OPENSSL_FIPS
+/*
+ * FIP checker. Return value indicates status of context parameters: 1 :
+ * redirect to FIPS. 0 : don't redirect to FIPS. -1 : illegal operation in
+ * FIPS mode.
+ */
+
+static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx)
+{
+ RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
+ int rv = -1;
+ if (!FIPS_mode())
+ return 0;
+ if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+ rv = 0;
+ if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv)
+ return -1;
+ if (rctx->md) {
+ const EVP_MD *fmd;
+ fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md));
+ if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS))
+ return rv;
+ }
+ if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) {
+ const EVP_MD *fmd;
+ fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md));
+ if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS))
+ return rv;
+ }
+ return 1;
+}
+#endif
+
+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;
+
+#ifdef OPENSSL_FIPS
+ ret = pkey_fips_check_ctx(ctx);
+ if (ret < 0) {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+ return -1;
+ }
+#endif
+
+ 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;
+ }
+#ifdef OPENSSL_FIPS
+ if (ret > 0) {
+ unsigned int slen;
+ ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md,
+ rctx->pad_mode,
+ rctx->saltlen,
+ rctx->mgf1md, sig, &slen);
+ if (ret > 0)
+ *siglen = slen;
+ else
+ *siglen = 0;
+ return ret;
+ }
+#endif
+
+ if (EVP_MD_type(rctx->md) == NID_mdc2) {
+ unsigned int sltmp;
+ if (rctx->pad_mode != RSA_PKCS1_PADDING)
+ return -1;
+ ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2,
+ tbs, tbslen, sig, &sltmp, rsa);
+
+ if (ret <= 0)
+ return ret;
+ ret = sltmp;
+ } else if (rctx->pad_mode == RSA_X931_PADDING) {
+ if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
+ }
+ if (!setup_tbuf(rctx, ctx)) {
+ RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE);
+ 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_mgf1(rsa,
+ rctx->tbuf, tbs,
+ rctx->md, rctx->mgf1md,
+ 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;
+#ifdef OPENSSL_FIPS
+ int rv;
+ rv = pkey_fips_check_ctx(ctx);
+ if (rv < 0) {
+ RSAerr(RSA_F_PKEY_RSA_VERIFY,
+ RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+ return -1;
+ }
+#endif
+ if (rctx->md) {
+#ifdef OPENSSL_FIPS
+ if (rv > 0) {
+ return FIPS_rsa_verify_digest(rsa,
+ tbs, tbslen,
+ rctx->md,
+ rctx->pad_mode,
+ rctx->saltlen,
+ rctx->mgf1md, sig, siglen);
+
+ }
+#endif
+ 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_mgf1(rsa, tbs,
+ rctx->md, rctx->mgf1md,
+ 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;
+ if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+ int klen = RSA_size(ctx->pkey->pkey.rsa);
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
+ in, inlen,
+ rctx->oaep_label,
+ rctx->oaep_labellen,
+ rctx->md, rctx->mgf1md))
+ return -1;
+ ret = RSA_public_encrypt(klen, rctx->tbuf, out,
+ ctx->pkey->pkey.rsa, RSA_NO_PADDING);
+ } else
+ 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;
+ if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+ int i;
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
+ ctx->pkey->pkey.rsa, RSA_NO_PADDING);
+ if (ret <= 0)
+ return ret;
+ for (i = 0; i < ret; i++) {
+ if (rctx->tbuf[i])
+ break;
+ }
+ ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i,
+ ret - i, ret,
+ rctx->oaep_label,
+ rctx->oaep_labellen,
+ rctx->md, rctx->mgf1md);
+ } else
+ 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_GET_RSA_PADDING:
+ *(int *)p2 = rctx->pad_mode;
+ return 1;
+
+ case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
+ case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
+ if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+ return -2;
+ }
+ if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
+ *(int *)p2 = rctx->saltlen;
+ else {
+ if (p1 < -2)
+ 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;
+ BN_free(rctx->pub_exp);
+ rctx->pub_exp = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_RSA_OAEP_MD:
+ case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
+ if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
+ return -2;
+ }
+ if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD)
+ *(const EVP_MD **)p2 = rctx->md;
+ else
+ rctx->md = 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_GET_MD:
+ *(const EVP_MD **)p2 = rctx->md;
+ return 1;
+
+ case EVP_PKEY_CTRL_RSA_MGF1_MD:
+ case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
+ if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING
+ && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
+ return -2;
+ }
+ if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
+ if (rctx->mgf1md)
+ *(const EVP_MD **)p2 = rctx->mgf1md;
+ else
+ *(const EVP_MD **)p2 = rctx->md;
+ } else
+ rctx->mgf1md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
+ if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
+ return -2;
+ }
+ if (rctx->oaep_label)
+ OPENSSL_free(rctx->oaep_label);
+ if (p2 && p1 > 0) {
+ rctx->oaep_label = p2;
+ rctx->oaep_labellen = p1;
+ } else {
+ rctx->oaep_label = NULL;
+ rctx->oaep_labellen = 0;
+ }
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
+ if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
+ return -2;
+ }
+ *(unsigned char **)p2 = rctx->oaep_label;
+ return rctx->oaep_labellen;
+
+ case EVP_PKEY_CTRL_DIGESTINIT:
+ case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+ case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
+ return 1;
+#ifndef OPENSSL_NO_CMS
+ case EVP_PKEY_CTRL_CMS_DECRYPT:
+ case EVP_PKEY_CTRL_CMS_ENCRYPT:
+ case EVP_PKEY_CTRL_CMS_SIGN:
+ return 1;
+#endif
+ 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, "oaep"))
+ 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;
+ }
+
+ if (!strcmp(type, "rsa_mgf1_md")) {
+ const EVP_MD *md;
+ if (!(md = EVP_get_digestbyname(value))) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md);
+ }
+
+ if (!strcmp(type, "rsa_oaep_md")) {
+ const EVP_MD *md;
+ if (!(md = EVP_get_digestbyname(value))) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md);
+ }
+ if (!strcmp(type, "rsa_oaep_label")) {
+ unsigned char *lab;
+ long lablen;
+ int ret;
+ lab = string_to_hex(value, &lablen);
+ if (!lab)
+ return 0;
+ ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
+ if (ret <= 0)
+ OPENSSL_free(lab);
+ 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/Cryptlib/OpenSSL/crypto/rsa/rsa_prn.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_prn.c
new file mode 100644
index 00000000..076f871b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_prn.c
@@ -0,0 +1,92 @@
+/* crypto/rsa/rsa_prn.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+
+#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/Cryptlib/OpenSSL/crypto/rsa/rsa_pss.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_pss.c
new file mode 100644
index 00000000..41bc0844
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_pss.c
@@ -0,0 +1,290 @@
+/* rsa_pss.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#if defined(_MSC_VER) && defined(_ARM_)
+# pragma optimize("g", off)
+#endif
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const unsigned char *EM,
+ int sLen)
+{
+ return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
+}
+
+int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+ const unsigned char *EM, int sLen)
+{
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ const unsigned char *H;
+ unsigned char *DB = NULL;
+ EVP_MD_CTX ctx;
+ unsigned char H_[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX_init(&ctx);
+
+ if (mgf1Hash == NULL)
+ mgf1Hash = Hash;
+
+ hLen = EVP_MD_size(Hash);
+ if (hLen < 0)
+ goto err;
+ /*-
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is autorecovered from signature
+ * -N reserved
+ */
+ if (sLen == -1)
+ sLen = hLen;
+ else if (sLen == -2)
+ sLen = -2;
+ else if (sLen < -2) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (EM[0] & (0xFF << MSBits)) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
+ goto err;
+ }
+ if (MSBits == 0) {
+ EM++;
+ emLen--;
+ }
+ if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+ goto err;
+ }
+ if (EM[emLen - 1] != 0xbc) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ DB = OPENSSL_malloc(maskedDBLen);
+ if (!DB) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
+ goto err;
+ for (i = 0; i < maskedDBLen; i++)
+ DB[i] ^= EM[i];
+ if (MSBits)
+ DB[0] &= 0xFF >> (8 - MSBits);
+ for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
+ if (DB[i++] != 0x1) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
+ goto err;
+ }
+ if (sLen >= 0 && (maskedDBLen - i) != sLen) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+ if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
+ || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
+ || !EVP_DigestUpdate(&ctx, mHash, hLen))
+ goto err;
+ if (maskedDBLen - i) {
+ if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
+ goto err;
+ }
+ if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
+ goto err;
+ if (memcmp(H_, H, hLen)) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
+ ret = 0;
+ } else
+ ret = 1;
+
+ err:
+ if (DB)
+ OPENSSL_free(DB);
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return ret;
+
+}
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, int sLen)
+{
+ return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
+}
+
+int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+ int sLen)
+{
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ unsigned char *H, *salt = NULL, *p;
+ EVP_MD_CTX ctx;
+
+ if (mgf1Hash == NULL)
+ mgf1Hash = Hash;
+
+ hLen = EVP_MD_size(Hash);
+ if (hLen < 0)
+ goto err;
+ /*-
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is maximized
+ * -N reserved
+ */
+ if (sLen == -1)
+ sLen = hLen;
+ else if (sLen == -2)
+ sLen = -2;
+ else if (sLen < -2) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (MSBits == 0) {
+ *EM++ = 0;
+ emLen--;
+ }
+ if (sLen == -2) {
+ sLen = emLen - hLen - 2;
+ } else if (emLen < (hLen + sLen + 2)) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ goto err;
+ }
+ if (sLen > 0) {
+ salt = OPENSSL_malloc(sLen);
+ if (!salt) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (RAND_bytes(salt, sLen) <= 0)
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
+ || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
+ || !EVP_DigestUpdate(&ctx, mHash, hLen))
+ goto err;
+ if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx, H, NULL))
+ goto err;
+ EVP_MD_CTX_cleanup(&ctx);
+
+ /* Generate dbMask in place then perform XOR on it */
+ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
+ goto err;
+
+ p = EM;
+
+ /*
+ * Initial PS XORs with all zeroes which is a NOP so just update pointer.
+ * Note from a test above this value is guaranteed to be non-negative.
+ */
+ p += emLen - sLen - hLen - 2;
+ *p++ ^= 0x1;
+ if (sLen > 0) {
+ for (i = 0; i < sLen; i++)
+ *p++ ^= salt[i];
+ }
+ if (MSBits)
+ EM[0] &= 0xFF >> (8 - MSBits);
+
+ /* H is already in place so just set final 0xbc */
+
+ EM[emLen - 1] = 0xbc;
+
+ ret = 1;
+
+ err:
+ if (salt)
+ OPENSSL_free(salt);
+
+ return ret;
+
+}
+
+#if defined(_MSC_VER)
+# pragma optimize("",on)
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_saos.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_saos.c
new file mode 100644
index 00000000..e4002360
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_saos.c
@@ -0,0 +1,148 @@
+/* crypto/rsa/rsa_saos.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int RSA_sign_ASN1_OCTET_STRING(int type,
+ const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen,
+ RSA *rsa)
+{
+ ASN1_OCTET_STRING sig;
+ int i, j, ret = 1;
+ unsigned char *p, *s;
+
+ sig.type = V_ASN1_OCTET_STRING;
+ sig.length = m_len;
+ sig.data = (unsigned char *)m;
+
+ i = i2d_ASN1_OCTET_STRING(&sig, NULL);
+ j = RSA_size(rsa);
+ if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
+ RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,
+ RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+ return (0);
+ }
+ s = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1);
+ if (s == NULL) {
+ RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ p = s;
+ i2d_ASN1_OCTET_STRING(&sig, &p);
+ i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
+ if (i <= 0)
+ ret = 0;
+ else
+ *siglen = i;
+
+ OPENSSL_cleanse(s, (unsigned int)j + 1);
+ OPENSSL_free(s);
+ return (ret);
+}
+
+int RSA_verify_ASN1_OCTET_STRING(int dtype,
+ const unsigned char *m,
+ unsigned int m_len, unsigned char *sigbuf,
+ unsigned int siglen, RSA *rsa)
+{
+ int i, ret = 0;
+ unsigned char *s;
+ const unsigned char *p;
+ ASN1_OCTET_STRING *sig = NULL;
+
+ if (siglen != (unsigned int)RSA_size(rsa)) {
+ RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,
+ RSA_R_WRONG_SIGNATURE_LENGTH);
+ return (0);
+ }
+
+ s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen);
+ if (s == NULL) {
+ RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
+
+ if (i <= 0)
+ goto err;
+
+ p = s;
+ sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i);
+ if (sig == NULL)
+ goto err;
+
+ if (((unsigned int)sig->length != m_len) ||
+ (memcmp(m, sig->data, m_len) != 0)) {
+ RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE);
+ } else
+ ret = 1;
+ err:
+ if (sig != NULL)
+ M_ASN1_OCTET_STRING_free(sig);
+ if (s != NULL) {
+ OPENSSL_cleanse(s, (unsigned int)siglen);
+ OPENSSL_free(s);
+ }
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_sign.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_sign.c
new file mode 100644
index 00000000..82ca8324
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_sign.c
@@ -0,0 +1,301 @@
+/* crypto/rsa/rsa_sign.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "rsa_locl.h"
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define SSL_SIG_LENGTH 36
+
+int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+{
+ X509_SIG sig;
+ ASN1_TYPE parameter;
+ int i, j, ret = 1;
+ unsigned char *p, *tmps = NULL;
+ const unsigned char *s = NULL;
+ X509_ALGOR algor;
+ ASN1_OCTET_STRING digest;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD);
+ return 0;
+ }
+#endif
+ if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) {
+ return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
+ }
+ /* Special case: SSL signature, just check the length */
+ if (type == NID_md5_sha1) {
+ if (m_len != SSL_SIG_LENGTH) {
+ RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
+ return (0);
+ }
+ i = SSL_SIG_LENGTH;
+ s = m;
+ } else {
+ sig.algor = &algor;
+ sig.algor->algorithm = OBJ_nid2obj(type);
+ if (sig.algor->algorithm == NULL) {
+ RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return (0);
+ }
+ if (sig.algor->algorithm->length == 0) {
+ RSAerr(RSA_F_RSA_SIGN,
+ RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+ return (0);
+ }
+ parameter.type = V_ASN1_NULL;
+ parameter.value.ptr = NULL;
+ sig.algor->parameter = &parameter;
+
+ sig.digest = &digest;
+ sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
+ sig.digest->length = m_len;
+
+ i = i2d_X509_SIG(&sig, NULL);
+ }
+ j = RSA_size(rsa);
+ if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
+ RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+ return (0);
+ }
+ if (type != NID_md5_sha1) {
+ tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1);
+ if (tmps == NULL) {
+ RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ p = tmps;
+ i2d_X509_SIG(&sig, &p);
+ s = tmps;
+ }
+ i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
+ if (i <= 0)
+ ret = 0;
+ else
+ *siglen = i;
+
+ if (type != NID_md5_sha1) {
+ OPENSSL_cleanse(tmps, (unsigned int)j + 1);
+ OPENSSL_free(tmps);
+ }
+ return (ret);
+}
+
+/*
+ * Check DigestInfo structure does not contain extraneous data by reencoding
+ * using DER and checking encoding against original.
+ */
+static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo,
+ int dinfolen)
+{
+ unsigned char *der = NULL;
+ int derlen;
+ int ret = 0;
+ derlen = i2d_X509_SIG(sig, &der);
+ if (derlen <= 0)
+ return 0;
+ if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
+ ret = 1;
+ OPENSSL_cleanse(der, derlen);
+ OPENSSL_free(der);
+ return ret;
+}
+
+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;
+ X509_SIG *sig = NULL;
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD);
+ return 0;
+ }
+#endif
+
+ if (siglen != (unsigned int)RSA_size(rsa)) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
+ return (0);
+ }
+
+ if ((dtype == NID_md5_sha1) && rm) {
+ 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_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
+ goto err;
+ }
+ i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
+
+ if (i <= 0)
+ goto err;
+ /*
+ * Oddball MDC2 case: signature can be OCTET STRING. check for correct
+ * tag and length octets.
+ */
+ if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) {
+ if (rm) {
+ memcpy(rm, s + 2, 16);
+ *prm_len = 16;
+ ret = 1;
+ } else if (memcmp(m, s + 2, 16)) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+ } else {
+ ret = 1;
+ }
+ } else if (dtype == NID_md5_sha1) {
+ /* Special case: SSL signature */
+ if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+ else
+ ret = 1;
+ } else {
+ const unsigned char *p = s;
+ sig = d2i_X509_SIG(NULL, &p, (long)i);
+
+ if (sig == NULL)
+ goto err;
+
+ /* Excess data can be used to create forgeries */
+ if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+
+ /*
+ * Parameters to the signature algorithm can also be used to create
+ * forgeries
+ */
+ if (sig->algor->parameter
+ && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+
+ sigtype = OBJ_obj2nid(sig->algor->algorithm);
+
+#ifdef RSA_DEBUG
+ /* put a backward compatibility flag in EAY */
+ fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
+ OBJ_nid2ln(dtype));
+#endif
+ if (sigtype != dtype) {
+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
+ goto err;
+ }
+ 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_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+ } else
+ ret = 1;
+ }
+ err:
+ if (sig != NULL)
+ X509_SIG_free(sig);
+ if (s != NULL) {
+ OPENSSL_cleanse(s, (unsigned int)siglen);
+ OPENSSL_free(s);
+ }
+ 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/Cryptlib/OpenSSL/crypto/rsa/rsa_ssl.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_ssl.c
new file mode 100644
index 00000000..746e01f6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_ssl.c
@@ -0,0 +1,149 @@
+/* crypto/rsa/rsa_ssl.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+{
+ int i, j;
+ unsigned char *p;
+
+ if (flen > (tlen - 11)) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return (0);
+ }
+
+ p = (unsigned char *)to;
+
+ *(p++) = 0;
+ *(p++) = 2; /* Public Key BT (Block Type) */
+
+ /* pad out with non-zero random data */
+ j = tlen - 3 - 8 - flen;
+
+ if (RAND_bytes(p, j) <= 0)
+ return (0);
+ for (i = 0; i < j; i++) {
+ if (*p == '\0')
+ do {
+ if (RAND_bytes(p, 1) <= 0)
+ return (0);
+ } while (*p == '\0');
+ p++;
+ }
+
+ memset(p, 3, 8);
+ p += 8;
+ *(p++) = '\0';
+
+ memcpy(p, from, (unsigned int)flen);
+ return (1);
+}
+
+int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
+ const unsigned char *from, int flen, int num)
+{
+ int i, j, k;
+ const unsigned char *p;
+
+ p = from;
+ if (flen < 10) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL);
+ return (-1);
+ }
+ if ((num != (flen + 1)) || (*(p++) != 02)) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02);
+ return (-1);
+ }
+
+ /* scan over padding data */
+ j = flen - 1; /* one for type */
+ for (i = 0; i < j; i++)
+ if (*(p++) == 0)
+ break;
+
+ if ((i == j) || (i < 8)) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,
+ RSA_R_NULL_BEFORE_BLOCK_MISSING);
+ return (-1);
+ }
+ for (k = -9; k < -1; k++) {
+ if (p[k] != 0x03)
+ break;
+ }
+ if (k == -1) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK);
+ return (-1);
+ }
+
+ i++; /* Skip over the '\0' */
+ j -= i;
+ if (j > tlen) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE);
+ return (-1);
+ }
+ memcpy(to, p, (unsigned int)j);
+
+ return (j);
+}
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_x931.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_x931.c
new file mode 100644
index 00000000..725ead04
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_x931.c
@@ -0,0 +1,167 @@
+/* rsa_x931.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+
+int RSA_padding_add_X931(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+{
+ int j;
+ unsigned char *p;
+
+ /*
+ * Absolute minimum amount of padding is 1 header nibble, 1 padding
+ * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+ */
+
+ j = tlen - flen - 2;
+
+ if (j < 0) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return -1;
+ }
+
+ p = (unsigned char *)to;
+
+ /* If no padding start and end nibbles are in one byte */
+ if (j == 0)
+ *p++ = 0x6A;
+ else {
+ *p++ = 0x6B;
+ if (j > 1) {
+ memset(p, 0xBB, j - 1);
+ p += j - 1;
+ }
+ *p++ = 0xBA;
+ }
+ memcpy(p, from, (unsigned int)flen);
+ p += flen;
+ *p = 0xCC;
+ return (1);
+}
+
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+ const unsigned char *from, int flen, int num)
+{
+ int i = 0, j;
+ const unsigned char *p;
+
+ p = from;
+ if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER);
+ return -1;
+ }
+
+ if (*p++ == 0x6B) {
+ j = flen - 3;
+ for (i = 0; i < j; i++) {
+ unsigned char c = *p++;
+ if (c == 0xBA)
+ break;
+ if (c != 0xBB) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+ return -1;
+ }
+ }
+
+ j -= i;
+
+ if (i == 0) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+ return -1;
+ }
+
+ } else
+ j = flen - 2;
+
+ if (p[j] != 0xCC) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+ return -1;
+ }
+
+ memcpy(to, p, (unsigned int)j);
+
+ return (j);
+}
+
+/* Translate between X931 hash ids and NIDs */
+
+int RSA_X931_hash_id(int nid)
+{
+ switch (nid) {
+ case NID_sha1:
+ return 0x33;
+
+ case NID_sha256:
+ return 0x34;
+
+ case NID_sha384:
+ return 0x36;
+
+ case NID_sha512:
+ return 0x35;
+
+ }
+ return -1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha1_one.c b/Cryptlib/OpenSSL/crypto/sha/sha1_one.c
new file mode 100644
index 00000000..a6dd760a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha1_one.c
@@ -0,0 +1,79 @@
+/* crypto/sha/sha1_one.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 <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+
+#ifndef OPENSSL_NO_SHA1
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
+{
+ SHA_CTX c;
+ static unsigned char m[SHA_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ if (!SHA1_Init(&c))
+ return NULL;
+ SHA1_Update(&c, d, n);
+ SHA1_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c));
+ return (md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha1dgst.c b/Cryptlib/OpenSSL/crypto/sha/sha1dgst.c
new file mode 100644
index 00000000..a67f1fe3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha1dgst.c
@@ -0,0 +1,74 @@
+/* crypto/sha/sha1dgst.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 <openssl/crypto.h>
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
+
+# undef SHA_0
+# define SHA_1
+
+# include <openssl/opensslv.h>
+
+const char SHA1_version[] = "SHA1" OPENSSL_VERSION_PTEXT;
+
+/* The implementation is in ../md32_common.h */
+
+# include "sha_locl.h"
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha256.c b/Cryptlib/OpenSSL/crypto/sha/sha256.c
new file mode 100644
index 00000000..72a11593
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha256.c
@@ -0,0 +1,387 @@
+/* crypto/sha/sha256.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved
+ * according to the OpenSSL license [found in ../../LICENSE].
+ * ====================================================================
+ */
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
+
+# include <stdlib.h>
+# include <string.h>
+
+# include <openssl/crypto.h>
+# include <openssl/sha.h>
+# include <openssl/opensslv.h>
+
+const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT;
+
+fips_md_init_ctx(SHA224, SHA256)
+{
+ 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->md_len = SHA224_DIGEST_LENGTH;
+ return 1;
+}
+
+fips_md_init(SHA256)
+{
+ 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->md_len = SHA256_DIGEST_LENGTH;
+ return 1;
+}
+
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
+{
+ SHA256_CTX c;
+ static unsigned char m[SHA224_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ SHA224_Init(&c);
+ SHA256_Update(&c, d, n);
+ SHA256_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c));
+ return (md);
+}
+
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
+{
+ SHA256_CTX c;
+ static unsigned char m[SHA256_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ SHA256_Init(&c);
+ SHA256_Update(&c, d, n);
+ SHA256_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c));
+ return (md);
+}
+
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
+{
+ return SHA256_Update(c, data, len);
+}
+
+int SHA224_Final(unsigned char *md, SHA256_CTX *c)
+{
+ return SHA256_Final(md, c);
+}
+
+# define DATA_ORDER_IS_BIG_ENDIAN
+
+# define HASH_LONG SHA_LONG
+# define HASH_CTX SHA256_CTX
+# define HASH_CBLOCK SHA_CBLOCK
+/*
+ * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
+ * default: case below covers for it. It's not clear however if it's
+ * permitted to truncate to amount of bytes not divisible by 4. I bet not,
+ * but if it is, then default: case shall be extended. For reference.
+ * Idea behind separate cases for pre-defined lenghts is to let the
+ * compiler decide if it's appropriate to unroll small loops.
+ */
+# define HASH_MAKE_STRING(c,s) do { \
+ unsigned long ll; \
+ unsigned int nn; \
+ switch ((c)->md_len) \
+ { case SHA224_DIGEST_LENGTH: \
+ for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \
+ { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \
+ break; \
+ case SHA256_DIGEST_LENGTH: \
+ for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \
+ { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \
+ break; \
+ default: \
+ if ((c)->md_len > SHA256_DIGEST_LENGTH) \
+ return 0; \
+ for (nn=0;nn<(c)->md_len/4;nn++) \
+ { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \
+ break; \
+ } \
+ } while (0)
+
+# define HASH_UPDATE SHA256_Update
+# define HASH_TRANSFORM SHA256_Transform
+# define HASH_FINAL SHA256_Final
+# define HASH_BLOCK_DATA_ORDER sha256_block_data_order
+# ifndef SHA256_ASM
+static
+# endif
+void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
+
+# include "md32_common.h"
+
+# ifndef SHA256_ASM
+static const SHA_LONG K256[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+ 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+ 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+ 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+ 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+ 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+ 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+ 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+ 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+ 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+ 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+ 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+ 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/*
+ * FIPS specification refers to right rotations, while our ROTATE macro
+ * is left one. This is why you might notice that rotation coefficients
+ * differ from those observed in FIPS document by 32-N...
+ */
+# define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
+# define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
+# define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
+# define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
+
+# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+# ifdef OPENSSL_SMALL_FOOTPRINT
+
+static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
+ size_t num)
+{
+ unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2;
+ SHA_LONG X[16], l;
+ int i;
+ const unsigned char *data = in;
+
+ while (num--) {
+
+ a = ctx->h[0];
+ b = ctx->h[1];
+ c = ctx->h[2];
+ d = ctx->h[3];
+ e = ctx->h[4];
+ f = ctx->h[5];
+ g = ctx->h[6];
+ h = ctx->h[7];
+
+ for (i = 0; i < 16; i++) {
+ HOST_c2l(data, l);
+ T1 = X[i] = l;
+ T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
+ T2 = Sigma0(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+ }
+
+ for (; i < 64; i++) {
+ s0 = X[(i + 1) & 0x0f];
+ s0 = sigma0(s0);
+ s1 = X[(i + 14) & 0x0f];
+ s1 = sigma1(s1);
+
+ T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
+ T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
+ T2 = Sigma0(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+ }
+
+ ctx->h[0] += a;
+ ctx->h[1] += b;
+ ctx->h[2] += c;
+ ctx->h[3] += d;
+ ctx->h[4] += e;
+ ctx->h[5] += f;
+ ctx->h[6] += g;
+ ctx->h[7] += h;
+
+ }
+}
+
+# else
+
+# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \
+ T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \
+ h = Sigma0(a) + Maj(a,b,c); \
+ d += T1; h += T1; } while (0)
+
+# define ROUND_16_63(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)
+
+static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
+ size_t num)
+{
+ unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
+ SHA_LONG X[16];
+ int i;
+ const unsigned char *data = in;
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ while (num--) {
+
+ a = ctx->h[0];
+ b = ctx->h[1];
+ c = ctx->h[2];
+ d = ctx->h[3];
+ e = ctx->h[4];
+ f = ctx->h[5];
+ g = ctx->h[6];
+ h = ctx->h[7];
+
+ if (!is_endian.little && sizeof(SHA_LONG) == 4
+ && ((size_t)in % 4) == 0) {
+ const SHA_LONG *W = (const SHA_LONG *)data;
+
+ T1 = X[0] = W[0];
+ ROUND_00_15(0, a, b, c, d, e, f, g, h);
+ T1 = X[1] = W[1];
+ ROUND_00_15(1, h, a, b, c, d, e, f, g);
+ T1 = X[2] = W[2];
+ ROUND_00_15(2, g, h, a, b, c, d, e, f);
+ T1 = X[3] = W[3];
+ ROUND_00_15(3, f, g, h, a, b, c, d, e);
+ T1 = X[4] = W[4];
+ ROUND_00_15(4, e, f, g, h, a, b, c, d);
+ T1 = X[5] = W[5];
+ ROUND_00_15(5, d, e, f, g, h, a, b, c);
+ T1 = X[6] = W[6];
+ ROUND_00_15(6, c, d, e, f, g, h, a, b);
+ T1 = X[7] = W[7];
+ ROUND_00_15(7, b, c, d, e, f, g, h, a);
+ T1 = X[8] = W[8];
+ ROUND_00_15(8, a, b, c, d, e, f, g, h);
+ T1 = X[9] = W[9];
+ ROUND_00_15(9, h, a, b, c, d, e, f, g);
+ T1 = X[10] = W[10];
+ ROUND_00_15(10, g, h, a, b, c, d, e, f);
+ T1 = X[11] = W[11];
+ ROUND_00_15(11, f, g, h, a, b, c, d, e);
+ T1 = X[12] = W[12];
+ ROUND_00_15(12, e, f, g, h, a, b, c, d);
+ T1 = X[13] = W[13];
+ ROUND_00_15(13, d, e, f, g, h, a, b, c);
+ T1 = X[14] = W[14];
+ ROUND_00_15(14, c, d, e, f, g, h, a, b);
+ T1 = X[15] = W[15];
+ ROUND_00_15(15, b, c, d, e, f, g, h, a);
+
+ data += SHA256_CBLOCK;
+ } else {
+ SHA_LONG l;
+
+ HOST_c2l(data, l);
+ T1 = X[0] = l;
+ ROUND_00_15(0, a, b, c, d, e, f, g, h);
+ HOST_c2l(data, l);
+ T1 = X[1] = l;
+ ROUND_00_15(1, h, a, b, c, d, e, f, g);
+ HOST_c2l(data, l);
+ T1 = X[2] = l;
+ ROUND_00_15(2, g, h, a, b, c, d, e, f);
+ HOST_c2l(data, l);
+ T1 = X[3] = l;
+ ROUND_00_15(3, f, g, h, a, b, c, d, e);
+ HOST_c2l(data, l);
+ T1 = X[4] = l;
+ ROUND_00_15(4, e, f, g, h, a, b, c, d);
+ HOST_c2l(data, l);
+ T1 = X[5] = l;
+ ROUND_00_15(5, d, e, f, g, h, a, b, c);
+ HOST_c2l(data, l);
+ T1 = X[6] = l;
+ ROUND_00_15(6, c, d, e, f, g, h, a, b);
+ HOST_c2l(data, l);
+ T1 = X[7] = l;
+ ROUND_00_15(7, b, c, d, e, f, g, h, a);
+ HOST_c2l(data, l);
+ T1 = X[8] = l;
+ ROUND_00_15(8, a, b, c, d, e, f, g, h);
+ HOST_c2l(data, l);
+ T1 = X[9] = l;
+ ROUND_00_15(9, h, a, b, c, d, e, f, g);
+ HOST_c2l(data, l);
+ T1 = X[10] = l;
+ ROUND_00_15(10, g, h, a, b, c, d, e, f);
+ HOST_c2l(data, l);
+ T1 = X[11] = l;
+ ROUND_00_15(11, f, g, h, a, b, c, d, e);
+ HOST_c2l(data, l);
+ T1 = X[12] = l;
+ ROUND_00_15(12, e, f, g, h, a, b, c, d);
+ HOST_c2l(data, l);
+ T1 = X[13] = l;
+ ROUND_00_15(13, d, e, f, g, h, a, b, c);
+ HOST_c2l(data, l);
+ T1 = X[14] = l;
+ ROUND_00_15(14, c, d, e, f, g, h, a, b);
+ HOST_c2l(data, l);
+ T1 = X[15] = l;
+ ROUND_00_15(15, b, c, d, e, f, g, h, a);
+ }
+
+ for (i = 16; i < 64; i += 8) {
+ ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
+ ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
+ ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
+ ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
+ ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
+ ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
+ ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
+ ROUND_16_63(i + 7, 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;
+ ctx->h[4] += e;
+ ctx->h[5] += f;
+ ctx->h[6] += g;
+ ctx->h[7] += h;
+
+ }
+}
+
+# endif
+# endif /* SHA256_ASM */
+
+#endif /* OPENSSL_NO_SHA256 */
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha512.c b/Cryptlib/OpenSSL/crypto/sha/sha512.c
new file mode 100644
index 00000000..3bf66ae1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha512.c
@@ -0,0 +1,684 @@
+/* crypto/sha/sha512.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved
+ * according to the OpenSSL license [found in ../../LICENSE].
+ * ====================================================================
+ */
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
+/*-
+ * IMPLEMENTATION NOTES.
+ *
+ * As you might have noticed 32-bit hash algorithms:
+ *
+ * - permit SHA_LONG to be wider than 32-bit (case on CRAY);
+ * - optimized versions implement two transform functions: one operating
+ * on [aligned] data in host byte order and one - on data in input
+ * stream byte order;
+ * - share common byte-order neutral collector and padding function
+ * implementations, ../md32_common.h;
+ *
+ * Neither of the above applies to this SHA-512 implementations. Reasons
+ * [in reverse order] are:
+ *
+ * - it's the only 64-bit hash algorithm for the moment of this writing,
+ * there is no need for common collector/padding implementation [yet];
+ * - by supporting only one transform function [which operates on
+ * *aligned* data in input stream byte order, big-endian in this case]
+ * we minimize burden of maintenance in two ways: a) collector/padding
+ * function is simpler; b) only one transform function to stare at;
+ * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
+ * apply a number of optimizations to mitigate potential performance
+ * penalties caused by previous design decision;
+ *
+ * Caveat lector.
+ *
+ * Implementation relies on the fact that "long long" is 64-bit on
+ * both 32- and 64-bit platforms. If some compiler vendor comes up
+ * with 128-bit long long, adjustment to sha.h would be required.
+ * As this implementation relies on 64-bit integer type, it's totally
+ * inappropriate for platforms which don't support it, most notably
+ * 16-bit platforms.
+ * <appro@fy.chalmers.se>
+ */
+# include <stdlib.h>
+# include <string.h>
+
+# include <openssl/crypto.h>
+# include <openssl/sha.h>
+# include <openssl/opensslv.h>
+
+# include "cryptlib.h"
+
+const char SHA512_version[] = "SHA-512" OPENSSL_VERSION_PTEXT;
+
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__s390__) || defined(__s390x__) || \
+ defined(__aarch64__) || \
+ defined(SHA512_ASM)
+# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+# endif
+
+fips_md_init_ctx(SHA384, SHA512)
+{
+ c->h[0] = U64(0xcbbb9d5dc1059ed8);
+ c->h[1] = U64(0x629a292a367cd507);
+ c->h[2] = U64(0x9159015a3070dd17);
+ c->h[3] = U64(0x152fecd8f70e5939);
+ c->h[4] = U64(0x67332667ffc00b31);
+ c->h[5] = U64(0x8eb44a8768581511);
+ c->h[6] = U64(0xdb0c2e0d64f98fa7);
+ c->h[7] = U64(0x47b5481dbefa4fa4);
+
+ c->Nl = 0;
+ c->Nh = 0;
+ c->num = 0;
+ c->md_len = SHA384_DIGEST_LENGTH;
+ return 1;
+}
+
+fips_md_init(SHA512)
+{
+ c->h[0] = U64(0x6a09e667f3bcc908);
+ c->h[1] = U64(0xbb67ae8584caa73b);
+ c->h[2] = U64(0x3c6ef372fe94f82b);
+ c->h[3] = U64(0xa54ff53a5f1d36f1);
+ c->h[4] = U64(0x510e527fade682d1);
+ c->h[5] = U64(0x9b05688c2b3e6c1f);
+ c->h[6] = U64(0x1f83d9abfb41bd6b);
+ c->h[7] = U64(0x5be0cd19137e2179);
+
+ c->Nl = 0;
+ c->Nh = 0;
+ c->num = 0;
+ c->md_len = SHA512_DIGEST_LENGTH;
+ return 1;
+}
+
+# ifndef SHA512_ASM
+static
+# endif
+void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
+
+int SHA512_Final(unsigned char *md, SHA512_CTX *c)
+{
+ unsigned char *p = (unsigned char *)c->u.p;
+ size_t n = c->num;
+
+ p[n] = 0x80; /* There always is a room for one */
+ n++;
+ if (n > (sizeof(c->u) - 16))
+ memset(p + n, 0, sizeof(c->u) - n), n = 0,
+ sha512_block_data_order(c, p, 1);
+
+ memset(p + n, 0, sizeof(c->u) - 16 - n);
+# ifdef B_ENDIAN
+ c->u.d[SHA_LBLOCK - 2] = c->Nh;
+ c->u.d[SHA_LBLOCK - 1] = c->Nl;
+# else
+ p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
+ p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
+ p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
+ p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
+ p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
+ p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
+ p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
+ p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
+ p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
+ p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
+ p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
+ p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
+ p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
+ p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
+ p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
+ p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
+# endif
+
+ sha512_block_data_order(c, p, 1);
+
+ if (md == 0)
+ return 0;
+
+ switch (c->md_len) {
+ /* Let compiler decide if it's appropriate to unroll... */
+ case SHA384_DIGEST_LENGTH:
+ for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
+ SHA_LONG64 t = c->h[n];
+
+ *(md++) = (unsigned char)(t >> 56);
+ *(md++) = (unsigned char)(t >> 48);
+ *(md++) = (unsigned char)(t >> 40);
+ *(md++) = (unsigned char)(t >> 32);
+ *(md++) = (unsigned char)(t >> 24);
+ *(md++) = (unsigned char)(t >> 16);
+ *(md++) = (unsigned char)(t >> 8);
+ *(md++) = (unsigned char)(t);
+ }
+ break;
+ case SHA512_DIGEST_LENGTH:
+ for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
+ SHA_LONG64 t = c->h[n];
+
+ *(md++) = (unsigned char)(t >> 56);
+ *(md++) = (unsigned char)(t >> 48);
+ *(md++) = (unsigned char)(t >> 40);
+ *(md++) = (unsigned char)(t >> 32);
+ *(md++) = (unsigned char)(t >> 24);
+ *(md++) = (unsigned char)(t >> 16);
+ *(md++) = (unsigned char)(t >> 8);
+ *(md++) = (unsigned char)(t);
+ }
+ break;
+ /* ... as well as make sure md_len is not abused. */
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+int SHA384_Final(unsigned char *md, SHA512_CTX *c)
+{
+ return SHA512_Final(md, c);
+}
+
+int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
+{
+ SHA_LONG64 l;
+ unsigned char *p = c->u.p;
+ const unsigned char *data = (const unsigned char *)_data;
+
+ if (len == 0)
+ return 1;
+
+ l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff);
+ if (l < c->Nl)
+ c->Nh++;
+ if (sizeof(len) >= 8)
+ c->Nh += (((SHA_LONG64) len) >> 61);
+ c->Nl = l;
+
+ if (c->num != 0) {
+ size_t n = sizeof(c->u) - c->num;
+
+ if (len < n) {
+ memcpy(p + c->num, data, len), c->num += (unsigned int)len;
+ return 1;
+ } else {
+ memcpy(p + c->num, data, n), c->num = 0;
+ len -= n, data += n;
+ sha512_block_data_order(c, p, 1);
+ }
+ }
+
+ if (len >= sizeof(c->u)) {
+# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+ if ((size_t)data % sizeof(c->u.d[0]) != 0)
+ while (len >= sizeof(c->u))
+ memcpy(p, data, sizeof(c->u)),
+ sha512_block_data_order(c, p, 1),
+ len -= sizeof(c->u), data += sizeof(c->u);
+ else
+# endif
+ sha512_block_data_order(c, data, len / sizeof(c->u)),
+ data += len, len %= sizeof(c->u), data -= len;
+ }
+
+ if (len != 0)
+ memcpy(p, data, len), c->num = (int)len;
+
+ return 1;
+}
+
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
+{
+ return SHA512_Update(c, data, len);
+}
+
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
+{
+# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+ if ((size_t)data % sizeof(c->u.d[0]) != 0)
+ memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p;
+# endif
+ sha512_block_data_order(c, data, 1);
+}
+
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
+{
+ SHA512_CTX c;
+ static unsigned char m[SHA384_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ SHA384_Init(&c);
+ SHA512_Update(&c, d, n);
+ SHA512_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c));
+ return (md);
+}
+
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
+{
+ SHA512_CTX c;
+ static unsigned char m[SHA512_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ SHA512_Init(&c);
+ SHA512_Update(&c, d, n);
+ SHA512_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c));
+ return (md);
+}
+
+# ifndef SHA512_ASM
+static const SHA_LONG64 K512[80] = {
+ U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
+ U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
+ U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
+ U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
+ U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
+ U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
+ U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
+ U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
+ U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
+ U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
+ U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
+ U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
+ U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
+ U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
+ U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
+ U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
+ U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
+ U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
+ U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
+ U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
+ U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
+ U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
+ U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
+ U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
+ U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
+ U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
+ U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
+ U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
+ U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
+ U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
+ U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
+ U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
+ U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
+ U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
+ U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
+ U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
+ U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
+ U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
+ U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
+ U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
+};
+
+# 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) ({ SHA_LONG64 ret; \
+ asm ("rorq %1,%0" \
+ : "=r"(ret) \
+ : "J"(n),"0"(a) \
+ : "cc"); ret; })
+# if !defined(B_ENDIAN)
+# define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \
+ asm ("bswapq %0" \
+ : "=r"(ret) \
+ : "0"(ret)); ret; })
+# endif
+# elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
+# if defined(I386_ONLY)
+# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+ unsigned int hi=p[0],lo=p[1]; \
+ asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
+ "roll $16,%%eax; roll $16,%%edx; "\
+ "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \
+ : "=a"(lo),"=d"(hi) \
+ : "0"(lo),"1"(hi) : "cc"); \
+ ((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]; \
+ 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) ({ SHA_LONG64 ret; \
+ asm ("rotrdi %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a),"K"(n)); ret; })
+# elif defined(__aarch64__)
+# define ROTR(a,n) ({ SHA_LONG64 ret; \
+ asm ("ror %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a),"I"(n)); ret; })
+# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
+ __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
+# define PULL64(x) ({ SHA_LONG64 ret; \
+ asm ("rev %0,%1" \
+ : "=r"(ret) \
+ : "r"(*((const SHA_LONG64 *)(&(x))))); ret; })
+# endif
+# 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)
+# if defined(I386_ONLY)
+static SHA_LONG64 __fastcall __pull64be(const void *x)
+{
+ _asm mov edx,[ecx + 0]
+ _asm mov eax,[ecx + 4]
+_asm xchg dh, dl
+ _asm xchg ah, al
+ _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al}
+# else
+static SHA_LONG64 __fastcall __pull64be(const void *x)
+{
+ _asm mov edx,[ecx + 0]
+ _asm mov eax,[ecx + 4]
+_asm bswap edx _asm bswap eax}
+# endif
+# define PULL64(x) __pull64be(&(x))
+# if _MSC_VER<=1200
+# pragma inline_depth(0)
+# endif
+# endif
+# endif
+# endif
+# ifndef PULL64
+# define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
+# define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
+# endif
+# ifndef ROTR
+# define ROTR(x,s) (((x)>>s) | (x)<<(64-s))
+# endif
+# define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
+# define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
+# define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
+# define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+# 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]);
+ }
+
+ 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)
+{
+ const SHA_LONG64 *W = in;
+ SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2;
+ SHA_LONG64 X[16];
+ int i;
+
+ while (num--) {
+
+ a = ctx->h[0];
+ b = ctx->h[1];
+ c = ctx->h[2];
+ d = ctx->h[3];
+ e = ctx->h[4];
+ f = ctx->h[5];
+ g = ctx->h[6];
+ h = ctx->h[7];
+
+ for (i = 0; i < 16; i++) {
+# ifdef B_ENDIAN
+ T1 = X[i] = W[i];
+# else
+ T1 = X[i] = PULL64(W[i]);
+# endif
+ T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
+ T2 = Sigma0(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+ }
+
+ for (; i < 80; i++) {
+ s0 = X[(i + 1) & 0x0f];
+ s0 = sigma0(s0);
+ s1 = X[(i + 14) & 0x0f];
+ s1 = sigma1(s1);
+
+ T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
+ T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
+ T2 = Sigma0(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+ }
+
+ ctx->h[0] += a;
+ ctx->h[1] += b;
+ ctx->h[2] += c;
+ ctx->h[3] += d;
+ ctx->h[4] += e;
+ ctx->h[5] += f;
+ ctx->h[6] += g;
+ ctx->h[7] += h;
+
+ W += SHA_LBLOCK;
+ }
+}
+
+# else
+# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \
+ T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \
+ h = Sigma0(a) + Maj(a,b,c); \
+ d += T1; h += T1; } 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)
+{
+ const SHA_LONG64 *W = in;
+ SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1;
+ SHA_LONG64 X[16];
+ int i;
+
+ while (num--) {
+
+ a = ctx->h[0];
+ b = ctx->h[1];
+ c = ctx->h[2];
+ d = ctx->h[3];
+ e = ctx->h[4];
+ f = ctx->h[5];
+ g = ctx->h[6];
+ h = ctx->h[7];
+
+# ifdef B_ENDIAN
+ T1 = X[0] = W[0];
+ ROUND_00_15(0, a, b, c, d, e, f, g, h);
+ T1 = X[1] = W[1];
+ ROUND_00_15(1, h, a, b, c, d, e, f, g);
+ T1 = X[2] = W[2];
+ ROUND_00_15(2, g, h, a, b, c, d, e, f);
+ T1 = X[3] = W[3];
+ ROUND_00_15(3, f, g, h, a, b, c, d, e);
+ T1 = X[4] = W[4];
+ ROUND_00_15(4, e, f, g, h, a, b, c, d);
+ T1 = X[5] = W[5];
+ ROUND_00_15(5, d, e, f, g, h, a, b, c);
+ T1 = X[6] = W[6];
+ ROUND_00_15(6, c, d, e, f, g, h, a, b);
+ T1 = X[7] = W[7];
+ ROUND_00_15(7, b, c, d, e, f, g, h, a);
+ T1 = X[8] = W[8];
+ ROUND_00_15(8, a, b, c, d, e, f, g, h);
+ T1 = X[9] = W[9];
+ ROUND_00_15(9, h, a, b, c, d, e, f, g);
+ T1 = X[10] = W[10];
+ ROUND_00_15(10, g, h, a, b, c, d, e, f);
+ T1 = X[11] = W[11];
+ ROUND_00_15(11, f, g, h, a, b, c, d, e);
+ T1 = X[12] = W[12];
+ ROUND_00_15(12, e, f, g, h, a, b, c, d);
+ T1 = X[13] = W[13];
+ ROUND_00_15(13, d, e, f, g, h, a, b, c);
+ T1 = X[14] = W[14];
+ ROUND_00_15(14, c, d, e, f, g, h, a, b);
+ T1 = X[15] = W[15];
+ ROUND_00_15(15, b, c, d, e, f, g, h, a);
+# else
+ T1 = X[0] = PULL64(W[0]);
+ ROUND_00_15(0, a, b, c, d, e, f, g, h);
+ T1 = X[1] = PULL64(W[1]);
+ ROUND_00_15(1, h, a, b, c, d, e, f, g);
+ T1 = X[2] = PULL64(W[2]);
+ ROUND_00_15(2, g, h, a, b, c, d, e, f);
+ T1 = X[3] = PULL64(W[3]);
+ ROUND_00_15(3, f, g, h, a, b, c, d, e);
+ T1 = X[4] = PULL64(W[4]);
+ ROUND_00_15(4, e, f, g, h, a, b, c, d);
+ T1 = X[5] = PULL64(W[5]);
+ ROUND_00_15(5, d, e, f, g, h, a, b, c);
+ T1 = X[6] = PULL64(W[6]);
+ ROUND_00_15(6, c, d, e, f, g, h, a, b);
+ T1 = X[7] = PULL64(W[7]);
+ ROUND_00_15(7, b, c, d, e, f, g, h, a);
+ T1 = X[8] = PULL64(W[8]);
+ ROUND_00_15(8, a, b, c, d, e, f, g, h);
+ T1 = X[9] = PULL64(W[9]);
+ ROUND_00_15(9, h, a, b, c, d, e, f, g);
+ T1 = X[10] = PULL64(W[10]);
+ ROUND_00_15(10, g, h, a, b, c, d, e, f);
+ T1 = X[11] = PULL64(W[11]);
+ ROUND_00_15(11, f, g, h, a, b, c, d, e);
+ T1 = X[12] = PULL64(W[12]);
+ ROUND_00_15(12, e, f, g, h, a, b, c, d);
+ T1 = X[13] = PULL64(W[13]);
+ ROUND_00_15(13, d, e, f, g, h, a, b, c);
+ T1 = X[14] = PULL64(W[14]);
+ ROUND_00_15(14, c, d, e, f, g, h, a, b);
+ 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 += 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, 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;
+ ctx->h[4] += e;
+ ctx->h[5] += f;
+ ctx->h[6] += g;
+ ctx->h[7] += h;
+
+ W += SHA_LBLOCK;
+ }
+}
+
+# endif
+
+# endif /* SHA512_ASM */
+
+#else /* !OPENSSL_NO_SHA512 */
+
+# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
+static void *dummy = &dummy;
+# endif
+
+#endif /* !OPENSSL_NO_SHA512 */
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha_dgst.c b/Cryptlib/OpenSSL/crypto/sha/sha_dgst.c
new file mode 100644
index 00000000..f77cf5e3
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha_dgst.c
@@ -0,0 +1,74 @@
+/* crypto/sha/sha1dgst.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 <openssl/crypto.h>
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
+
+# undef SHA_1
+# define SHA_0
+
+# include <openssl/opensslv.h>
+
+const char SHA_version[] = "SHA" OPENSSL_VERSION_PTEXT;
+
+/* The implementation is in ../md32_common.h */
+
+# include "sha_locl.h"
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha_locl.h b/Cryptlib/OpenSSL/crypto/sha/sha_locl.h
new file mode 100644
index 00000000..03bd411e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha_locl.h
@@ -0,0 +1,500 @@
+/* crypto/sha/sha_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 <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG SHA_LONG
+#define HASH_CTX SHA_CTX
+#define HASH_CBLOCK SHA_CBLOCK
+#define HASH_MAKE_STRING(c,s) do { \
+ unsigned long ll; \
+ ll=(c)->h0; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h1; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h2; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h3; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h4; (void)HOST_l2c(ll,(s)); \
+ } while (0)
+
+#if defined(SHA_0)
+
+# define HASH_UPDATE SHA_Update
+# define HASH_TRANSFORM SHA_Transform
+# define HASH_FINAL SHA_Final
+# define HASH_INIT SHA_Init
+# define HASH_BLOCK_DATA_ORDER sha_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id))
+
+static void sha_block_data_order(SHA_CTX *c, const void *p, size_t num);
+
+#elif defined(SHA_1)
+
+# define HASH_UPDATE SHA1_Update
+# define HASH_TRANSFORM SHA1_Transform
+# define HASH_FINAL SHA1_Final
+# define HASH_INIT SHA1_Init
+# define HASH_BLOCK_DATA_ORDER sha1_block_data_order
+# if defined(__MWERKS__) && defined(__MC68K__)
+ /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
+# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \
+ ix=(a)=ROTATE((a),1); \
+ } while (0)
+# else
+# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \
+ ix=(a)=ROTATE((a),1) \
+ )
+# endif
+
+# ifndef SHA1_ASM
+static
+# endif
+void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
+
+#else
+# error "Either SHA_0 or SHA_1 must be defined."
+#endif
+
+#include "md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+#ifdef SHA_0
+fips_md_init(SHA)
+#else
+fips_md_init_ctx(SHA1, SHA)
+#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;
+ return 1;
+}
+
+#define K_00_19 0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be simplified
+ * to the code in F_00_19. Wei attributes these optimisations to Peter
+ * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define
+ * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another
+ * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
+#define F_60_79(b,c,d) F_20_39(b,c,d)
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+
+# define BODY_00_15(i,a,b,c,d,e,f,xi) \
+ (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+ Xupdate(f,xi,xa,xb,xc,xd); \
+ (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+ Xupdate(f,xi,xa,xb,xc,xd); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,xa,xa,xb,xc,xd); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,xa,xa,xb,xc,xd); \
+ (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,xa,xa,xb,xc,xd); \
+ (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# ifdef X
+# undef X
+# endif
+# ifndef MD32_XARRAY
+ /*
+ * Originally X was an array. As it's automatic it's natural
+ * to expect RISC compiler to accomodate at least part of it in
+ * the register bank, isn't it? Unfortunately not all compilers
+ * "find" this expectation reasonable:-( On order to make such
+ * compilers generate better code I replace X[] with a bunch of
+ * X0, X1, etc. See the function body below...
+ * <appro@fy.chalmers.se>
+ */
+# define X(i) XX##i
+# else
+ /*
+ * However! Some compilers (most notably HP C) get overwhelmed by
+ * that many local variables so that we have to have the way to
+ * fall down to the original behavior.
+ */
+# define X(i) XX[i]
+# endif
+
+# if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
+{
+ const unsigned char *data = p;
+ register unsigned MD32_REG_T A, B, C, D, E, T, l;
+# ifndef MD32_XARRAY
+ unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+ XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+# else
+ SHA_LONG XX[16];
+# endif
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ for (;;) {
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ if (!is_endian.little && sizeof(SHA_LONG) == 4
+ && ((size_t)p % 4) == 0) {
+ const SHA_LONG *W = (const SHA_LONG *)data;
+
+ X(0) = W[0];
+ X(1) = W[1];
+ BODY_00_15(0, A, B, C, D, E, T, X(0));
+ X(2) = W[2];
+ BODY_00_15(1, T, A, B, C, D, E, X(1));
+ X(3) = W[3];
+ BODY_00_15(2, E, T, A, B, C, D, X(2));
+ X(4) = W[4];
+ BODY_00_15(3, D, E, T, A, B, C, X(3));
+ X(5) = W[5];
+ BODY_00_15(4, C, D, E, T, A, B, X(4));
+ X(6) = W[6];
+ BODY_00_15(5, B, C, D, E, T, A, X(5));
+ X(7) = W[7];
+ BODY_00_15(6, A, B, C, D, E, T, X(6));
+ X(8) = W[8];
+ BODY_00_15(7, T, A, B, C, D, E, X(7));
+ X(9) = W[9];
+ BODY_00_15(8, E, T, A, B, C, D, X(8));
+ X(10) = W[10];
+ BODY_00_15(9, D, E, T, A, B, C, X(9));
+ X(11) = W[11];
+ BODY_00_15(10, C, D, E, T, A, B, X(10));
+ X(12) = W[12];
+ BODY_00_15(11, B, C, D, E, T, A, X(11));
+ X(13) = W[13];
+ BODY_00_15(12, A, B, C, D, E, T, X(12));
+ X(14) = W[14];
+ BODY_00_15(13, T, A, B, C, D, E, X(13));
+ X(15) = W[15];
+ BODY_00_15(14, E, T, A, B, C, D, X(14));
+ BODY_00_15(15, D, E, T, A, B, C, X(15));
+
+ data += SHA_CBLOCK;
+ } else {
+ (void)HOST_c2l(data, l);
+ X(0) = l;
+ (void)HOST_c2l(data, l);
+ X(1) = l;
+ BODY_00_15(0, A, B, C, D, E, T, X(0));
+ (void)HOST_c2l(data, l);
+ X(2) = l;
+ BODY_00_15(1, T, A, B, C, D, E, X(1));
+ (void)HOST_c2l(data, l);
+ X(3) = l;
+ BODY_00_15(2, E, T, A, B, C, D, X(2));
+ (void)HOST_c2l(data, l);
+ X(4) = l;
+ BODY_00_15(3, D, E, T, A, B, C, X(3));
+ (void)HOST_c2l(data, l);
+ X(5) = l;
+ BODY_00_15(4, C, D, E, T, A, B, X(4));
+ (void)HOST_c2l(data, l);
+ X(6) = l;
+ BODY_00_15(5, B, C, D, E, T, A, X(5));
+ (void)HOST_c2l(data, l);
+ X(7) = l;
+ BODY_00_15(6, A, B, C, D, E, T, X(6));
+ (void)HOST_c2l(data, l);
+ X(8) = l;
+ BODY_00_15(7, T, A, B, C, D, E, X(7));
+ (void)HOST_c2l(data, l);
+ X(9) = l;
+ BODY_00_15(8, E, T, A, B, C, D, X(8));
+ (void)HOST_c2l(data, l);
+ X(10) = l;
+ BODY_00_15(9, D, E, T, A, B, C, X(9));
+ (void)HOST_c2l(data, l);
+ X(11) = l;
+ BODY_00_15(10, C, D, E, T, A, B, X(10));
+ (void)HOST_c2l(data, l);
+ X(12) = l;
+ BODY_00_15(11, B, C, D, E, T, A, X(11));
+ (void)HOST_c2l(data, l);
+ X(13) = l;
+ BODY_00_15(12, A, B, C, D, E, T, X(12));
+ (void)HOST_c2l(data, l);
+ X(14) = l;
+ BODY_00_15(13, T, A, B, C, D, E, X(13));
+ (void)HOST_c2l(data, l);
+ X(15) = l;
+ BODY_00_15(14, E, T, A, B, C, D, X(14));
+ BODY_00_15(15, D, E, T, A, B, C, X(15));
+ }
+
+ BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13));
+ BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14));
+ BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15));
+ BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0));
+
+ BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1));
+ BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2));
+ BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3));
+ BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4));
+ BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5));
+ BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6));
+ BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7));
+ BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8));
+ BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9));
+ BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10));
+ BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11));
+ BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12));
+
+ BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13));
+ BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14));
+ BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15));
+ BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0));
+ BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1));
+ BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2));
+ BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3));
+ BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4));
+
+ BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5));
+ BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6));
+ BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7));
+ BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8));
+ BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9));
+ BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10));
+ BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11));
+ BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12));
+ BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13));
+ BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14));
+ BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15));
+ BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0));
+ BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1));
+ BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2));
+ BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3));
+ BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4));
+ BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5));
+ BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6));
+ BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7));
+ BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8));
+
+ BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9));
+ BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10));
+ BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11));
+ BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12));
+ BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13));
+ BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14));
+ BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15));
+ BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0));
+ BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1));
+ BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2));
+ BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3));
+ BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4));
+ BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5));
+ BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6));
+ BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7));
+ BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8));
+ BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9));
+ BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10));
+ BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11));
+ BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12));
+
+ c->h0 = (c->h0 + E) & 0xffffffffL;
+ c->h1 = (c->h1 + T) & 0xffffffffL;
+ c->h2 = (c->h2 + A) & 0xffffffffL;
+ c->h3 = (c->h3 + B) & 0xffffffffL;
+ c->h4 = (c->h4 + C) & 0xffffffffL;
+
+ if (--num == 0)
+ break;
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ }
+}
+# endif
+
+#else /* OPENSSL_SMALL_FOOTPRINT */
+
+# define BODY_00_15(xi) do { \
+ T=E+K_00_19+F_00_19(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T+xi; } while(0)
+
+# define BODY_16_19(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T+=E+K_00_19+F_00_19(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T; } while(0)
+
+# define BODY_20_39(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T+=E+K_20_39+F_20_39(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T; } while(0)
+
+# define BODY_40_59(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T+=E+K_40_59+F_40_59(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T; } while(0)
+
+# define BODY_60_79(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T=E+K_60_79+F_60_79(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T+xa; } while(0)
+
+# if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
+{
+ const unsigned char *data = p;
+ register unsigned MD32_REG_T A, B, C, D, E, T, l;
+ int i;
+ SHA_LONG X[16];
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ for (;;) {
+ for (i = 0; i < 16; i++) {
+ HOST_c2l(data, l);
+ X[i] = l;
+ BODY_00_15(X[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]);
+ }
+ for (; i < 24; i++) {
+ BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15],
+ X[(i + 13) & 15]);
+ }
+ for (i = 0; i < 20; i++) {
+ BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
+ X[(i + 5) & 15]);
+ }
+ for (i = 4; i < 24; i++) {
+ BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
+ X[(i + 5) & 15]);
+ }
+
+ c->h0 = (c->h0 + A) & 0xffffffffL;
+ c->h1 = (c->h1 + B) & 0xffffffffL;
+ c->h2 = (c->h2 + C) & 0xffffffffL;
+ c->h3 = (c->h3 + D) & 0xffffffffL;
+ c->h4 = (c->h4 + E) & 0xffffffffL;
+
+ if (--num == 0)
+ break;
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ }
+}
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/sha/sha_one.c b/Cryptlib/OpenSSL/crypto/sha/sha_one.c
new file mode 100644
index 00000000..0930b98a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/sha/sha_one.c
@@ -0,0 +1,79 @@
+/* crypto/sha/sha_one.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 <stdio.h>
+#include <string.h>
+#include <openssl/sha.h>
+#include <openssl/crypto.h>
+
+#ifndef OPENSSL_NO_SHA0
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md)
+{
+ SHA_CTX c;
+ static unsigned char m[SHA_DIGEST_LENGTH];
+
+ if (md == NULL)
+ md = m;
+ if (!SHA_Init(&c))
+ return NULL;
+ SHA_Update(&c, d, n);
+ SHA_Final(md, &c);
+ OPENSSL_cleanse(&c, sizeof(c));
+ return (md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/stack/stack.c b/Cryptlib/OpenSSL/crypto/stack/stack.c
new file mode 100644
index 00000000..fa50083e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/stack/stack.c
@@ -0,0 +1,384 @@
+/* crypto/stack/stack.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.]
+ */
+
+/*-
+ * Code for stacks
+ * Author - Eric Young v 1.0
+ * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the
+ * lowest index for the searched item.
+ *
+ * 1.1 eay - Take from netdb and added to SSLeay
+ *
+ * 1.0 eay - First version 29/07/92
+ */
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+#include <openssl/objects.h>
+
+#undef MIN_NODES
+#define MIN_NODES 4
+
+const char STACK_version[] = "Stack" OPENSSL_VERSION_PTEXT;
+
+#include <errno.h>
+
+int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
+ (const void *, const void *) {
+ int (*old) (const void *, const void *) = sk->comp;
+
+ if (sk->comp != c)
+ sk->sorted = 0;
+ sk->comp = c;
+
+ return old;
+}
+
+_STACK *sk_dup(_STACK *sk)
+{
+ _STACK *ret;
+ char **s;
+
+ if ((ret = sk_new(sk->comp)) == NULL)
+ goto err;
+ s = (char **)OPENSSL_realloc((char *)ret->data,
+ (unsigned int)sizeof(char *) *
+ sk->num_alloc);
+ if (s == NULL)
+ goto err;
+ ret->data = s;
+
+ ret->num = sk->num;
+ memcpy(ret->data, sk->data, sizeof(char *) * sk->num);
+ ret->sorted = sk->sorted;
+ ret->num_alloc = sk->num_alloc;
+ ret->comp = sk->comp;
+ return (ret);
+ err:
+ if (ret)
+ sk_free(ret);
+ return (NULL);
+}
+
+_STACK *sk_deep_copy(_STACK *sk, void *(*copy_func) (void *),
+ void (*free_func) (void *))
+{
+ _STACK *ret;
+ int i;
+
+ if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL)
+ return ret;
+ ret->comp = sk->comp;
+ ret->sorted = sk->sorted;
+ ret->num = sk->num;
+ ret->num_alloc = sk->num > MIN_NODES ? sk->num : MIN_NODES;
+ ret->data = OPENSSL_malloc(sizeof(char *) * ret->num_alloc);
+ if (ret->data == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ for (i = 0; i < ret->num_alloc; i++)
+ ret->data[i] = NULL;
+
+ for (i = 0; i < ret->num; ++i) {
+ if (sk->data[i] == NULL)
+ continue;
+ if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
+ while (--i >= 0)
+ if (ret->data[i] != NULL)
+ free_func(ret->data[i]);
+ sk_free(ret);
+ return NULL;
+ }
+ }
+ return ret;
+}
+
+_STACK *sk_new_null(void)
+{
+ return sk_new((int (*)(const void *, const void *))0);
+}
+
+_STACK *sk_new(int (*c) (const void *, const void *))
+{
+ _STACK *ret;
+ int i;
+
+ if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL)
+ goto err;
+ if ((ret->data = OPENSSL_malloc(sizeof(char *) * MIN_NODES)) == NULL)
+ goto err;
+ for (i = 0; i < MIN_NODES; i++)
+ ret->data[i] = NULL;
+ ret->comp = c;
+ ret->num_alloc = MIN_NODES;
+ ret->num = 0;
+ ret->sorted = 0;
+ return (ret);
+ err:
+ if (ret)
+ OPENSSL_free(ret);
+ return (NULL);
+}
+
+int sk_insert(_STACK *st, void *data, int loc)
+{
+ char **s;
+
+ if (st == NULL)
+ return 0;
+ if (st->num_alloc <= st->num + 1) {
+ s = OPENSSL_realloc((char *)st->data,
+ (unsigned int)sizeof(char *) * st->num_alloc * 2);
+ if (s == NULL)
+ return (0);
+ st->data = s;
+ st->num_alloc *= 2;
+ }
+ if ((loc >= (int)st->num) || (loc < 0))
+ st->data[st->num] = data;
+ else {
+ int i;
+ char **f, **t;
+
+ 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(&(st->data[loc + 1]),
+ &(st->data[loc]), sizeof(char *) * (st->num - loc));
+#endif
+ st->data[loc] = data;
+ }
+ st->num++;
+ st->sorted = 0;
+ return (st->num);
+}
+
+void *sk_delete_ptr(_STACK *st, void *p)
+{
+ int i;
+
+ for (i = 0; i < st->num; i++)
+ if (st->data[i] == p)
+ return (sk_delete(st, i));
+ return (NULL);
+}
+
+void *sk_delete(_STACK *st, int loc)
+{
+ char *ret;
+ int i, j;
+
+ if (!st || (loc < 0) || (loc >= st->num))
+ return NULL;
+
+ ret = st->data[loc];
+ if (loc != st->num - 1) {
+ j = st->num - 1;
+ for (i = loc; i < j; i++)
+ st->data[i] = st->data[i + 1];
+ /*
+ * In theory memcpy is not safe for this memcpy( &(st->data[loc]),
+ * &(st->data[loc+1]), sizeof(char *)*(st->num-loc-1));
+ */
+ }
+ st->num--;
+ return (ret);
+}
+
+static int internal_find(_STACK *st, void *data, int ret_val_options)
+{
+ const void *const *r;
+ int i;
+
+ if (st == NULL)
+ return -1;
+
+ if (st->comp == NULL) {
+ for (i = 0; i < st->num; i++)
+ if (st->data[i] == data)
+ return (i);
+ return (-1);
+ }
+ sk_sort(st);
+ if (data == NULL)
+ return (-1);
+ r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
+ ret_val_options);
+ if (r == NULL)
+ return (-1);
+ return (int)((char **)r - st->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, void *data)
+{
+ return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+}
+
+int sk_push(_STACK *st, void *data)
+{
+ return (sk_insert(st, data, st->num));
+}
+
+int sk_unshift(_STACK *st, void *data)
+{
+ return (sk_insert(st, data, 0));
+}
+
+void *sk_shift(_STACK *st)
+{
+ if (st == NULL)
+ return (NULL);
+ if (st->num <= 0)
+ return (NULL);
+ return (sk_delete(st, 0));
+}
+
+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)
+{
+ if (st == NULL)
+ return;
+ if (st->num <= 0)
+ return;
+ memset((char *)st->data, 0, sizeof(*st->data) * st->num);
+ st->num = 0;
+}
+
+void sk_pop_free(_STACK *st, void (*func) (void *))
+{
+ int i;
+
+ if (st == NULL)
+ return;
+ for (i = 0; i < st->num; i++)
+ if (st->data[i] != NULL)
+ func(st->data[i]);
+ sk_free(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)
+{
+ if (st == NULL)
+ return -1;
+ return st->num;
+}
+
+void *sk_value(const _STACK *st, int i)
+{
+ if (!st || (i < 0) || (i >= st->num))
+ return NULL;
+ return st->data[i];
+}
+
+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)
+{
+ if (st && !st->sorted && st->comp != NULL) {
+ int (*comp_func) (const void *, const void *);
+
+ /*
+ * same comment as in sk_find ... previously st->comp was declared as
+ * a (void*,void*) callback type, but this made the population of the
+ * callback pointer illogical - our callbacks compare type** with
+ * type**, so we leave the casting until absolutely necessary (ie.
+ * "now").
+ */
+ comp_func = (int (*)(const void *, const void *))(st->comp);
+ qsort(st->data, st->num, sizeof(char *), comp_func);
+ st->sorted = 1;
+ }
+}
+
+int sk_is_sorted(const _STACK *st)
+{
+ if (!st)
+ return 1;
+ return st->sorted;
+}
diff --git a/Cryptlib/OpenSSL/crypto/txt_db/txt_db.c b/Cryptlib/OpenSSL/crypto/txt_db/txt_db.c
new file mode 100644
index 00000000..f9b42ac6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/txt_db/txt_db.c
@@ -0,0 +1,381 @@
+/* crypto/txt_db/txt_db.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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/txt_db.h>
+
+#undef BUFSIZE
+#define BUFSIZE 512
+
+const char TXT_DB_version[] = "TXT_DB" OPENSSL_VERSION_PTEXT;
+
+TXT_DB *TXT_DB_read(BIO *in, int num)
+{
+ TXT_DB *ret = NULL;
+ int er = 1;
+ int esc = 0;
+ long ln = 0;
+ int i, add, n;
+ int size = BUFSIZE;
+ int offset = 0;
+ 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 = OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
+ goto err;
+ ret->num_fields = num;
+ ret->index = NULL;
+ ret->qual = NULL;
+ if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL)
+ goto err;
+ if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL)
+ goto err;
+ if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL)
+ goto err;
+ for (i = 0; i < num; i++) {
+ ret->index[i] = NULL;
+ ret->qual[i] = NULL;
+ }
+
+ add = (num + 1) * sizeof(char *);
+ buf->data[size - 1] = '\0';
+ offset = 0;
+ for (;;) {
+ if (offset != 0) {
+ size += BUFSIZE;
+ if (!BUF_MEM_grow_clean(buf, size))
+ goto err;
+ }
+ buf->data[offset] = '\0';
+ BIO_gets(in, &(buf->data[offset]), size - offset);
+ ln++;
+ if (buf->data[offset] == '\0')
+ break;
+ if ((offset == 0) && (buf->data[0] == '#'))
+ continue;
+ i = strlen(&(buf->data[offset]));
+ offset += i;
+ if (buf->data[offset - 1] != '\n')
+ continue;
+ else {
+ buf->data[offset - 1] = '\0'; /* blat the '\n' */
+ if (!(p = OPENSSL_malloc(add + offset)))
+ goto err;
+ offset = 0;
+ }
+ pp = (char **)p;
+ p += add;
+ n = 0;
+ pp[n++] = p;
+ i = 0;
+ f = buf->data;
+
+ esc = 0;
+ for (;;) {
+ if (*f == '\0')
+ break;
+ if (*f == '\t') {
+ if (esc)
+ p--;
+ else {
+ *(p++) = '\0';
+ f++;
+ if (n >= num)
+ break;
+ pp[n++] = p;
+ continue;
+ }
+ }
+ esc = (*f == '\\');
+ *(p++) = *(f++);
+ }
+ *(p++) = '\0';
+ if ((n != num) || (*f != '\0')) {
+#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_OPENSSL_PSTRING_push(ret->data, pp)) {
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary
+ * fix :-( */
+ fprintf(stderr, "failure in sk_push\n");
+#endif
+ er = 2;
+ goto err;
+ }
+ }
+ er = 0;
+ err:
+ BUF_MEM_free(buf);
+ if (er) {
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+ if (er == 1)
+ fprintf(stderr, "OPENSSL_malloc failure\n");
+#endif
+ if (ret != NULL) {
+ 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);
+ }
+ return (NULL);
+ } else
+ return (ret);
+}
+
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
+ OPENSSL_STRING *value)
+{
+ OPENSSL_STRING *ret;
+ LHASH_OF(OPENSSL_STRING) *lh;
+
+ if (idx >= db->num_fields) {
+ db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
+ return (NULL);
+ }
+ lh = db->index[idx];
+ if (lh == NULL) {
+ db->error = DB_ERROR_NO_INDEX;
+ return (NULL);
+ }
+ 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) (OPENSSL_STRING *),
+ LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
+{
+ LHASH_OF(OPENSSL_STRING) *idx;
+ OPENSSL_STRING *r;
+ int i, n;
+
+ if (field >= db->num_fields) {
+ db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
+ return (0);
+ }
+ /* 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_OPENSSL_PSTRING_num(db->data);
+ for (i = 0; i < n; i++) {
+ r = sk_OPENSSL_PSTRING_value(db->data, i);
+ if ((qual != NULL) && (qual(r) == 0))
+ continue;
+ if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
+ db->error = DB_ERROR_INDEX_CLASH;
+ db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r);
+ db->arg2 = i;
+ lh_OPENSSL_STRING_free(idx);
+ return (0);
+ }
+ }
+ if (db->index[field] != NULL)
+ lh_OPENSSL_STRING_free(db->index[field]);
+ db->index[field] = idx;
+ db->qual[field] = qual;
+ return (1);
+}
+
+long TXT_DB_write(BIO *out, TXT_DB *db)
+{
+ long i, j, n, nn, l, tot = 0;
+ char *p, **pp, *f;
+ BUF_MEM *buf = NULL;
+ long ret = -1;
+
+ if ((buf = BUF_MEM_new()) == NULL)
+ goto err;
+ n = sk_OPENSSL_PSTRING_num(db->data);
+ nn = db->num_fields;
+ for (i = 0; i < n; i++) {
+ pp = sk_OPENSSL_PSTRING_value(db->data, i);
+
+ l = 0;
+ for (j = 0; j < nn; j++) {
+ if (pp[j] != NULL)
+ l += strlen(pp[j]);
+ }
+ if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn)))
+ goto err;
+
+ p = buf->data;
+ for (j = 0; j < nn; j++) {
+ f = pp[j];
+ if (f != NULL)
+ for (;;) {
+ if (*f == '\0')
+ break;
+ if (*f == '\t')
+ *(p++) = '\\';
+ *(p++) = *(f++);
+ }
+ *(p++) = '\t';
+ }
+ p[-1] = '\n';
+ j = p - buf->data;
+ if (BIO_write(out, buf->data, (int)j) != j)
+ goto err;
+ tot += j;
+ }
+ ret = tot;
+ err:
+ if (buf != NULL)
+ BUF_MEM_free(buf);
+ return (ret);
+}
+
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
+{
+ int i;
+ OPENSSL_STRING *r;
+
+ for (i = 0; i < db->num_fields; i++) {
+ if (db->index[i] != NULL) {
+ if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
+ continue;
+ r = lh_OPENSSL_STRING_retrieve(db->index[i], row);
+ if (r != NULL) {
+ db->error = DB_ERROR_INDEX_CLASH;
+ db->arg1 = i;
+ db->arg_row = r;
+ goto err;
+ }
+ }
+ }
+ /* We have passed the index checks, now just append and insert */
+ if (!sk_OPENSSL_PSTRING_push(db->data, row)) {
+ db->error = DB_ERROR_MALLOC;
+ goto err;
+ }
+
+ for (i = 0; i < db->num_fields; i++) {
+ if (db->index[i] != NULL) {
+ if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
+ continue;
+ (void)lh_OPENSSL_STRING_insert(db->index[i], row);
+ }
+ }
+ return (1);
+ err:
+ return (0);
+}
+
+void TXT_DB_free(TXT_DB *db)
+{
+ int i, n;
+ char **p, *max;
+
+ if (db == NULL)
+ return;
+
+ if (db->index != NULL) {
+ for (i = db->num_fields - 1; i >= 0; 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_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) {
+ /*
+ * check if any 'fields' have been allocated from outside of the
+ * initial block
+ */
+ p = sk_OPENSSL_PSTRING_value(db->data, i);
+ max = p[db->num_fields]; /* last address */
+ if (max == NULL) { /* new row */
+ for (n = 0; n < db->num_fields; n++)
+ if (p[n] != NULL)
+ OPENSSL_free(p[n]);
+ } else {
+ for (n = 0; n < db->num_fields; n++) {
+ if (((p[n] < (char *)p) || (p[n] > max))
+ && (p[n] != NULL))
+ OPENSSL_free(p[n]);
+ }
+ }
+ OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i));
+ }
+ sk_OPENSSL_PSTRING_free(db->data);
+ }
+ OPENSSL_free(db);
+}
diff --git a/Cryptlib/OpenSSL/crypto/ui/ui_compat.c b/Cryptlib/OpenSSL/crypto/ui/ui_compat.c
new file mode 100644
index 00000000..e79d54ee
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ui/ui_compat.c
@@ -0,0 +1,69 @@
+/* crypto/ui/ui_compat.c */
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/ui_compat.h>
+
+int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt,
+ int verify)
+{
+ return UI_UTIL_read_pw_string(buf, length, prompt, verify);
+}
+
+int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt,
+ int verify)
+{
+ return UI_UTIL_read_pw(buf, buff, size, prompt, verify);
+}
diff --git a/Cryptlib/OpenSSL/crypto/ui/ui_lib.c b/Cryptlib/OpenSSL/crypto/ui/ui_lib.c
new file mode 100644
index 00000000..2f580352
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ui/ui_lib.c
@@ -0,0 +1,870 @@
+/* crypto/ui/ui_lib.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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
+ * 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 <string.h>
+#include "cryptlib.h"
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/ui.h>
+#include <openssl/err.h>
+#include "ui_locl.h"
+
+IMPLEMENT_STACK_OF(UI_STRING_ST)
+
+static const UI_METHOD *default_UI_meth = NULL;
+
+UI *UI_new(void)
+{
+ return (UI_new_method(NULL));
+}
+
+UI *UI_new_method(const UI_METHOD *method)
+{
+ UI *ret;
+
+ ret = (UI *)OPENSSL_malloc(sizeof(UI));
+ if (ret == NULL) {
+ UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (method == NULL)
+ ret->meth = UI_get_default_method();
+ else
+ ret->meth = method;
+
+ ret->strings = NULL;
+ ret->user_data = NULL;
+ ret->flags = 0;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
+ return ret;
+}
+
+static void free_string(UI_STRING *uis)
+{
+ if (uis->flags & OUT_STRING_FREEABLE) {
+ OPENSSL_free((char *)uis->out_string);
+ switch (uis->type) {
+ case UIT_BOOLEAN:
+ OPENSSL_free((char *)uis->_.boolean_data.action_desc);
+ OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
+ OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
+ break;
+ default:
+ break;
+ }
+ }
+ OPENSSL_free(uis);
+}
+
+void UI_free(UI *ui)
+{
+ if (ui == NULL)
+ return;
+ sk_UI_STRING_pop_free(ui->strings, free_string);
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
+ OPENSSL_free(ui);
+}
+
+static int allocate_string_stack(UI *ui)
+{
+ if (ui->strings == NULL) {
+ ui->strings = sk_UI_STRING_new_null();
+ if (ui->strings == NULL) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
+ int prompt_freeable,
+ enum UI_string_types type,
+ int input_flags, char *result_buf)
+{
+ UI_STRING *ret = NULL;
+
+ if (prompt == NULL) {
+ UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER);
+ } else if ((type == UIT_PROMPT || type == UIT_VERIFY
+ || type == UIT_BOOLEAN) && result_buf == NULL) {
+ UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER);
+ } else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING)))) {
+ ret->out_string = prompt;
+ ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0;
+ ret->input_flags = input_flags;
+ ret->type = type;
+ ret->result_buf = result_buf;
+ }
+ return ret;
+}
+
+static int general_allocate_string(UI *ui, const char *prompt,
+ int prompt_freeable,
+ enum UI_string_types type, int input_flags,
+ char *result_buf, int minsize, int maxsize,
+ const char *test_buf)
+{
+ int ret = -1;
+ UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
+ type, input_flags, result_buf);
+
+ if (s) {
+ if (allocate_string_stack(ui) >= 0) {
+ s->_.string_data.result_minsize = minsize;
+ s->_.string_data.result_maxsize = maxsize;
+ s->_.string_data.test_buf = test_buf;
+ ret = sk_UI_STRING_push(ui->strings, s);
+ /* sk_push() returns 0 on error. Let's addapt that */
+ if (ret <= 0)
+ ret--;
+ } else
+ free_string(s);
+ }
+ return ret;
+}
+
+static int general_allocate_boolean(UI *ui,
+ const char *prompt,
+ const char *action_desc,
+ const char *ok_chars,
+ const char *cancel_chars,
+ int prompt_freeable,
+ enum UI_string_types type,
+ int input_flags, char *result_buf)
+{
+ int ret = -1;
+ UI_STRING *s;
+ const char *p;
+
+ if (ok_chars == NULL) {
+ UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
+ } else if (cancel_chars == NULL) {
+ UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
+ } else {
+ for (p = ok_chars; *p; p++) {
+ if (strchr(cancel_chars, *p)) {
+ UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
+ UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
+ }
+ }
+
+ s = general_allocate_prompt(ui, prompt, prompt_freeable,
+ type, input_flags, result_buf);
+
+ if (s) {
+ if (allocate_string_stack(ui) >= 0) {
+ s->_.boolean_data.action_desc = action_desc;
+ s->_.boolean_data.ok_chars = ok_chars;
+ s->_.boolean_data.cancel_chars = cancel_chars;
+ ret = sk_UI_STRING_push(ui->strings, s);
+ /*
+ * sk_push() returns 0 on error. Let's addapt that
+ */
+ if (ret <= 0)
+ ret--;
+ } else
+ free_string(s);
+ }
+ }
+ return ret;
+}
+
+/*
+ * Returns the index to the place in the stack or -1 for error. Uses a
+ * direct reference to the prompt.
+ */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+ char *result_buf, int minsize, int maxsize)
+{
+ return general_allocate_string(ui, prompt, 0,
+ UIT_PROMPT, flags, result_buf, minsize,
+ maxsize, NULL);
+}
+
+/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+ char *result_buf, int minsize, int maxsize)
+{
+ char *prompt_copy = NULL;
+
+ if (prompt) {
+ prompt_copy = BUF_strdup(prompt);
+ if (prompt_copy == NULL) {
+ UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+
+ return general_allocate_string(ui, prompt_copy, 1,
+ UIT_PROMPT, flags, result_buf, minsize,
+ maxsize, NULL);
+}
+
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+ char *result_buf, int minsize, int maxsize,
+ const char *test_buf)
+{
+ return general_allocate_string(ui, prompt, 0,
+ UIT_VERIFY, flags, result_buf, minsize,
+ maxsize, test_buf);
+}
+
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+ char *result_buf, int minsize, int maxsize,
+ const char *test_buf)
+{
+ char *prompt_copy = NULL;
+
+ if (prompt) {
+ prompt_copy = BUF_strdup(prompt);
+ if (prompt_copy == NULL) {
+ UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ }
+
+ return general_allocate_string(ui, prompt_copy, 1,
+ UIT_VERIFY, flags, result_buf, minsize,
+ maxsize, test_buf);
+}
+
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+ const char *ok_chars, const char *cancel_chars,
+ int flags, char *result_buf)
+{
+ return general_allocate_boolean(ui, prompt, action_desc,
+ ok_chars, cancel_chars, 0, UIT_BOOLEAN,
+ flags, result_buf);
+}
+
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+ const char *ok_chars, const char *cancel_chars,
+ int flags, char *result_buf)
+{
+ char *prompt_copy = NULL;
+ char *action_desc_copy = NULL;
+ char *ok_chars_copy = NULL;
+ char *cancel_chars_copy = NULL;
+
+ if (prompt) {
+ prompt_copy = BUF_strdup(prompt);
+ if (prompt_copy == NULL) {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (action_desc) {
+ action_desc_copy = BUF_strdup(action_desc);
+ if (action_desc_copy == NULL) {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (ok_chars) {
+ ok_chars_copy = BUF_strdup(ok_chars);
+ if (ok_chars_copy == NULL) {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (cancel_chars) {
+ cancel_chars_copy = BUF_strdup(cancel_chars);
+ if (cancel_chars_copy == NULL) {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
+ ok_chars_copy, cancel_chars_copy, 1,
+ UIT_BOOLEAN, flags, result_buf);
+ err:
+ if (prompt_copy)
+ OPENSSL_free(prompt_copy);
+ if (action_desc_copy)
+ OPENSSL_free(action_desc_copy);
+ if (ok_chars_copy)
+ OPENSSL_free(ok_chars_copy);
+ if (cancel_chars_copy)
+ OPENSSL_free(cancel_chars_copy);
+ return -1;
+}
+
+int UI_add_info_string(UI *ui, const char *text)
+{
+ return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
+ NULL);
+}
+
+int UI_dup_info_string(UI *ui, const char *text)
+{
+ char *text_copy = NULL;
+
+ if (text) {
+ text_copy = BUF_strdup(text);
+ if (text_copy == NULL) {
+ UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ }
+
+ return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
+ 0, 0, NULL);
+}
+
+int UI_add_error_string(UI *ui, const char *text)
+{
+ return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
+ NULL);
+}
+
+int UI_dup_error_string(UI *ui, const char *text)
+{
+ char *text_copy = NULL;
+
+ if (text) {
+ text_copy = BUF_strdup(text);
+ if (text_copy == NULL) {
+ UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ }
+ return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
+ 0, 0, NULL);
+}
+
+char *UI_construct_prompt(UI *ui, const char *object_desc,
+ const char *object_name)
+{
+ char *prompt = NULL;
+
+ if (ui->meth->ui_construct_prompt)
+ prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
+ else {
+ char prompt1[] = "Enter ";
+ char prompt2[] = " for ";
+ char prompt3[] = ":";
+ int len = 0;
+
+ if (object_desc == NULL)
+ return NULL;
+ len = sizeof(prompt1) - 1 + strlen(object_desc);
+ if (object_name)
+ len += sizeof(prompt2) - 1 + strlen(object_name);
+ len += sizeof(prompt3) - 1;
+
+ prompt = (char *)OPENSSL_malloc(len + 1);
+ BUF_strlcpy(prompt, prompt1, len + 1);
+ BUF_strlcat(prompt, object_desc, len + 1);
+ if (object_name) {
+ BUF_strlcat(prompt, prompt2, len + 1);
+ BUF_strlcat(prompt, object_name, len + 1);
+ }
+ BUF_strlcat(prompt, prompt3, len + 1);
+ }
+ return prompt;
+}
+
+void *UI_add_user_data(UI *ui, void *user_data)
+{
+ void *old_data = ui->user_data;
+ ui->user_data = user_data;
+ return old_data;
+}
+
+void *UI_get0_user_data(UI *ui)
+{
+ return ui->user_data;
+}
+
+const char *UI_get0_result(UI *ui, int i)
+{
+ if (i < 0) {
+ UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL);
+ return NULL;
+ }
+ if (i >= sk_UI_STRING_num(ui->strings)) {
+ UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE);
+ return NULL;
+ }
+ return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
+}
+
+static int print_error(const char *str, size_t len, UI *ui)
+{
+ UI_STRING uis;
+
+ memset(&uis, 0, sizeof(uis));
+ uis.type = UIT_ERROR;
+ uis.out_string = str;
+
+ if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis))
+ return -1;
+ return 0;
+}
+
+int UI_process(UI *ui)
+{
+ int i, ok = 0;
+
+ if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
+ return -1;
+
+ if (ui->flags & UI_FLAG_PRINT_ERRORS)
+ ERR_print_errors_cb((int (*)(const char *, size_t, void *))
+ print_error, (void *)ui);
+
+ for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
+ if (ui->meth->ui_write_string
+ && !ui->meth->ui_write_string(ui,
+ sk_UI_STRING_value(ui->strings, i)))
+ {
+ ok = -1;
+ goto err;
+ }
+ }
+
+ if (ui->meth->ui_flush)
+ switch (ui->meth->ui_flush(ui)) {
+ case -1: /* Interrupt/Cancel/something... */
+ ok = -2;
+ goto err;
+ case 0: /* Errors */
+ ok = -1;
+ goto err;
+ default: /* Success */
+ ok = 0;
+ break;
+ }
+
+ for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
+ if (ui->meth->ui_read_string) {
+ switch (ui->meth->ui_read_string(ui,
+ sk_UI_STRING_value(ui->strings,
+ i))) {
+ case -1: /* Interrupt/Cancel/something... */
+ ok = -2;
+ goto err;
+ case 0: /* Errors */
+ ok = -1;
+ goto err;
+ default: /* Success */
+ ok = 0;
+ break;
+ }
+ }
+ }
+ err:
+ if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
+ return -1;
+ return ok;
+}
+
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
+{
+ if (ui == NULL) {
+ UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ switch (cmd) {
+ case UI_CTRL_PRINT_ERRORS:
+ {
+ int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS);
+ if (i)
+ ui->flags |= UI_FLAG_PRINT_ERRORS;
+ else
+ ui->flags &= ~UI_FLAG_PRINT_ERRORS;
+ return save_flag;
+ }
+ case UI_CTRL_IS_REDOABLE:
+ return ! !(ui->flags & UI_FLAG_REDOABLE);
+ default:
+ break;
+ }
+ UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND);
+ return -1;
+}
+
+int UI_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_UI, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int UI_set_ex_data(UI *r, int idx, void *arg)
+{
+ return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *UI_get_ex_data(UI *r, int idx)
+{
+ return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+void UI_set_default_method(const UI_METHOD *meth)
+{
+ default_UI_meth = meth;
+}
+
+const UI_METHOD *UI_get_default_method(void)
+{
+ if (default_UI_meth == NULL) {
+ default_UI_meth = UI_OpenSSL();
+ }
+ return default_UI_meth;
+}
+
+const UI_METHOD *UI_get_method(UI *ui)
+{
+ return ui->meth;
+}
+
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
+{
+ ui->meth = meth;
+ return ui->meth;
+}
+
+UI_METHOD *UI_create_method(char *name)
+{
+ UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD));
+
+ if (ui_method) {
+ memset(ui_method, 0, sizeof(*ui_method));
+ ui_method->name = BUF_strdup(name);
+ }
+ return ui_method;
+}
+
+/*
+ * BIG FSCKING WARNING!!!! If you use this on a statically allocated method
+ * (that is, it hasn't been allocated using UI_create_method(), you deserve
+ * anything Murphy can throw at you and more! You have been warned.
+ */
+void UI_destroy_method(UI_METHOD *ui_method)
+{
+ OPENSSL_free(ui_method->name);
+ ui_method->name = NULL;
+ OPENSSL_free(ui_method);
+}
+
+int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
+{
+ if (method) {
+ method->ui_open_session = opener;
+ return 0;
+ } else
+ return -1;
+}
+
+int UI_method_set_writer(UI_METHOD *method,
+ int (*writer) (UI *ui, UI_STRING *uis))
+{
+ if (method) {
+ method->ui_write_string = writer;
+ return 0;
+ } else
+ return -1;
+}
+
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
+{
+ if (method) {
+ method->ui_flush = flusher;
+ return 0;
+ } else
+ return -1;
+}
+
+int UI_method_set_reader(UI_METHOD *method,
+ int (*reader) (UI *ui, UI_STRING *uis))
+{
+ if (method) {
+ method->ui_read_string = reader;
+ return 0;
+ } else
+ return -1;
+}
+
+int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
+{
+ if (method) {
+ method->ui_close_session = closer;
+ return 0;
+ } else
+ 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)
+ return method->ui_open_session;
+ else
+ return NULL;
+}
+
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) {
+ if (method)
+ return method->ui_write_string;
+ else
+ return NULL;
+}
+
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) {
+ if (method)
+ return method->ui_flush;
+ else
+ return NULL;
+}
+
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) {
+ if (method)
+ return method->ui_read_string;
+ else
+ return NULL;
+}
+
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *) {
+ if (method)
+ return method->ui_close_session;
+ else
+ 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)
+ return UIT_NONE;
+ return uis->type;
+}
+
+int UI_get_input_flags(UI_STRING *uis)
+{
+ if (!uis)
+ return 0;
+ return uis->input_flags;
+}
+
+const char *UI_get0_output_string(UI_STRING *uis)
+{
+ if (!uis)
+ return NULL;
+ return uis->out_string;
+}
+
+const char *UI_get0_action_string(UI_STRING *uis)
+{
+ if (!uis)
+ return NULL;
+ switch (uis->type) {
+ case UIT_PROMPT:
+ case UIT_BOOLEAN:
+ return uis->_.boolean_data.action_desc;
+ default:
+ return NULL;
+ }
+}
+
+const char *UI_get0_result_string(UI_STRING *uis)
+{
+ if (!uis)
+ return NULL;
+ switch (uis->type) {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ return uis->result_buf;
+ default:
+ return NULL;
+ }
+}
+
+const char *UI_get0_test_string(UI_STRING *uis)
+{
+ if (!uis)
+ return NULL;
+ switch (uis->type) {
+ case UIT_VERIFY:
+ return uis->_.string_data.test_buf;
+ default:
+ return NULL;
+ }
+}
+
+int UI_get_result_minsize(UI_STRING *uis)
+{
+ if (!uis)
+ return -1;
+ switch (uis->type) {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ return uis->_.string_data.result_minsize;
+ default:
+ return -1;
+ }
+}
+
+int UI_get_result_maxsize(UI_STRING *uis)
+{
+ if (!uis)
+ return -1;
+ switch (uis->type) {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ return uis->_.string_data.result_maxsize;
+ default:
+ return -1;
+ }
+}
+
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
+{
+ int l = strlen(result);
+
+ ui->flags &= ~UI_FLAG_REDOABLE;
+
+ if (!uis)
+ return -1;
+ switch (uis->type) {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ {
+ char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1];
+ char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1];
+
+ BIO_snprintf(number1, sizeof(number1), "%d",
+ uis->_.string_data.result_minsize);
+ BIO_snprintf(number2, sizeof(number2), "%d",
+ uis->_.string_data.result_maxsize);
+
+ if (l < uis->_.string_data.result_minsize) {
+ ui->flags |= UI_FLAG_REDOABLE;
+ UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL);
+ ERR_add_error_data(5, "You must type in ",
+ number1, " to ", number2, " characters");
+ return -1;
+ }
+ if (l > uis->_.string_data.result_maxsize) {
+ ui->flags |= UI_FLAG_REDOABLE;
+ UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE);
+ ERR_add_error_data(5, "You must type in ",
+ number1, " to ", number2, " characters");
+ return -1;
+ }
+ }
+
+ if (!uis->result_buf) {
+ UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
+ return -1;
+ }
+
+ BUF_strlcpy(uis->result_buf, result,
+ uis->_.string_data.result_maxsize + 1);
+ break;
+ case UIT_BOOLEAN:
+ {
+ const char *p;
+
+ if (!uis->result_buf) {
+ UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
+ return -1;
+ }
+
+ uis->result_buf[0] = '\0';
+ for (p = result; *p; p++) {
+ if (strchr(uis->_.boolean_data.ok_chars, *p)) {
+ uis->result_buf[0] = uis->_.boolean_data.ok_chars[0];
+ break;
+ }
+ if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
+ uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0];
+ break;
+ }
+ }
+ }
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/ui/ui_locl.h b/Cryptlib/OpenSSL/crypto/ui/ui_locl.h
new file mode 100644
index 00000000..bebc13ab
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ui/ui_locl.h
@@ -0,0 +1,145 @@
+/* crypto/ui/ui.h */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * 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
+ * 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_UI_LOCL_H
+# define HEADER_UI_LOCL_H
+
+# include <openssl/ui.h>
+# include <openssl/crypto.h>
+
+# ifdef _
+# undef _
+# endif
+
+struct ui_method_st {
+ char *name;
+ /*
+ * All the functions return 1 or non-NULL for success and 0 or NULL for
+ * failure
+ */
+ /*
+ * Open whatever channel for this, be it the console, an X window or
+ * whatever. This function should use the ex_data structure to save
+ * intermediate data.
+ */
+ int (*ui_open_session) (UI *ui);
+ int (*ui_write_string) (UI *ui, UI_STRING *uis);
+ /*
+ * Flush the output. If a GUI dialog box is used, this function can be
+ * used to actually display it.
+ */
+ int (*ui_flush) (UI *ui);
+ int (*ui_read_string) (UI *ui, UI_STRING *uis);
+ int (*ui_close_session) (UI *ui);
+ /*
+ * Construct a prompt in a user-defined manner. object_desc is a textual
+ * short description of the object, for example "pass phrase", and
+ * object_name is the name of the object (might be a card name or a file
+ * name. The returned string shall always be allocated on the heap with
+ * OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+ */
+ char *(*ui_construct_prompt) (UI *ui, const char *object_desc,
+ const char *object_name);
+};
+
+struct ui_string_st {
+ enum UI_string_types type; /* Input */
+ const char *out_string; /* Input */
+ int input_flags; /* Flags from the user */
+ /*
+ * The following parameters are completely irrelevant for UIT_INFO, and
+ * can therefore be set to 0 or NULL
+ */
+ char *result_buf; /* Input and Output: If not NULL,
+ * user-defined with size in result_maxsize.
+ * Otherwise, it may be allocated by the UI
+ * routine, meaning result_minsize is going
+ * to be overwritten. */
+ union {
+ struct {
+ int result_minsize; /* Input: minimum required size of the
+ * result. */
+ int result_maxsize; /* Input: maximum permitted size of the
+ * result */
+ const char *test_buf; /* Input: test string to verify against */
+ } string_data;
+ struct {
+ const char *action_desc; /* Input */
+ const char *ok_chars; /* Input */
+ const char *cancel_chars; /* Input */
+ } boolean_data;
+ } _;
+
+# define OUT_STRING_FREEABLE 0x01
+ int flags; /* flags for internal use */
+};
+
+struct ui_st {
+ const UI_METHOD *meth;
+ STACK_OF(UI_STRING) *strings; /* We might want to prompt for more than
+ * one thing at a time, and with different
+ * echoing status. */
+ void *user_data;
+ CRYPTO_EX_DATA ex_data;
+# define UI_FLAG_REDOABLE 0x0001
+# define UI_FLAG_PRINT_ERRORS 0x0100
+ int flags;
+};
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/ui/ui_util.c b/Cryptlib/OpenSSL/crypto/ui/ui_util.c
new file mode 100644
index 00000000..80dd40e4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/ui/ui_util.c
@@ -0,0 +1,97 @@
+/* crypto/ui/ui_util.c */
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include "ui_locl.h"
+
+#ifndef BUFSIZ
+#define BUFSIZ 256
+#endif
+
+int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
+ int verify)
+{
+ char buff[BUFSIZ];
+ int ret;
+
+ ret =
+ UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length,
+ prompt, verify);
+ OPENSSL_cleanse(buff, BUFSIZ);
+ return (ret);
+}
+
+int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
+ int verify)
+{
+ int ok = 0;
+ UI *ui;
+
+ if (size < 1)
+ return -1;
+
+ ui = UI_new();
+ if (ui) {
+ ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1);
+ if (ok >= 0 && verify)
+ ok = UI_add_verify_string(ui, prompt, 0, buff, 0, size - 1, buf);
+ if (ok >= 0)
+ ok = UI_process(ui);
+ UI_free(ui);
+ }
+ if (ok > 0)
+ ok = 0;
+ return (ok);
+}
diff --git a/Cryptlib/OpenSSL/crypto/uid.c b/Cryptlib/OpenSSL/crypto/uid.c
new file mode 100644
index 00000000..90694c67
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/uid.c
@@ -0,0 +1,88 @@
+/* crypto/uid.c */
+/* ====================================================================
+ * 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 <openssl/crypto.h>
+#include <openssl/opensslconf.h>
+
+#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2)
+
+# include OPENSSL_UNISTD
+
+int OPENSSL_issetugid(void)
+{
+ return issetugid();
+}
+
+#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
+
+int OPENSSL_issetugid(void)
+{
+ return 0;
+}
+
+#else
+
+# include OPENSSL_UNISTD
+# include <sys/types.h>
+
+int OPENSSL_issetugid(void)
+{
+ if (getuid() != geteuid())
+ return 1;
+ if (getgid() != getegid())
+ return 1;
+ return 0;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/x509/vpm_int.h b/Cryptlib/OpenSSL/crypto/x509/vpm_int.h
new file mode 100644
index 00000000..9c55defc
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/vpm_int.h
@@ -0,0 +1,70 @@
+/* vpm_int.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2013.
+ */
+/* ====================================================================
+ * Copyright (c) 2013 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).
+ *
+ */
+
+/* internal only structure to hold additional X509_VERIFY_PARAM data */
+
+struct X509_VERIFY_PARAM_ID_st {
+ STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
+ unsigned int hostflags; /* Flags to control matching features */
+ char *peername; /* Matching hostname in peer certificate */
+ char *email; /* If not NULL email address to match */
+ size_t emaillen;
+ unsigned char *ip; /* If not NULL IP address to match */
+ size_t iplen; /* Length of IP address */
+};
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_att.c b/Cryptlib/OpenSSL/crypto/x509/x509_att.c
new file mode 100644
index 00000000..bd59281f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_att.c
@@ -0,0 +1,384 @@
+/* crypto/x509/x509_att.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 <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
+{
+ return sk_X509_ATTRIBUTE_num(x);
+}
+
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+ int lastpos)
+{
+ ASN1_OBJECT *obj;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-2);
+ return (X509at_get_attr_by_OBJ(x, obj, lastpos));
+}
+
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+ ASN1_OBJECT *obj, int lastpos)
+{
+ int n;
+ X509_ATTRIBUTE *ex;
+
+ if (sk == NULL)
+ return (-1);
+ lastpos++;
+ if (lastpos < 0)
+ lastpos = 0;
+ n = sk_X509_ATTRIBUTE_num(sk);
+ for (; lastpos < n; lastpos++) {
+ ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
+ if (OBJ_cmp(ex->object, obj) == 0)
+ return (lastpos);
+ }
+ return (-1);
+}
+
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
+{
+ if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
+ return NULL;
+ else
+ return sk_X509_ATTRIBUTE_value(x, loc);
+}
+
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
+{
+ X509_ATTRIBUTE *ret;
+
+ if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
+ return (NULL);
+ ret = sk_X509_ATTRIBUTE_delete(x, loc);
+ return (ret);
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+ X509_ATTRIBUTE *attr)
+{
+ X509_ATTRIBUTE *new_attr = NULL;
+ STACK_OF(X509_ATTRIBUTE) *sk = NULL;
+
+ if (x == NULL) {
+ X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER);
+ goto err2;
+ }
+
+ if (*x == NULL) {
+ if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
+ goto err;
+ } else
+ sk = *x;
+
+ if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
+ goto err2;
+ if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
+ goto err;
+ if (*x == NULL)
+ *x = sk;
+ return (sk);
+ err:
+ X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE);
+ err2:
+ if (new_attr != NULL)
+ X509_ATTRIBUTE_free(new_attr);
+ if (sk != NULL)
+ sk_X509_ATTRIBUTE_free(sk);
+ return (NULL);
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+ **x, const ASN1_OBJECT *obj,
+ int type,
+ const unsigned char *bytes,
+ int len)
+{
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+ attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
+ if (!attr)
+ return 0;
+ ret = X509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+ **x, int nid, int type,
+ const unsigned char *bytes,
+ int len)
+{
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+ attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
+ if (!attr)
+ return 0;
+ ret = X509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+ **x, const char *attrname,
+ int type,
+ const unsigned char *bytes,
+ int len)
+{
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+ attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
+ if (!attr)
+ return 0;
+ ret = X509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
+}
+
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
+ ASN1_OBJECT *obj, int lastpos, int type)
+{
+ int i;
+ X509_ATTRIBUTE *at;
+ i = X509at_get_attr_by_OBJ(x, obj, lastpos);
+ if (i == -1)
+ return NULL;
+ if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
+ return NULL;
+ at = X509at_get_attr(x, i);
+ if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
+ return NULL;
+ return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+ int atrtype, const void *data,
+ int len)
+{
+ ASN1_OBJECT *obj;
+ X509_ATTRIBUTE *ret;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL) {
+ X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
+ if (ret == NULL)
+ ASN1_OBJECT_free(obj);
+ return (ret);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+ const ASN1_OBJECT *obj,
+ int atrtype, const void *data,
+ int len)
+{
+ X509_ATTRIBUTE *ret;
+
+ if ((attr == NULL) || (*attr == NULL)) {
+ if ((ret = X509_ATTRIBUTE_new()) == NULL) {
+ X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,
+ ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ } else
+ ret = *attr;
+
+ if (!X509_ATTRIBUTE_set1_object(ret, obj))
+ goto err;
+ if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
+ goto err;
+
+ if ((attr != NULL) && (*attr == NULL))
+ *attr = ret;
+ return (ret);
+ err:
+ if ((attr == NULL) || (ret != *attr))
+ X509_ATTRIBUTE_free(ret);
+ return (NULL);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+ const char *atrname, int type,
+ const unsigned char *bytes,
+ int len)
+{
+ ASN1_OBJECT *obj;
+ X509_ATTRIBUTE *nattr;
+
+ obj = OBJ_txt2obj(atrname, 0);
+ if (obj == NULL) {
+ X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
+ X509_R_INVALID_FIELD_NAME);
+ ERR_add_error_data(2, "name=", atrname);
+ return (NULL);
+ }
+ nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
+ ASN1_OBJECT_free(obj);
+ return nattr;
+}
+
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
+{
+ if ((attr == NULL) || (obj == NULL))
+ return (0);
+ ASN1_OBJECT_free(attr->object);
+ attr->object = OBJ_dup(obj);
+ return (1);
+}
+
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+ const void *data, int len)
+{
+ ASN1_TYPE *ttmp;
+ ASN1_STRING *stmp = NULL;
+ int atype = 0;
+ if (!attr)
+ return 0;
+ if (attrtype & MBSTRING_FLAG) {
+ stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
+ OBJ_obj2nid(attr->object));
+ if (!stmp) {
+ X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
+ return 0;
+ }
+ atype = stmp->type;
+ } else if (len != -1) {
+ if (!(stmp = ASN1_STRING_type_new(attrtype)))
+ goto err;
+ if (!ASN1_STRING_set(stmp, data, len))
+ goto err;
+ atype = attrtype;
+ }
+ if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
+ goto err;
+ attr->single = 0;
+ /*
+ * This is a bit naughty because the attribute should really have at
+ * least one value but some types use and zero length SET and require
+ * this.
+ */
+ if (attrtype == 0)
+ return 1;
+ if (!(ttmp = ASN1_TYPE_new()))
+ goto err;
+ if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
+ if (!ASN1_TYPE_set1(ttmp, attrtype, data))
+ goto err;
+ } else
+ ASN1_TYPE_set(ttmp, atype, stmp);
+ if (!sk_ASN1_TYPE_push(attr->value.set, ttmp))
+ goto err;
+ return 1;
+ err:
+ X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
+{
+ if (!attr->single)
+ return sk_ASN1_TYPE_num(attr->value.set);
+ if (attr->value.single)
+ return 1;
+ return 0;
+}
+
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
+{
+ if (attr == NULL)
+ return (NULL);
+ return (attr->object);
+}
+
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+ int atrtype, void *data)
+{
+ ASN1_TYPE *ttmp;
+ ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
+ if (!ttmp)
+ return NULL;
+ if (atrtype != ASN1_TYPE_get(ttmp)) {
+ X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
+ return NULL;
+ }
+ return ttmp->value.ptr;
+}
+
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
+{
+ if (attr == NULL)
+ return (NULL);
+ if (idx >= X509_ATTRIBUTE_count(attr))
+ return NULL;
+ if (!attr->single)
+ return sk_ASN1_TYPE_value(attr->value.set, idx);
+ else
+ return attr->value.single;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_cmp.c b/Cryptlib/OpenSSL/crypto/x509/x509_cmp.c
new file mode 100644
index 00000000..49c71b91
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_cmp.c
@@ -0,0 +1,498 @@
+/* crypto/x509/x509_cmp.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 <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
+{
+ int i;
+ X509_CINF *ai, *bi;
+
+ ai = a->cert_info;
+ bi = b->cert_info;
+ i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
+ if (i)
+ return (i);
+ return (X509_NAME_cmp(ai->issuer, bi->issuer));
+}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_and_serial_hash(X509 *a)
+{
+ unsigned long ret = 0;
+ EVP_MD_CTX ctx;
+ unsigned char md[16];
+ char *f;
+
+ EVP_MD_CTX_init(&ctx);
+ f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
+ if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
+ goto err;
+ OPENSSL_free(f);
+ if (!EVP_DigestUpdate
+ (&ctx, (unsigned char *)a->cert_info->serialNumber->data,
+ (unsigned long)a->cert_info->serialNumber->length))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL))
+ goto err;
+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+ ) & 0xffffffffL;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return (ret);
+}
+#endif
+
+int X509_issuer_name_cmp(const X509 *a, const X509 *b)
+{
+ return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
+}
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b)
+{
+ return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
+}
+
+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);
+}
+
+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);
+}
+
+ASN1_INTEGER *X509_get_serialNumber(X509 *a)
+{
+ return (a->cert_info->serialNumber);
+}
+
+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 prototyped to take "const"
+ * arguments (eg. for use in STACKs), the way X509 handling is - these
+ * operations may involve ensuring the hashes are up-to-date and ensuring
+ * certain cert information is cached. So this is the point where the
+ * "depth-first" constification tree has to halt with an evil cast.
+ */
+int X509_cmp(const X509 *a, const X509 *b)
+{
+ int rv;
+ /* ensure hash is valid */
+ X509_check_purpose((X509 *)a, -1, 0);
+ X509_check_purpose((X509 *)b, -1, 0);
+
+ rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
+ if (rv)
+ return rv;
+ /* Check for match against stored encoding too */
+ if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) {
+ rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
+ if (rv)
+ return rv;
+ return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
+ a->cert_info->enc.len);
+ }
+ return rv;
+}
+#endif
+
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
+{
+ int ret;
+
+ /* Ensure canonical encoding is present and up to date */
+
+ if (!a->canon_enc || a->modified) {
+ ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+ if (ret < 0)
+ return -2;
+ }
+
+ if (!b->canon_enc || b->modified) {
+ ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+ if (ret < 0)
+ return -2;
+ }
+
+ ret = a->canon_enclen - b->canon_enclen;
+
+ if (ret)
+ return ret;
+
+ return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+
+}
+
+unsigned long X509_NAME_hash(X509_NAME *x)
+{
+ unsigned long ret = 0;
+ unsigned char md[SHA_DIGEST_LENGTH];
+
+ /* Make sure X509_NAME structure contains valid cached encoding */
+ i2d_X509_NAME(x, NULL);
+ if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
+ NULL))
+ 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_old(X509_NAME *x)
+{
+ EVP_MD_CTX md_ctx;
+ unsigned long ret = 0;
+ unsigned char md[16];
+
+ /* 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);
+ if (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))
+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+ ) & 0xffffffffL;
+ EVP_MD_CTX_cleanup(&md_ctx);
+
+ return (ret);
+}
+#endif
+
+/* Search a stack of X509 for a match */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+ ASN1_INTEGER *serial)
+{
+ int i;
+ X509_CINF cinf;
+ X509 x, *x509 = NULL;
+
+ if (!sk)
+ return NULL;
+
+ x.cert_info = &cinf;
+ cinf.serialNumber = serial;
+ cinf.issuer = name;
+
+ for (i = 0; i < sk_X509_num(sk); i++) {
+ x509 = sk_X509_value(sk, i);
+ if (X509_issuer_and_serial_cmp(x509, &x) == 0)
+ return (x509);
+ }
+ return (NULL);
+}
+
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
+{
+ X509 *x509;
+ int i;
+
+ for (i = 0; i < sk_X509_num(sk); i++) {
+ x509 = sk_X509_value(sk, i);
+ if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
+ return (x509);
+ }
+ return (NULL);
+}
+
+EVP_PKEY *X509_get_pubkey(X509 *x)
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (NULL);
+ return (X509_PUBKEY_get(x->cert_info->key));
+}
+
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
+{
+ if (!x)
+ return NULL;
+ return x->cert_info->key->public_key;
+}
+
+int X509_check_private_key(X509 *x, EVP_PKEY *k)
+{
+ EVP_PKEY *xk;
+ int ret;
+
+ xk = X509_get_pubkey(x);
+
+ if (xk)
+ ret = EVP_PKEY_cmp(xk, k);
+ else
+ ret = -2;
+
+ switch (ret) {
+ case 1:
+ break;
+ case 0:
+ X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH);
+ break;
+ case -1:
+ X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH);
+ break;
+ case -2:
+ X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
+ }
+ if (xk)
+ EVP_PKEY_free(xk);
+ if (ret > 0)
+ return 1;
+ return 0;
+}
+
+/*
+ * Check a suite B algorithm is permitted: pass in a public key and the NID
+ * of its signature (or 0 if no signature). The pflags is a pointer to a
+ * flags field which must contain the suite B verification flags.
+ */
+
+#ifndef OPENSSL_NO_EC
+
+static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
+{
+ const EC_GROUP *grp = NULL;
+ int curve_nid;
+ if (pkey && pkey->type == EVP_PKEY_EC)
+ grp = EC_KEY_get0_group(pkey->pkey.ec);
+ if (!grp)
+ return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
+ curve_nid = EC_GROUP_get_curve_name(grp);
+ /* Check curve is consistent with LOS */
+ if (curve_nid == NID_secp384r1) { /* P-384 */
+ /*
+ * Check signature algorithm is consistent with curve.
+ */
+ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
+ return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+ if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
+ return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+ /* If we encounter P-384 we cannot use P-256 later */
+ *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
+ } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */
+ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
+ return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+ if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
+ return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+ } else
+ return X509_V_ERR_SUITE_B_INVALID_CURVE;
+
+ return X509_V_OK;
+}
+
+int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
+ unsigned long flags)
+{
+ int rv, i, sign_nid;
+ EVP_PKEY *pk = NULL;
+ unsigned long tflags;
+ if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+ return X509_V_OK;
+ tflags = flags;
+ /* If no EE certificate passed in must be first in chain */
+ if (x == NULL) {
+ x = sk_X509_value(chain, 0);
+ i = 1;
+ } else
+ i = 0;
+
+ if (X509_get_version(x) != 2) {
+ rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+ /* Correct error depth */
+ i = 0;
+ goto end;
+ }
+
+ pk = X509_get_pubkey(x);
+ /* Check EE key only */
+ rv = check_suite_b(pk, -1, &tflags);
+ if (rv != X509_V_OK) {
+ /* Correct error depth */
+ i = 0;
+ goto end;
+ }
+ for (; i < sk_X509_num(chain); i++) {
+ sign_nid = X509_get_signature_nid(x);
+ x = sk_X509_value(chain, i);
+ if (X509_get_version(x) != 2) {
+ rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+ goto end;
+ }
+ EVP_PKEY_free(pk);
+ pk = X509_get_pubkey(x);
+ rv = check_suite_b(pk, sign_nid, &tflags);
+ if (rv != X509_V_OK)
+ goto end;
+ }
+
+ /* Final check: root CA signature */
+ rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
+ end:
+ if (pk)
+ EVP_PKEY_free(pk);
+ if (rv != X509_V_OK) {
+ /* Invalid signature or LOS errors are for previous cert */
+ if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
+ || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
+ i--;
+ /*
+ * If we have LOS error and flags changed then we are signing P-384
+ * with P-256. Use more meaninggul error.
+ */
+ if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
+ rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
+ if (perror_depth)
+ *perror_depth = i;
+ }
+ return rv;
+}
+
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
+{
+ int sign_nid;
+ if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+ return X509_V_OK;
+ sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
+ return check_suite_b(pk, sign_nid, &flags);
+}
+
+#else
+int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
+ unsigned long flags)
+{
+ return 0;
+}
+
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
+{
+ return 0;
+}
+
+#endif
+/*
+ * Not strictly speaking an "up_ref" as a STACK doesn't have a reference
+ * count but it has the same effect by duping the STACK and upping the ref of
+ * each X509 structure.
+ */
+STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
+{
+ STACK_OF(X509) *ret;
+ int i;
+ ret = sk_X509_dup(chain);
+ for (i = 0; i < sk_X509_num(ret); i++) {
+ X509 *x = sk_X509_value(ret, i);
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ }
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_d2.c b/Cryptlib/OpenSSL/crypto/x509/x509_d2.c
new file mode 100644
index 00000000..50ca2a6d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_d2.c
@@ -0,0 +1,109 @@
+/* crypto/x509/x509_d2.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_STORE_set_default_paths(X509_STORE *ctx)
+{
+ X509_LOOKUP *lookup;
+
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+ if (lookup == NULL)
+ return (0);
+ X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+ if (lookup == NULL)
+ return (0);
+ X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+ /* clear any errors */
+ ERR_clear_error();
+
+ return (1);
+}
+
+int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
+ const char *path)
+{
+ X509_LOOKUP *lookup;
+
+ if (file != NULL) {
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+ if (lookup == NULL)
+ return (0);
+ if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
+ return (0);
+ }
+ if (path != NULL) {
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+ if (lookup == NULL)
+ return (0);
+ if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
+ return (0);
+ }
+ if ((path == NULL) && (file == NULL))
+ return (0);
+ return (1);
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_def.c b/Cryptlib/OpenSSL/crypto/x509/x509_def.c
new file mode 100644
index 00000000..25c55375
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_def.c
@@ -0,0 +1,92 @@
+/* crypto/x509/x509_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.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+
+const char *X509_get_default_private_dir(void)
+{
+ return (X509_PRIVATE_DIR);
+}
+
+const char *X509_get_default_cert_area(void)
+{
+ return (X509_CERT_AREA);
+}
+
+const char *X509_get_default_cert_dir(void)
+{
+ return (X509_CERT_DIR);
+}
+
+const char *X509_get_default_cert_file(void)
+{
+ return (X509_CERT_FILE);
+}
+
+const char *X509_get_default_cert_dir_env(void)
+{
+ return (X509_CERT_DIR_EVP);
+}
+
+const char *X509_get_default_cert_file_env(void)
+{
+ return (X509_CERT_FILE_EVP);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_err.c b/Cryptlib/OpenSSL/crypto/x509/x509_err.c
new file mode 100644
index 00000000..1e779fef
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_err.c
@@ -0,0 +1,187 @@
+/* crypto/x509/x509_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2012 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
+
+static ERR_STRING_DATA X509_str_functs[] = {
+ {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"},
+ {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"},
+ {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"},
+ {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"},
+ {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"},
+ {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"},
+ {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"},
+ {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"},
+ {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"},
+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID),
+ "X509_ATTRIBUTE_create_by_NID"},
+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),
+ "X509_ATTRIBUTE_create_by_OBJ"},
+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),
+ "X509_ATTRIBUTE_create_by_txt"},
+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"},
+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"},
+ {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"},
+ {ERR_FUNC(X509_F_X509_CRL_DIFF), "X509_CRL_diff"},
+ {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"},
+ {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),
+ "X509_EXTENSION_create_by_NID"},
+ {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),
+ "X509_EXTENSION_create_by_OBJ"},
+ {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),
+ "X509_get_pubkey_parameters"},
+ {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"},
+ {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"},
+ {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"},
+ {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"},
+ {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID),
+ "X509_NAME_ENTRY_create_by_NID"},
+ {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),
+ "X509_NAME_ENTRY_create_by_txt"},
+ {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),
+ "X509_NAME_ENTRY_set_object"},
+ {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"},
+ {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"},
+ {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"},
+ {ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"},
+ {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"},
+ {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY),
+ "X509_REQ_check_private_key"},
+ {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"},
+ {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"},
+ {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"},
+ {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"},
+ {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"},
+ {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER),
+ "X509_STORE_CTX_get1_issuer"},
+ {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"},
+ {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"},
+ {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT),
+ "X509_STORE_CTX_purpose_inherit"},
+ {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"},
+ {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"},
+ {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"},
+ {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA X509_str_reasons[] = {
+ {ERR_REASON(X509_R_AKID_MISMATCH), "akid mismatch"},
+ {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"},
+ {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"},
+ {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
+ {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),
+ "cert already in hash table"},
+ {ERR_REASON(X509_R_CRL_ALREADY_DELTA), "crl already delta"},
+ {ERR_REASON(X509_R_CRL_VERIFY_FAILURE), "crl verify failure"},
+ {ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"},
+ {ERR_REASON(X509_R_IDP_MISMATCH), "idp mismatch"},
+ {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"},
+ {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"},
+ {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"},
+ {ERR_REASON(X509_R_ISSUER_MISMATCH), "issuer mismatch"},
+ {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"},
+ {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_NAME_TOO_LONG), "name too long"},
+ {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"},
+ {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
+ "no cert set for us to verify"},
+ {ERR_REASON(X509_R_NO_CRL_NUMBER), "no crl number"},
+ {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"},
+ {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"},
+ {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"},
+ {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"},
+ {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
+ {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
+ {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"},
+ {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_X509_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(X509_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, X509_str_functs);
+ ERR_load_strings(0, X509_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_ext.c b/Cryptlib/OpenSSL/crypto/x509/x509_ext.c
new file mode 100644
index 00000000..fb4e311d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_ext.c
@@ -0,0 +1,211 @@
+/* crypto/x509/x509_ext.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 <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509_CRL_get_ext_count(X509_CRL *x)
+{
+ return (X509v3_get_ext_count(x->crl->extensions));
+}
+
+int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos));
+}
+
+int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos));
+}
+
+int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
+{
+ return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos));
+}
+
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
+{
+ return (X509v3_get_ext(x->crl->extensions, loc));
+}
+
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
+{
+ return (X509v3_delete_ext(x->crl->extensions, loc));
+}
+
+void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
+{
+ return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
+}
+
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+ unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
+}
+
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL);
+}
+
+int X509_get_ext_count(X509 *x)
+{
+ return (X509v3_get_ext_count(x->cert_info->extensions));
+}
+
+int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos));
+}
+
+int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos));
+}
+
+int X509_get_ext_by_critical(X509 *x, int crit, int lastpos)
+{
+ return (X509v3_get_ext_by_critical
+ (x->cert_info->extensions, crit, lastpos));
+}
+
+X509_EXTENSION *X509_get_ext(X509 *x, int loc)
+{
+ return (X509v3_get_ext(x->cert_info->extensions, loc));
+}
+
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
+{
+ return (X509v3_delete_ext(x->cert_info->extensions, loc));
+}
+
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL);
+}
+
+void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
+{
+ return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
+}
+
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+ unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
+ flags);
+}
+
+int X509_REVOKED_get_ext_count(X509_REVOKED *x)
+{
+ return (X509v3_get_ext_count(x->extensions));
+}
+
+int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
+{
+ return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos));
+}
+
+int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos));
+}
+
+int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos)
+{
+ return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
+}
+
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
+{
+ return (X509v3_get_ext(x->extensions, loc));
+}
+
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
+{
+ return (X509v3_delete_ext(x->extensions, loc));
+}
+
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
+}
+
+void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
+{
+ return X509V3_get_d2i(x->extensions, nid, crit, idx);
+}
+
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+ unsigned long flags)
+{
+ return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
+}
+
+IMPLEMENT_STACK_OF(X509_EXTENSION)
+
+IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_lu.c b/Cryptlib/OpenSSL/crypto/x509/x509_lu.c
new file mode 100644
index 00000000..50120a4d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_lu.c
@@ -0,0 +1,710 @@
+/* crypto/x509/x509_lu.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
+{
+ X509_LOOKUP *ret;
+
+ ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
+ if (ret == NULL)
+ return NULL;
+
+ ret->init = 0;
+ ret->skip = 0;
+ ret->method = method;
+ ret->method_data = NULL;
+ ret->store_ctx = NULL;
+ if ((method->new_item != NULL) && !method->new_item(ret)) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+void X509_LOOKUP_free(X509_LOOKUP *ctx)
+{
+ if (ctx == NULL)
+ return;
+ if ((ctx->method != NULL) && (ctx->method->free != NULL))
+ (*ctx->method->free) (ctx);
+ OPENSSL_free(ctx);
+}
+
+int X509_LOOKUP_init(X509_LOOKUP *ctx)
+{
+ if (ctx->method == NULL)
+ return 0;
+ if (ctx->method->init != NULL)
+ return ctx->method->init(ctx);
+ else
+ return 1;
+}
+
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
+{
+ if (ctx->method == NULL)
+ return 0;
+ if (ctx->method->shutdown != NULL)
+ return ctx->method->shutdown(ctx);
+ else
+ return 1;
+}
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+ char **ret)
+{
+ if (ctx->method == NULL)
+ return -1;
+ if (ctx->method->ctrl != NULL)
+ return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
+ else
+ return 1;
+}
+
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+ X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
+ return X509_LU_FAIL;
+ if (ctx->skip)
+ return 0;
+ return ctx->method->get_by_subject(ctx, type, name, ret);
+}
+
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+ ASN1_INTEGER *serial, X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
+ return X509_LU_FAIL;
+ return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
+}
+
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+ unsigned char *bytes, int len,
+ X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
+ return X509_LU_FAIL;
+ return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
+}
+
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
+ X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
+ return X509_LU_FAIL;
+ return ctx->method->get_by_alias(ctx, type, str, len, ret);
+}
+
+static int x509_object_cmp(const X509_OBJECT *const *a,
+ const X509_OBJECT *const *b)
+{
+ int ret;
+
+ ret = ((*a)->type - (*b)->type);
+ if (ret)
+ return ret;
+ switch ((*a)->type) {
+ case X509_LU_X509:
+ ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
+ break;
+ case X509_LU_CRL:
+ ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
+ break;
+ default:
+ /* abort(); */
+ return 0;
+ }
+ return ret;
+}
+
+X509_STORE *X509_STORE_new(void)
+{
+ X509_STORE *ret;
+
+ if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
+ return NULL;
+ ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+ ret->cache = 1;
+ ret->get_cert_methods = sk_X509_LOOKUP_new_null();
+ ret->verify = 0;
+ ret->verify_cb = 0;
+
+ if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
+ return NULL;
+
+ ret->get_issuer = 0;
+ ret->check_issued = 0;
+ ret->check_revocation = 0;
+ 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)) {
+ sk_X509_OBJECT_free(ret->objs);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ ret->references = 1;
+ return ret;
+}
+
+static void cleanup(X509_OBJECT *a)
+{
+ if (!a)
+ return;
+ if (a->type == X509_LU_X509) {
+ X509_free(a->data.x509);
+ } else if (a->type == X509_LU_CRL) {
+ X509_CRL_free(a->data.crl);
+ } else {
+ /* abort(); */
+ }
+
+ OPENSSL_free(a);
+}
+
+void X509_STORE_free(X509_STORE *vfy)
+{
+ int i;
+ STACK_OF(X509_LOOKUP) *sk;
+ X509_LOOKUP *lu;
+
+ if (vfy == NULL)
+ return;
+
+ i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);
+#ifdef REF_PRINT
+ REF_PRINT("X509_STORE", vfy);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "X509_STORE_free, bad reference count\n");
+ abort(); /* ok */
+ }
+#endif
+
+ sk = vfy->get_cert_methods;
+ for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+ lu = sk_X509_LOOKUP_value(sk, i);
+ X509_LOOKUP_shutdown(lu);
+ X509_LOOKUP_free(lu);
+ }
+ sk_X509_LOOKUP_free(sk);
+ sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
+ if (vfy->param)
+ X509_VERIFY_PARAM_free(vfy->param);
+ OPENSSL_free(vfy);
+}
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
+{
+ int i;
+ STACK_OF(X509_LOOKUP) *sk;
+ X509_LOOKUP *lu;
+
+ sk = v->get_cert_methods;
+ for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+ lu = sk_X509_LOOKUP_value(sk, i);
+ if (m == lu->method) {
+ return lu;
+ }
+ }
+ /* a new one */
+ lu = X509_LOOKUP_new(m);
+ if (lu == NULL)
+ return NULL;
+ else {
+ lu->store_ctx = v;
+ if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
+ return lu;
+ else {
+ X509_LOOKUP_free(lu);
+ return NULL;
+ }
+ }
+}
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
+ X509_OBJECT *ret)
+{
+ X509_STORE *ctx = vs->ctx;
+ X509_LOOKUP *lu;
+ X509_OBJECT stmp, *tmp;
+ int i, j;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+ if (tmp == NULL || type == X509_LU_CRL) {
+ for (i = vs->current_method;
+ i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
+ lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
+ j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
+ if (j < 0) {
+ vs->current_method = j;
+ return j;
+ } else if (j) {
+ tmp = &stmp;
+ break;
+ }
+ }
+ vs->current_method = 0;
+ if (tmp == NULL)
+ return 0;
+ }
+
+/*- if (ret->data.ptr != NULL)
+ X509_OBJECT_free_contents(ret); */
+
+ ret->type = tmp->type;
+ ret->data.ptr = tmp->data.ptr;
+
+ X509_OBJECT_up_ref_count(ret);
+
+ return 1;
+}
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
+{
+ X509_OBJECT *obj;
+ int ret = 1;
+
+ if (x == NULL)
+ return 0;
+ obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+ if (obj == NULL) {
+ X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ obj->type = X509_LU_X509;
+ obj->data.x509 = x;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+
+ X509_OBJECT_up_ref_count(obj);
+
+ if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ X509err(X509_F_X509_STORE_ADD_CERT,
+ X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ ret = 0;
+ } else
+ sk_X509_OBJECT_push(ctx->objs, obj);
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+ return ret;
+}
+
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
+{
+ X509_OBJECT *obj;
+ int ret = 1;
+
+ if (x == NULL)
+ return 0;
+ obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+ if (obj == NULL) {
+ X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ obj->type = X509_LU_CRL;
+ obj->data.crl = x;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+
+ X509_OBJECT_up_ref_count(obj);
+
+ if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ ret = 0;
+ } else
+ sk_X509_OBJECT_push(ctx->objs, obj);
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+ return ret;
+}
+
+void X509_OBJECT_up_ref_count(X509_OBJECT *a)
+{
+ switch (a->type) {
+ case X509_LU_X509:
+ CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509);
+ break;
+ case X509_LU_CRL:
+ CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL);
+ break;
+ }
+}
+
+void X509_OBJECT_free_contents(X509_OBJECT *a)
+{
+ switch (a->type) {
+ case X509_LU_X509:
+ X509_free(a->data.x509);
+ break;
+ case X509_LU_CRL:
+ X509_CRL_free(a->data.crl);
+ break;
+ }
+}
+
+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) {
+ case X509_LU_X509:
+ stmp.data.x509 = &x509_s;
+ x509_s.cert_info = &cinf_s;
+ cinf_s.subject = name;
+ break;
+ case X509_LU_CRL:
+ stmp.data.crl = &crl_s;
+ crl_s.crl = &crl_info_s;
+ crl_info_s.issuer = name;
+ break;
+ default:
+ /* abort(); */
+ return -1;
+ }
+
+ 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, X509_NAME *name)
+{
+ int idx;
+ idx = X509_OBJECT_idx_by_subject(h, type, name);
+ if (idx == -1)
+ return NULL;
+ 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);
+
+ /*
+ * 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) && (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) {
+ 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;
+}
+
+/*-
+ * Try to get issuer certificate from store. Due to limitations
+ * of the API this can only retrieve a single certificate matching
+ * a given subject name. However it will fill the cache with all
+ * matching certificates, so we can examine the cache for all
+ * matches.
+ *
+ * Return values are:
+ * 1 lookup successful.
+ * 0 certificate not found.
+ * -1 some other error.
+ */
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
+{
+ X509_NAME *xn;
+ X509_OBJECT obj, *pobj;
+ int i, ok, idx, ret;
+ xn = X509_get_issuer_name(x);
+ ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
+ if (ok != X509_LU_X509) {
+ if (ok == X509_LU_RETRY) {
+ X509_OBJECT_free_contents(&obj);
+ X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY);
+ return -1;
+ } else if (ok != X509_LU_FAIL) {
+ X509_OBJECT_free_contents(&obj);
+ /* not good :-(, break anyway */
+ return -1;
+ }
+ return 0;
+ }
+ /* If certificate matches all OK */
+ if (ctx->check_issued(ctx, x, obj.data.x509)) {
+ *issuer = obj.data.x509;
+ return 1;
+ }
+ X509_OBJECT_free_contents(&obj);
+
+ /* Else find index of first cert accepted by 'check_issued' */
+ ret = 0;
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
+ if (idx != -1) { /* should be true as we've had at least one
+ * match */
+ /* Look through all matching certs for suitable issuer */
+ for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
+ pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+ /* See if we've run past the matches */
+ if (pobj->type != X509_LU_X509)
+ break;
+ if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
+ break;
+ if (ctx->check_issued(ctx, x, pobj->data.x509)) {
+ *issuer = pobj->data.x509;
+ X509_OBJECT_up_ref_count(pobj);
+ ret = 1;
+ break;
+ }
+ }
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ return ret;
+}
+
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
+{
+ return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
+
+int X509_STORE_set_depth(X509_STORE *ctx, int depth)
+{
+ X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+ return 1;
+}
+
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
+{
+ return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
+}
+
+int X509_STORE_set_trust(X509_STORE *ctx, int trust)
+{
+ return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
+}
+
+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;
+}
+
+void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
+ STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
+ *ctx,
+ X509_NAME *nm))
+{
+ ctx->lookup_crls = cb;
+}
+
+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
+{
+ return ctx->ctx;
+}
+
+IMPLEMENT_STACK_OF(X509_LOOKUP)
+
+IMPLEMENT_STACK_OF(X509_OBJECT)
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_obj.c b/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
new file mode 100644
index 00000000..3de3ac72
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
@@ -0,0 +1,230 @@
+/* crypto/x509/x509_obj.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/buffer.h>
+
+/*
+ * Limit to ensure we don't overflow: much greater than
+ * anything enountered in practice.
+ */
+
+#define NAME_ONELINE_MAX (1024 * 1024)
+
+char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
+{
+ X509_NAME_ENTRY *ne;
+ int i;
+ int n, lold, l, l1, l2, num, j, type;
+ const char *s;
+ char *p;
+ unsigned char *q;
+ BUF_MEM *b = NULL;
+ static const char hex[17] = "0123456789ABCDEF";
+ int gs_doit[4];
+ char tmp_buf[80];
+#ifdef CHARSET_EBCDIC
+ char ebcdic_buf[1024];
+#endif
+
+ if (buf == NULL) {
+ if ((b = BUF_MEM_new()) == NULL)
+ goto err;
+ if (!BUF_MEM_grow(b, 200))
+ goto err;
+ b->data[0] = '\0';
+ len = 200;
+ } else if (len == 0) {
+ return NULL;
+ }
+ if (a == NULL) {
+ if (b) {
+ buf = b->data;
+ OPENSSL_free(b);
+ }
+ strncpy(buf, "NO X509_NAME", len);
+ buf[len - 1] = '\0';
+ return buf;
+ }
+
+ len--; /* space for '\0' */
+ l = 0;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ ne = sk_X509_NAME_ENTRY_value(a->entries, i);
+ n = OBJ_obj2nid(ne->object);
+ if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
+ i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
+ s = tmp_buf;
+ }
+ l1 = strlen(s);
+
+ type = ne->value->type;
+ num = ne->value->length;
+ if (num > NAME_ONELINE_MAX) {
+ X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+ goto end;
+ }
+ q = ne->value->data;
+#ifdef CHARSET_EBCDIC
+ if (type == V_ASN1_GENERALSTRING ||
+ type == V_ASN1_VISIBLESTRING ||
+ type == V_ASN1_PRINTABLESTRING ||
+ type == V_ASN1_TELETEXSTRING ||
+ type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) {
+ if (num > (int)sizeof(ebcdic_buf))
+ num = sizeof(ebcdic_buf);
+ ascii2ebcdic(ebcdic_buf, q, num);
+ q = ebcdic_buf;
+ }
+#endif
+
+ if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
+ for (j = 0; j < num; j++)
+ if (q[j] != 0)
+ gs_doit[j & 3] = 1;
+
+ if (gs_doit[0] | gs_doit[1] | gs_doit[2])
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
+ else {
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
+ gs_doit[3] = 1;
+ }
+ } else
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
+
+ for (l2 = j = 0; j < num; j++) {
+ if (!gs_doit[j & 3])
+ continue;
+ l2++;
+#ifndef CHARSET_EBCDIC
+ if ((q[j] < ' ') || (q[j] > '~'))
+ l2 += 3;
+#else
+ if ((os_toascii[q[j]] < os_toascii[' ']) ||
+ (os_toascii[q[j]] > os_toascii['~']))
+ l2 += 3;
+#endif
+ }
+
+ lold = l;
+ l += 1 + l1 + 1 + l2;
+ if (l > NAME_ONELINE_MAX) {
+ X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+ goto end;
+ }
+ if (b != NULL) {
+ if (!BUF_MEM_grow(b, l + 1))
+ goto err;
+ p = &(b->data[lold]);
+ } else if (l > len) {
+ break;
+ } else
+ p = &(buf[lold]);
+ *(p++) = '/';
+ memcpy(p, s, (unsigned int)l1);
+ p += l1;
+ *(p++) = '=';
+
+#ifndef CHARSET_EBCDIC /* q was assigned above already. */
+ q = ne->value->data;
+#endif
+
+ for (j = 0; j < num; j++) {
+ if (!gs_doit[j & 3])
+ continue;
+#ifndef CHARSET_EBCDIC
+ n = q[j];
+ if ((n < ' ') || (n > '~')) {
+ *(p++) = '\\';
+ *(p++) = 'x';
+ *(p++) = hex[(n >> 4) & 0x0f];
+ *(p++) = hex[n & 0x0f];
+ } else
+ *(p++) = n;
+#else
+ n = os_toascii[q[j]];
+ if ((n < os_toascii[' ']) || (n > os_toascii['~'])) {
+ *(p++) = '\\';
+ *(p++) = 'x';
+ *(p++) = hex[(n >> 4) & 0x0f];
+ *(p++) = hex[n & 0x0f];
+ } else
+ *(p++) = q[j];
+#endif
+ }
+ *p = '\0';
+ }
+ if (b != NULL) {
+ p = b->data;
+ OPENSSL_free(b);
+ } else
+ p = buf;
+ if (i == 0)
+ *p = '\0';
+ return (p);
+ err:
+ X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
+ end:
+ BUF_MEM_free(b);
+ return (NULL);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_r2x.c b/Cryptlib/OpenSSL/crypto/x509/x509_r2x.c
new file mode 100644
index 00000000..0ff439c9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_r2x.c
@@ -0,0 +1,113 @@
+/* crypto/x509/x509_r2x.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
+{
+ X509 *ret = NULL;
+ X509_CINF *xi = NULL;
+ X509_NAME *xn;
+
+ if ((ret = X509_new()) == NULL) {
+ X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* duplicate the request */
+ xi = ret->cert_info;
+
+ if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
+ if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
+ goto err;
+ if (!ASN1_INTEGER_set(xi->version, 2))
+ goto err;
+/*- xi->extensions=ri->attributes; <- bad, should not ever be done
+ ri->attributes=NULL; */
+ }
+
+ xn = X509_REQ_get_subject_name(r);
+ if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
+ goto err;
+ if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
+ goto err;
+
+ if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
+ goto err;
+ if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
+ NULL)
+ goto err;
+
+ X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
+
+ if (!X509_sign(ret, pkey, EVP_md5()))
+ goto err;
+ if (0) {
+ err:
+ X509_free(ret);
+ ret = NULL;
+ }
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_req.c b/Cryptlib/OpenSSL/crypto/x509/x509_req.c
new file mode 100644
index 00000000..01795f4b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_req.c
@@ -0,0 +1,328 @@
+/* crypto/x509/x509_req.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/pem.h>
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+ X509_REQ *ret;
+ X509_REQ_INFO *ri;
+ int i;
+ EVP_PKEY *pktmp;
+
+ ret = X509_REQ_new();
+ if (ret == NULL) {
+ X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ri = ret->req_info;
+
+ ri->version->length = 1;
+ ri->version->data = (unsigned char *)OPENSSL_malloc(1);
+ if (ri->version->data == NULL)
+ goto err;
+ ri->version->data[0] = 0; /* version == 0 */
+
+ if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
+ goto err;
+
+ pktmp = X509_get_pubkey(x);
+ if (pktmp == NULL)
+ goto err;
+ i = X509_REQ_set_pubkey(ret, pktmp);
+ EVP_PKEY_free(pktmp);
+ if (!i)
+ goto err;
+
+ if (pkey != NULL) {
+ if (!X509_REQ_sign(ret, pkey, md))
+ goto err;
+ }
+ return (ret);
+ err:
+ X509_REQ_free(ret);
+ return (NULL);
+}
+
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
+{
+ if ((req == NULL) || (req->req_info == NULL))
+ return (NULL);
+ return (X509_PUBKEY_get(req->req_info->pubkey));
+}
+
+int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
+{
+ EVP_PKEY *xk = NULL;
+ int ok = 0;
+
+ xk = X509_REQ_get_pubkey(x);
+ switch (EVP_PKEY_cmp(xk, k)) {
+ case 1:
+ ok = 1;
+ break;
+ case 0:
+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
+ X509_R_KEY_VALUES_MISMATCH);
+ break;
+ case -1:
+ X509err(X509_F_X509_REQ_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_REQ_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_REQ_CHECK_PRIVATE_KEY,
+ X509_R_CANT_CHECK_DH_KEY);
+ break;
+ }
+#endif
+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
+ }
+
+ EVP_PKEY_free(xk);
+ return (ok);
+}
+
+/*
+ * It seems several organisations had the same idea of including a list of
+ * extensions in a certificate request. There are at least two OIDs that are
+ * used and there may be more: so the list is configurable.
+ */
+
+static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef };
+
+static int *ext_nids = ext_nid_list;
+
+int X509_REQ_extension_nid(int req_nid)
+{
+ int i, nid;
+ for (i = 0;; i++) {
+ nid = ext_nids[i];
+ if (nid == NID_undef)
+ return 0;
+ else if (req_nid == nid)
+ return 1;
+ }
+}
+
+int *X509_REQ_get_extension_nids(void)
+{
+ return ext_nids;
+}
+
+void X509_REQ_set_extension_nids(int *nids)
+{
+ ext_nids = nids;
+}
+
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
+{
+ X509_ATTRIBUTE *attr;
+ ASN1_TYPE *ext = NULL;
+ int idx, *pnid;
+ const unsigned char *p;
+
+ if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
+ return (NULL);
+ for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
+ idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
+ if (idx == -1)
+ continue;
+ attr = X509_REQ_get_attr(req, idx);
+ if (attr->single)
+ ext = attr->value.single;
+ else if (sk_ASN1_TYPE_num(attr->value.set))
+ ext = sk_ASN1_TYPE_value(attr->value.set, 0);
+ break;
+ }
+ if (!ext || (ext->type != V_ASN1_SEQUENCE))
+ return NULL;
+ p = ext->value.sequence->data;
+ 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
+ * in case we want to create a non standard one.
+ */
+
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+ int nid)
+{
+ ASN1_TYPE *at = NULL;
+ X509_ATTRIBUTE *attr = NULL;
+ if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new()))
+ goto err;
+
+ at->type = V_ASN1_SEQUENCE;
+ /* Generate encoding of extensions */
+ 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;
+ at = NULL;
+ attr->single = 0;
+ attr->object = OBJ_nid2obj(nid);
+ if (!req->req_info->attributes) {
+ if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
+ goto err;
+ }
+ if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
+ goto err;
+ return 1;
+ err:
+ X509_ATTRIBUTE_free(attr);
+ ASN1_TYPE_free(at);
+ return 0;
+}
+
+/* This is the normal usage: use the "official" OID */
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
+{
+ return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
+}
+
+/* Request attribute functions */
+
+int X509_REQ_get_attr_count(const X509_REQ *req)
+{
+ return X509at_get_attr_count(req->req_info->attributes);
+}
+
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
+{
+ return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
+}
+
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
+{
+ return X509at_get_attr(req->req_info->attributes, loc);
+}
+
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
+{
+ return X509at_delete_attr(req->req_info->attributes, loc);
+}
+
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
+{
+ if (X509at_add1_attr(&req->req_info->attributes, attr))
+ return 1;
+ return 0;
+}
+
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+ const ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
+ type, bytes, len))
+ return 1;
+ return 0;
+}
+
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+ int nid, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
+ type, bytes, len))
+ return 1;
+ return 0;
+}
+
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+ const char *attrname, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
+ type, bytes, len))
+ return 1;
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_set.c b/Cryptlib/OpenSSL/crypto/x509/x509_set.c
new file mode 100644
index 00000000..5b802bd6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_set.c
@@ -0,0 +1,152 @@
+/* crypto/x509/x509_set.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_set_version(X509 *x, long version)
+{
+ if (x == NULL)
+ return (0);
+ if (version == 0) {
+ M_ASN1_INTEGER_free(x->cert_info->version);
+ x->cert_info->version = NULL;
+ return (1);
+ }
+ if (x->cert_info->version == NULL) {
+ if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL)
+ return (0);
+ }
+ return (ASN1_INTEGER_set(x->cert_info->version, version));
+}
+
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
+{
+ ASN1_INTEGER *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->cert_info->serialNumber;
+ if (in != serial) {
+ in = M_ASN1_INTEGER_dup(serial);
+ if (in != NULL) {
+ M_ASN1_INTEGER_free(x->cert_info->serialNumber);
+ x->cert_info->serialNumber = in;
+ }
+ }
+ return (in != NULL);
+}
+
+int X509_set_issuer_name(X509 *x, X509_NAME *name)
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (0);
+ return (X509_NAME_set(&x->cert_info->issuer, name));
+}
+
+int X509_set_subject_name(X509 *x, X509_NAME *name)
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (0);
+ return (X509_NAME_set(&x->cert_info->subject, name));
+}
+
+int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
+{
+ ASN1_TIME *in;
+
+ if ((x == NULL) || (x->cert_info->validity == NULL))
+ return (0);
+ in = x->cert_info->validity->notBefore;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->cert_info->validity->notBefore);
+ x->cert_info->validity->notBefore = in;
+ }
+ }
+ return (in != NULL);
+}
+
+int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
+{
+ ASN1_TIME *in;
+
+ if ((x == NULL) || (x->cert_info->validity == NULL))
+ return (0);
+ in = x->cert_info->validity->notAfter;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->cert_info->validity->notAfter);
+ x->cert_info->validity->notAfter = in;
+ }
+ }
+ return (in != NULL);
+}
+
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (0);
+ return (X509_PUBKEY_set(&(x->cert_info->key), pkey));
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_trs.c b/Cryptlib/OpenSSL/crypto/x509/x509_trs.c
new file mode 100644
index 00000000..11e07634
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_trs.c
@@ -0,0 +1,318 @@
+/* x509_trs.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b);
+static void trtable_free(X509_TRUST *p);
+
+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
+static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
+
+static int obj_trust(int id, X509 *x, int flags);
+static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
+
+/*
+ * WARNING: the following table should be kept in order of trust and without
+ * any gaps so we can just subtract the minimum trust value to get an index
+ * into the table
+ */
+
+static X509_TRUST trstandard[] = {
+ {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
+ {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth,
+ NULL},
+ {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth,
+ NULL},
+ {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_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
+};
+
+#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
+
+IMPLEMENT_STACK_OF(X509_TRUST)
+
+static STACK_OF(X509_TRUST) *trtable = NULL;
+
+static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b)
+{
+ return (*a)->trust - (*b)->trust;
+}
+
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+ int) {
+ int (*oldtrust) (int, X509 *, int);
+ oldtrust = default_trust;
+ default_trust = trust;
+ return oldtrust;
+}
+
+int X509_check_trust(X509 *x, int id, int flags)
+{
+ X509_TRUST *pt;
+ int idx;
+ if (id == -1)
+ return 1;
+ /* We get this as a default value */
+ if (id == 0) {
+ int rv;
+ rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
+ if (rv != X509_TRUST_UNTRUSTED)
+ return rv;
+ return trust_compat(NULL, x, 0);
+ }
+ idx = X509_TRUST_get_by_id(id);
+ if (idx == -1)
+ return default_trust(id, x, flags);
+ pt = X509_TRUST_get0(idx);
+ return pt->check_trust(pt, x, flags);
+}
+
+int X509_TRUST_get_count(void)
+{
+ if (!trtable)
+ return X509_TRUST_COUNT;
+ return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
+}
+
+X509_TRUST *X509_TRUST_get0(int idx)
+{
+ if (idx < 0)
+ return NULL;
+ if (idx < (int)X509_TRUST_COUNT)
+ return trstandard + idx;
+ return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
+}
+
+int X509_TRUST_get_by_id(int id)
+{
+ X509_TRUST tmp;
+ int idx;
+ if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
+ return id - X509_TRUST_MIN;
+ tmp.trust = id;
+ if (!trtable)
+ return -1;
+ idx = sk_X509_TRUST_find(trtable, &tmp);
+ if (idx == -1)
+ return -1;
+ return idx + X509_TRUST_COUNT;
+}
+
+int X509_TRUST_set(int *t, int trust)
+{
+ if (X509_TRUST_get_by_id(trust) == -1) {
+ X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
+ return 0;
+ }
+ *t = trust;
+ return 1;
+}
+
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+ char *name, int arg1, void *arg2)
+{
+ int idx;
+ X509_TRUST *trtmp;
+ /*
+ * This is set according to what we change: application can't set it
+ */
+ flags &= ~X509_TRUST_DYNAMIC;
+ /* This will always be set for application modified trust entries */
+ flags |= X509_TRUST_DYNAMIC_NAME;
+ /* Get existing entry if any */
+ idx = X509_TRUST_get_by_id(id);
+ /* Need a new entry */
+ if (idx == -1) {
+ if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ trtmp->flags = X509_TRUST_DYNAMIC;
+ } else
+ trtmp = X509_TRUST_get0(idx);
+
+ /* OPENSSL_free existing name if dynamic */
+ if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
+ OPENSSL_free(trtmp->name);
+ /* dup supplied name */
+ if (!(trtmp->name = BUF_strdup(name))) {
+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ /* Keep the dynamic flag of existing entry */
+ trtmp->flags &= X509_TRUST_DYNAMIC;
+ /* Set all other flags */
+ trtmp->flags |= flags;
+
+ trtmp->trust = id;
+ trtmp->check_trust = ck;
+ trtmp->arg1 = arg1;
+ trtmp->arg2 = arg2;
+
+ /* If its a new entry manage the dynamic table */
+ if (idx == -1) {
+ if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!sk_X509_TRUST_push(trtable, trtmp)) {
+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void trtable_free(X509_TRUST *p)
+{
+ if (!p)
+ return;
+ if (p->flags & X509_TRUST_DYNAMIC) {
+ if (p->flags & X509_TRUST_DYNAMIC_NAME)
+ OPENSSL_free(p->name);
+ OPENSSL_free(p);
+ }
+}
+
+void X509_TRUST_cleanup(void)
+{
+ unsigned int i;
+ for (i = 0; i < X509_TRUST_COUNT; i++)
+ trtable_free(trstandard + i);
+ sk_X509_TRUST_pop_free(trtable, trtable_free);
+ trtable = NULL;
+}
+
+int X509_TRUST_get_flags(X509_TRUST *xp)
+{
+ return xp->flags;
+}
+
+char *X509_TRUST_get0_name(X509_TRUST *xp)
+{
+ return xp->name;
+}
+
+int X509_TRUST_get_trust(X509_TRUST *xp)
+{
+ return xp->trust;
+}
+
+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
+{
+ if (x->aux && (x->aux->trust || x->aux->reject))
+ return obj_trust(trust->arg1, x, flags);
+ /*
+ * we don't have any trust settings: for compatibility we return trusted
+ * if it is self signed
+ */
+ return trust_compat(trust, x, flags);
+}
+
+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
+{
+ if (x->aux)
+ return obj_trust(trust->arg1, x, flags);
+ return X509_TRUST_UNTRUSTED;
+}
+
+static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
+{
+ X509_check_purpose(x, -1, 0);
+ if (x->ex_flags & EXFLAG_SS)
+ return X509_TRUST_TRUSTED;
+ else
+ return X509_TRUST_UNTRUSTED;
+}
+
+static int obj_trust(int id, X509 *x, int flags)
+{
+ ASN1_OBJECT *obj;
+ int i;
+ X509_CERT_AUX *ax;
+ ax = x->aux;
+ if (!ax)
+ return X509_TRUST_UNTRUSTED;
+ if (ax->reject) {
+ for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
+ obj = sk_ASN1_OBJECT_value(ax->reject, i);
+ if (OBJ_obj2nid(obj) == id)
+ return X509_TRUST_REJECTED;
+ }
+ }
+ if (ax->trust) {
+ for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
+ obj = sk_ASN1_OBJECT_value(ax->trust, i);
+ if (OBJ_obj2nid(obj) == id)
+ return X509_TRUST_TRUSTED;
+ }
+ }
+ return X509_TRUST_UNTRUSTED;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_txt.c b/Cryptlib/OpenSSL/crypto/x509/x509_txt.c
new file mode 100644
index 00000000..3d46d3ff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_txt.c
@@ -0,0 +1,211 @@
+/* crypto/x509/x509_txt.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 <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+const char *X509_verify_cert_error_string(long n)
+{
+ static char buf[100];
+
+ switch ((int)n) {
+ case X509_V_OK:
+ return ("ok");
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ return ("unable to get issuer certificate");
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ return ("unable to get certificate CRL");
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+ return ("unable to decrypt certificate's signature");
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+ return ("unable to decrypt CRL's signature");
+ case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+ return ("unable to decode issuer public key");
+ case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+ return ("certificate signature failure");
+ case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+ return ("CRL signature failure");
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ return ("certificate is not yet valid");
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ return ("CRL is not yet valid");
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ return ("certificate has expired");
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ return ("CRL has expired");
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ return ("format error in certificate's notBefore field");
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ return ("format error in certificate's notAfter field");
+ case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+ return ("format error in CRL's lastUpdate field");
+ case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+ return ("format error in CRL's nextUpdate field");
+ case X509_V_ERR_OUT_OF_MEM:
+ return ("out of memory");
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ return ("self signed certificate");
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ return ("self signed certificate in certificate chain");
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ return ("unable to get local issuer certificate");
+ case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+ return ("unable to verify the first certificate");
+ case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+ return ("certificate chain too long");
+ case X509_V_ERR_CERT_REVOKED:
+ return ("certificate revoked");
+ case X509_V_ERR_INVALID_CA:
+ return ("invalid CA certificate");
+ case X509_V_ERR_INVALID_NON_CA:
+ return ("invalid non-CA certificate (has CA markings)");
+ case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ return ("path length constraint exceeded");
+ case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+ return ("proxy path length constraint exceeded");
+ case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+ return
+ ("proxy certificates not allowed, please set the appropriate flag");
+ case X509_V_ERR_INVALID_PURPOSE:
+ return ("unsupported certificate purpose");
+ case X509_V_ERR_CERT_UNTRUSTED:
+ return ("certificate not trusted");
+ case X509_V_ERR_CERT_REJECTED:
+ return ("certificate rejected");
+ case X509_V_ERR_APPLICATION_VERIFICATION:
+ return ("application verification failure");
+ case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+ return ("subject issuer mismatch");
+ case X509_V_ERR_AKID_SKID_MISMATCH:
+ return ("authority and subject key identifier mismatch");
+ case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+ return ("authority and issuer serial number mismatch");
+ case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+ return ("key usage does not include certificate signing");
+ case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+ return ("unable to get CRL issuer certificate");
+ case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+ return ("unhandled critical extension");
+ case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
+ return ("key usage does not include CRL signing");
+ case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+ return ("key usage does not include digital signature");
+ case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
+ return ("unhandled critical CRL extension");
+ case X509_V_ERR_INVALID_EXTENSION:
+ return ("invalid or inconsistent certificate extension");
+ case X509_V_ERR_INVALID_POLICY_EXTENSION:
+ return ("invalid or inconsistent certificate policy extension");
+ case X509_V_ERR_NO_EXPLICIT_POLICY:
+ return ("no explicit policy");
+ 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");
+
+ case X509_V_ERR_SUITE_B_INVALID_VERSION:
+ return ("Suite B: certificate version invalid");
+ case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
+ return ("Suite B: invalid public key algorithm");
+ case X509_V_ERR_SUITE_B_INVALID_CURVE:
+ return ("Suite B: invalid ECC curve");
+ case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
+ return ("Suite B: invalid signature algorithm");
+ case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
+ return ("Suite B: curve not allowed for this LOS");
+ case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
+ return ("Suite B: cannot sign P-384 with P-256");
+
+ case X509_V_ERR_HOSTNAME_MISMATCH:
+ return ("Hostname mismatch");
+ case X509_V_ERR_EMAIL_MISMATCH:
+ return ("Email address mismatch");
+ case X509_V_ERR_IP_ADDRESS_MISMATCH:
+ return ("IP address mismatch");
+
+ default:
+ BIO_snprintf(buf, sizeof buf, "error number %ld", n);
+ return (buf);
+ }
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_v3.c b/Cryptlib/OpenSSL/crypto/x509/x509_v3.c
new file mode 100644
index 00000000..4a03445a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_v3.c
@@ -0,0 +1,284 @@
+/* crypto/x509/x509_v3.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 <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
+{
+ if (x == NULL)
+ return (0);
+ return (sk_X509_EXTENSION_num(x));
+}
+
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
+ int lastpos)
+{
+ ASN1_OBJECT *obj;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-2);
+ return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
+}
+
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
+ ASN1_OBJECT *obj, int lastpos)
+{
+ int n;
+ X509_EXTENSION *ex;
+
+ if (sk == NULL)
+ return (-1);
+ lastpos++;
+ if (lastpos < 0)
+ lastpos = 0;
+ n = sk_X509_EXTENSION_num(sk);
+ for (; lastpos < n; lastpos++) {
+ ex = sk_X509_EXTENSION_value(sk, lastpos);
+ if (OBJ_cmp(ex->object, obj) == 0)
+ return (lastpos);
+ }
+ return (-1);
+}
+
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
+ int lastpos)
+{
+ int n;
+ X509_EXTENSION *ex;
+
+ if (sk == NULL)
+ return (-1);
+ lastpos++;
+ if (lastpos < 0)
+ lastpos = 0;
+ n = sk_X509_EXTENSION_num(sk);
+ for (; lastpos < n; lastpos++) {
+ ex = sk_X509_EXTENSION_value(sk, lastpos);
+ if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
+ return (lastpos);
+ }
+ return (-1);
+}
+
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
+{
+ if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+ return NULL;
+ else
+ return sk_X509_EXTENSION_value(x, loc);
+}
+
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
+{
+ X509_EXTENSION *ret;
+
+ if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+ return (NULL);
+ ret = sk_X509_EXTENSION_delete(x, loc);
+ return (ret);
+}
+
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+ X509_EXTENSION *ex, int loc)
+{
+ X509_EXTENSION *new_ex = NULL;
+ int n;
+ STACK_OF(X509_EXTENSION) *sk = NULL;
+
+ if (x == NULL) {
+ X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER);
+ goto err2;
+ }
+
+ if (*x == NULL) {
+ if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
+ goto err;
+ } else
+ sk = *x;
+
+ n = sk_X509_EXTENSION_num(sk);
+ if (loc > n)
+ loc = n;
+ else if (loc < 0)
+ loc = n;
+
+ if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
+ goto err2;
+ if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
+ goto err;
+ if (*x == NULL)
+ *x = sk;
+ return (sk);
+ err:
+ X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE);
+ err2:
+ if (new_ex != NULL)
+ X509_EXTENSION_free(new_ex);
+ if (sk != NULL)
+ sk_X509_EXTENSION_free(sk);
+ return (NULL);
+}
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
+ int crit,
+ ASN1_OCTET_STRING *data)
+{
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ret;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL) {
+ X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
+ if (ret == NULL)
+ ASN1_OBJECT_free(obj);
+ return (ret);
+}
+
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+ ASN1_OBJECT *obj, int crit,
+ ASN1_OCTET_STRING *data)
+{
+ X509_EXTENSION *ret;
+
+ if ((ex == NULL) || (*ex == NULL)) {
+ if ((ret = X509_EXTENSION_new()) == NULL) {
+ X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,
+ ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ } else
+ ret = *ex;
+
+ if (!X509_EXTENSION_set_object(ret, obj))
+ goto err;
+ if (!X509_EXTENSION_set_critical(ret, crit))
+ goto err;
+ if (!X509_EXTENSION_set_data(ret, data))
+ goto err;
+
+ if ((ex != NULL) && (*ex == NULL))
+ *ex = ret;
+ return (ret);
+ err:
+ if ((ex == NULL) || (ret != *ex))
+ X509_EXTENSION_free(ret);
+ return (NULL);
+}
+
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj)
+{
+ if ((ex == NULL) || (obj == NULL))
+ return (0);
+ ASN1_OBJECT_free(ex->object);
+ ex->object = OBJ_dup(obj);
+ return (1);
+}
+
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
+{
+ if (ex == NULL)
+ return (0);
+ ex->critical = (crit) ? 0xFF : -1;
+ return (1);
+}
+
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
+{
+ int i;
+
+ if (ex == NULL)
+ return (0);
+ i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length);
+ if (!i)
+ return (0);
+ return (1);
+}
+
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
+{
+ if (ex == NULL)
+ return (NULL);
+ return (ex->object);
+}
+
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
+{
+ if (ex == NULL)
+ return (NULL);
+ return (ex->value);
+}
+
+int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
+{
+ if (ex == NULL)
+ return (0);
+ if (ex->critical > 0)
+ return 1;
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c b/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
new file mode 100644
index 00000000..25e8a89f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
@@ -0,0 +1,2501 @@
+/* crypto/x509/x509_vfy.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 <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include "vpm_int.h"
+
+/* 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_id(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;
+
+static int null_callback(int ok, X509_STORE_CTX *e)
+{
+ return ok;
+}
+
+#if 0
+static int x509_subject_cmp(X509 **a, X509 **b)
+{
+ return X509_subject_name_cmp(*a, *b);
+}
+#endif
+/* Return 1 is a certificate is self signed */
+static int cert_self_signed(X509 *x)
+{
+ X509_check_purpose(x, -1, 0);
+ if (x->ex_flags & EXFLAG_SS)
+ return 1;
+ else
+ return 0;
+}
+
+/* Given a certificate try and find an exact match in the store */
+
+static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
+{
+ STACK_OF(X509) *certs;
+ X509 *xtmp = NULL;
+ int i;
+ /* Lookup all certs with matching subject name */
+ certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
+ if (certs == NULL)
+ return NULL;
+ /* Look for exact match */
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ xtmp = sk_X509_value(certs, i);
+ if (!X509_cmp(xtmp, x))
+ break;
+ }
+ if (i < sk_X509_num(certs))
+ CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
+ else
+ xtmp = NULL;
+ sk_X509_pop_free(certs, X509_free);
+ return xtmp;
+}
+
+int X509_verify_cert(X509_STORE_CTX *ctx)
+{
+ X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
+ int bad_chain = 0;
+ X509_VERIFY_PARAM *param = ctx->param;
+ int depth, i, ok = 0;
+ int num, j, retry;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+ STACK_OF(X509) *sktmp = NULL;
+ int trust = X509_TRUST_UNTRUSTED;
+ int err;
+
+ if (ctx->cert == NULL) {
+ X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+ return -1;
+ }
+ if (ctx->chain != NULL) {
+ /*
+ * This X509_STORE_CTX has already been used to verify a cert. We
+ * cannot do another one.
+ */
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ cb = ctx->verify_cb;
+
+ /*
+ * first we make sure the chain we are going to build is present and that
+ * the first entry is in place
+ */
+ if (((ctx->chain = sk_X509_new_null()) == NULL) ||
+ (!sk_X509_push(ctx->chain, ctx->cert))) {
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ok = -1;
+ goto err;
+ }
+ CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
+ ctx->last_untrusted = 1;
+
+ /* We use a temporary STACK so we can chop and hack at it */
+ if (ctx->untrusted != NULL
+ && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ok = -1;
+ goto err;
+ }
+
+ num = sk_X509_num(ctx->chain);
+ x = sk_X509_value(ctx->chain, num - 1);
+ depth = param->depth;
+
+ for (;;) {
+ /* If we have enough, we break */
+ if (depth < num)
+ break; /* FIXME: If this happens, we should take
+ * note of it and, if appropriate, use the
+ * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
+ * later. */
+
+ /* If we are self signed, we break */
+ if (cert_self_signed(x))
+ break;
+ /*
+ * If asked see if we can find issuer in trusted store first
+ */
+ if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
+ ok = ctx->get_issuer(&xtmp, ctx, x);
+ if (ok < 0)
+ goto err;
+ /*
+ * If successful for now free up cert so it will be picked up
+ * again later.
+ */
+ if (ok > 0) {
+ X509_free(xtmp);
+ break;
+ }
+ }
+
+ /* If we were passed a cert chain, use it first */
+ if (ctx->untrusted != NULL) {
+ xtmp = find_issuer(ctx, sktmp, x);
+ if (xtmp != NULL) {
+ if (!sk_X509_push(ctx->chain, xtmp)) {
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ok = -1;
+ goto err;
+ }
+ CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
+ (void)sk_X509_delete_ptr(sktmp, xtmp);
+ ctx->last_untrusted++;
+ x = xtmp;
+ num++;
+ /*
+ * reparse the full chain for the next one
+ */
+ continue;
+ }
+ }
+ break;
+ }
+
+ /* Remember how many untrusted certs we have */
+ j = num;
+ /*
+ * at this point, chain should contain a list of untrusted certificates.
+ * We now need to add at least one trusted one, if possible, otherwise we
+ * complain.
+ */
+
+ do {
+ /*
+ * Examine last certificate in chain and see if it is self signed.
+ */
+ i = sk_X509_num(ctx->chain);
+ x = sk_X509_value(ctx->chain, i - 1);
+ if (cert_self_signed(x)) {
+ /* we have a self signed certificate */
+ if (sk_X509_num(ctx->chain) == 1) {
+ /*
+ * We have a single self signed certificate: see if we can
+ * find it in the store. We must have an exact match to avoid
+ * possible impersonation.
+ */
+ ok = ctx->get_issuer(&xtmp, ctx, x);
+ if ((ok <= 0) || X509_cmp(x, xtmp)) {
+ ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+ ctx->current_cert = x;
+ ctx->error_depth = i - 1;
+ if (ok == 1)
+ X509_free(xtmp);
+ bad_chain = 1;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto err;
+ } else {
+ /*
+ * We have a match: replace certificate with store
+ * version so we get any trust settings.
+ */
+ X509_free(x);
+ x = xtmp;
+ (void)sk_X509_set(ctx->chain, i - 1, x);
+ ctx->last_untrusted = 0;
+ }
+ } else {
+ /*
+ * extract and save self signed certificate for later use
+ */
+ chain_ss = sk_X509_pop(ctx->chain);
+ ctx->last_untrusted--;
+ num--;
+ j--;
+ x = sk_X509_value(ctx->chain, num - 1);
+ }
+ }
+ /* We now lookup certs from the certificate store */
+ for (;;) {
+ /* If we have enough, we break */
+ if (depth < num)
+ break;
+ /* If we are self signed, we break */
+ if (cert_self_signed(x))
+ break;
+ ok = ctx->get_issuer(&xtmp, ctx, x);
+
+ if (ok < 0)
+ goto err;
+ if (ok == 0)
+ break;
+ x = xtmp;
+ if (!sk_X509_push(ctx->chain, x)) {
+ X509_free(xtmp);
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ok = -1;
+ goto err;
+ }
+ num++;
+ }
+
+ /* we now have our chain, lets check it... */
+ if ((trust = check_trust(ctx)) == X509_TRUST_REJECTED) {
+ /* Callback already issued */
+ ok = 0;
+ goto err;
+ }
+
+ /*
+ * If it's not explicitly trusted then check if there is an alternative
+ * chain that could be used. We only do this if we haven't already
+ * checked via TRUSTED_FIRST and the user hasn't switched off alternate
+ * chain checking
+ */
+ retry = 0;
+ if (trust != X509_TRUST_TRUSTED
+ && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+ && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
+ while (j-- > 1) {
+ xtmp2 = sk_X509_value(ctx->chain, j - 1);
+ ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+ if (ok < 0)
+ goto err;
+ /* Check if we found an alternate chain */
+ if (ok > 0) {
+ /*
+ * Free up the found cert we'll add it again later
+ */
+ X509_free(xtmp);
+
+ /*
+ * Dump all the certs above this point - we've found an
+ * alternate chain
+ */
+ while (num > j) {
+ xtmp = sk_X509_pop(ctx->chain);
+ X509_free(xtmp);
+ num--;
+ }
+ ctx->last_untrusted = sk_X509_num(ctx->chain);
+ retry = 1;
+ break;
+ }
+ }
+ }
+ } while (retry);
+
+ /*
+ * If not explicitly trusted then indicate error unless it's a single
+ * self signed certificate in which case we've indicated an error already
+ * and set bad_chain == 1
+ */
+ if (trust != X509_TRUST_TRUSTED && !bad_chain) {
+ if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
+ if (ctx->last_untrusted >= num)
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
+ else
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
+ ctx->current_cert = x;
+ } else {
+
+ sk_X509_push(ctx->chain, chain_ss);
+ num++;
+ ctx->last_untrusted = num;
+ ctx->current_cert = chain_ss;
+ ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
+ chain_ss = NULL;
+ }
+
+ ctx->error_depth = num - 1;
+ bad_chain = 1;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+
+ /* We have the chain complete: now we need to check its purpose */
+ ok = check_chain_extensions(ctx);
+
+ if (!ok)
+ goto err;
+
+ /* Check name constraints */
+
+ ok = check_name_constraints(ctx);
+
+ if (!ok)
+ goto err;
+
+ ok = check_id(ctx);
+
+ if (!ok)
+ goto err;
+
+ /* We may as well copy down any DSA parameters that are required */
+ X509_get_pubkey_parameters(NULL, ctx->chain);
+
+ /*
+ * Check revocation status: we do this after copying parameters because
+ * they may be needed for CRL signature verification.
+ */
+
+ ok = ctx->check_revocation(ctx);
+ if (!ok)
+ goto err;
+
+ err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
+ ctx->param->flags);
+ if (err != X509_V_OK) {
+ ctx->error = err;
+ ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
+ ok = cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+
+ /* At this point, we have a chain and need to verify it */
+ if (ctx->verify != NULL)
+ ok = ctx->verify(ctx);
+ else
+ ok = internal_verify(ctx);
+ if (!ok)
+ goto err;
+
+#ifndef OPENSSL_NO_RFC3779
+ /* RFC 3779 path validation, now that CRL check has been done */
+ ok = v3_asid_validate_path(ctx);
+ if (!ok)
+ goto err;
+ ok = v3_addr_validate_path(ctx);
+ if (!ok)
+ goto err;
+#endif
+
+ /* If we get this far evaluate policies */
+ if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
+ ok = ctx->check_policy(ctx);
+ if (!ok)
+ goto err;
+ if (0) {
+ err:
+ /* Ensure we return an error */
+ if (ok > 0)
+ ok = 0;
+ X509_get_pubkey_parameters(NULL, ctx->chain);
+ }
+ if (sktmp != NULL)
+ sk_X509_free(sktmp);
+ if (chain_ss != NULL)
+ X509_free(chain_ss);
+ return ok;
+}
+
+/*
+ * Given a STACK_OF(X509) find the issuer of cert (if any)
+ */
+
+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
+{
+ int i;
+ X509 *issuer;
+ for (i = 0; i < sk_X509_num(sk); i++) {
+ issuer = sk_X509_value(sk, i);
+ if (ctx->check_issued(ctx, x, issuer))
+ return issuer;
+ }
+ return NULL;
+}
+
+/* Given a possible certificate and issuer check them */
+
+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
+{
+ int ret;
+ ret = X509_check_issued(issuer, x);
+ if (ret == X509_V_OK)
+ return 1;
+ /* If we haven't asked for issuer errors don't set ctx */
+ if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
+ return 0;
+
+ ctx->error = ret;
+ ctx->current_cert = x;
+ ctx->current_issuer = issuer;
+ return ctx->verify_cb(0, ctx);
+}
+
+/* Alternative lookup method: look from a STACK stored in other_ctx */
+
+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
+{
+ *issuer = find_issuer(ctx, ctx->other_ctx, x);
+ if (*issuer) {
+ CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
+ return 1;
+ } else
+ return 0;
+}
+
+/*
+ * Check a certificate chains extensions for consistency with the supplied
+ * purpose
+ */
+
+static int check_chain_extensions(X509_STORE_CTX *ctx)
+{
+#ifdef OPENSSL_NO_CHAIN_VERIFY
+ return 1;
+#else
+ int i, ok = 0, must_be_ca, plen = 0;
+ X509 *x;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+ int proxy_path_length = 0;
+ int purpose;
+ int allow_proxy_certs;
+ cb = ctx->verify_cb;
+
+ /*-
+ * must_be_ca can have 1 of 3 values:
+ * -1: we accept both CA and non-CA certificates, to allow direct
+ * use of self-signed certificates (which are marked as CA).
+ * 0: we only accept non-CA certificates. This is currently not
+ * used, but the possibility is present for future extensions.
+ * 1: we only accept CA certificates. This is currently used for
+ * all certificates in the chain except the leaf certificate.
+ */
+ must_be_ca = -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++) {
+ int ret;
+ x = sk_X509_value(ctx->chain, i);
+ if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+ && (x->ex_flags & EXFLAG_CRITICAL)) {
+ ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
+ ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ ret = X509_check_ca(x);
+ switch (must_be_ca) {
+ case -1:
+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ && (ret != 1) && (ret != 0)) {
+ ret = 0;
+ ctx->error = X509_V_ERR_INVALID_CA;
+ } else
+ ret = 1;
+ break;
+ case 0:
+ if (ret != 0) {
+ ret = 0;
+ ctx->error = X509_V_ERR_INVALID_NON_CA;
+ } else
+ ret = 1;
+ break;
+ default:
+ if ((ret == 0)
+ || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ && (ret != 1))) {
+ ret = 0;
+ ctx->error = X509_V_ERR_INVALID_CA;
+ } else
+ ret = 1;
+ break;
+ }
+ if (ret == 0) {
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ if (ctx->param->purpose > 0) {
+ ret = X509_check_purpose(x, purpose, must_be_ca > 0);
+ if ((ret == 0)
+ || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ && (ret != 1))) {
+ ctx->error = X509_V_ERR_INVALID_PURPOSE;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ }
+ /* Check pathlen if not self issued */
+ if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+ && (x->ex_pathlen != -1)
+ && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
+ ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ /* Increment path length if not self issued */
+ if (!(x->ex_flags & EXFLAG_SI))
+ plen++;
+ /*
+ * If this certificate is a proxy certificate, the next certificate
+ * must be another proxy certificate or a EE certificate. If not,
+ * the next certificate must be a CA certificate.
+ */
+ if (x->ex_flags & EXFLAG_PROXY) {
+ if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
+ ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ proxy_path_length++;
+ must_be_ca = 0;
+ } else
+ must_be_ca = 1;
+ }
+ ok = 1;
+ end:
+ return ok;
+#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_id_error(X509_STORE_CTX *ctx, int errcode)
+{
+ ctx->error = errcode;
+ ctx->current_cert = ctx->cert;
+ ctx->error_depth = 0;
+ return ctx->verify_cb(0, ctx);
+}
+
+static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
+{
+ int i;
+ int n = sk_OPENSSL_STRING_num(id->hosts);
+ char *name;
+
+ if (id->peername != NULL) {
+ OPENSSL_free(id->peername);
+ id->peername = NULL;
+ }
+ for (i = 0; i < n; ++i) {
+ name = sk_OPENSSL_STRING_value(id->hosts, i);
+ if (X509_check_host(x, name, 0, id->hostflags, &id->peername) > 0)
+ return 1;
+ }
+ return n == 0;
+}
+
+static int check_id(X509_STORE_CTX *ctx)
+{
+ X509_VERIFY_PARAM *vpm = ctx->param;
+ X509_VERIFY_PARAM_ID *id = vpm->id;
+ X509 *x = ctx->cert;
+ if (id->hosts && check_hosts(x, id) <= 0) {
+ if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
+ return 0;
+ }
+ if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
+ if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
+ return 0;
+ }
+ if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
+ if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
+ return 0;
+ }
+ return 1;
+}
+
+static int check_trust(X509_STORE_CTX *ctx)
+{
+ int i, ok;
+ X509 *x = NULL;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+ cb = ctx->verify_cb;
+ /* Check all trusted certificates in chain */
+ for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
+ x = sk_X509_value(ctx->chain, i);
+ ok = X509_check_trust(x, ctx->param->trust, 0);
+ /* If explicitly trusted return trusted */
+ if (ok == X509_TRUST_TRUSTED)
+ return X509_TRUST_TRUSTED;
+ /*
+ * If explicitly rejected notify callback and reject if not
+ * overridden.
+ */
+ if (ok == X509_TRUST_REJECTED) {
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ctx->error = X509_V_ERR_CERT_REJECTED;
+ ok = cb(0, ctx);
+ if (!ok)
+ return X509_TRUST_REJECTED;
+ }
+ }
+ /*
+ * If we accept partial chains and have at least one trusted certificate
+ * return success.
+ */
+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+ X509 *mx;
+ if (ctx->last_untrusted < sk_X509_num(ctx->chain))
+ return X509_TRUST_TRUSTED;
+ x = sk_X509_value(ctx->chain, 0);
+ mx = lookup_cert_match(ctx, x);
+ if (mx) {
+ (void)sk_X509_set(ctx->chain, 0, mx);
+ X509_free(x);
+ ctx->last_untrusted = 0;
+ return X509_TRUST_TRUSTED;
+ }
+ }
+
+ /*
+ * If no trusted certs in chain at all return untrusted and allow
+ * standard (no issuer cert) etc errors to be indicated.
+ */
+ return X509_TRUST_UNTRUSTED;
+}
+
+static int check_revocation(X509_STORE_CTX *ctx)
+{
+ int i, last, ok;
+ if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
+ return 1;
+ 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;
+ ok = check_cert(ctx);
+ if (!ok)
+ return ok;
+ }
+ return 1;
+}
+
+static int check_cert(X509_STORE_CTX *ctx)
+{
+ X509_CRL *crl = NULL, *dcrl = NULL;
+ X509 *x;
+ int ok, cnum;
+ unsigned int last_reasons;
+ cnum = ctx->error_depth;
+ x = sk_X509_value(ctx->chain, cnum);
+ ctx->current_cert = x;
+ ctx->current_issuer = NULL;
+ ctx->current_crl_score = 0;
+ ctx->current_reasons = 0;
+ while (ctx->current_reasons != CRLDP_ALL_REASONS) {
+ last_reasons = ctx->current_reasons;
+ /* 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;
+ /*
+ * If reasons not updated we wont get anywhere by another iteration,
+ * so exit loop.
+ */
+ if (last_reasons == ctx->current_reasons) {
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+ ok = ctx->verify_cb(0, ctx);
+ goto err;
+ }
+ }
+ err:
+ X509_CRL_free(crl);
+ X509_CRL_free(dcrl);
+
+ ctx->current_crl = NULL;
+ return ok;
+
+}
+
+/* Check CRL times against values in X509_STORE_CTX */
+
+static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
+{
+ time_t *ptime;
+ int i;
+ if (notify)
+ ctx->current_crl = crl;
+ if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+ ptime = &ctx->param->check_time;
+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+ return 1;
+ else
+ ptime = NULL;
+
+ 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 (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (i > 0) {
+ if (!notify)
+ return 0;
+ ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (X509_CRL_get_nextUpdate(crl)) {
+ i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
+
+ if (i == 0) {
+ if (!notify)
+ return 0;
+ ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
+ if (!ctx->verify_cb(0, ctx))
+ return 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 (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ }
+
+ if (notify)
+ ctx->current_crl = NULL;
+
+ return 1;
+}
+
+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, 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);
+ reasons = *preasons;
+ crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
+
+ if (crl_score > best_score) {
+ best_crl = crl;
+ best_crl_issuer = crl_issuer;
+ best_score = crl_score;
+ best_reasons = reasons;
+ }
+ }
+
+ if (best_crl) {
+ if (*pcrl)
+ X509_CRL_free(*pcrl);
+ *pcrl = best_crl;
+ *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;
+}
+
+/*
+ * 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 crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
+{
+ ASN1_OCTET_STRING *exta, *extb;
+ int i;
+ i = X509_CRL_get_ext_by_NID(a, nid, -1);
+ if (i >= 0) {
+ /* 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, -1);
+
+ 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;
+ }
+
+ *preasons = tmp_reasons;
+
+ return crl_score;
+
+}
+
+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 (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
+ *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 */
+
+ 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) {
+ 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 */
+static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
+{
+ X509 *issuer = NULL;
+ EVP_PKEY *ikey = NULL;
+ int ok = 0, chnum, cnum;
+ cnum = ctx->error_depth;
+ chnum = sk_X509_num(ctx->chain) - 1;
+ /* 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.
+ */
+ else if (cnum < chnum)
+ issuer = sk_X509_value(ctx->chain, cnum + 1);
+ else {
+ issuer = sk_X509_value(ctx->chain, chnum);
+ /* If not self signed, can't check signature */
+ if (!ctx->check_issued(ctx, issuer, issuer)) {
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ }
+
+ if (issuer) {
+ /*
+ * Skip most tests for deltas because they have already been done
+ */
+ if (!crl->base_crl_number) {
+ /* 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 */
+ ikey = X509_get_pubkey(issuer);
+
+ if (!ikey) {
+ ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ } else {
+ int rv;
+ rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
+ if (rv != X509_V_OK) {
+ ctx->error = rv;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ /* Verify CRL signature */
+ if (X509_CRL_verify(crl, ikey) <= 0) {
+ ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ }
+ }
+
+ ok = 1;
+
+ err:
+ EVP_PKEY_free(ikey);
+ return ok;
+}
+
+/* Check certificate against CRL */
+static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
+{
+ 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 (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+ && (crl->flags & EXFLAG_CRITICAL)) {
+ ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ return 0;
+ }
+ /*
+ * Look for serial number of certificate in CRL If found make sure reason
+ * is not removeFromCRL.
+ */
+ 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;
+ }
+
+ 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) {
+ X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ /* Invalid or inconsistent extensions */
+ if (ret == -1) {
+ /*
+ * Locate certificates with bad extensions and notify callback.
+ */
+ X509 *x;
+ int i;
+ for (i = 1; i < sk_X509_num(ctx->chain); i++) {
+ x = sk_X509_value(ctx->chain, i);
+ if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
+ continue;
+ ctx->current_cert = x;
+ ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ return 1;
+ }
+ if (ret == -2) {
+ ctx->current_cert = NULL;
+ ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
+ return ctx->verify_cb(0, ctx);
+ }
+
+ if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
+ ctx->current_cert = NULL;
+ ctx->error = X509_V_OK;
+ if (!ctx->verify_cb(2, ctx))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
+{
+ time_t *ptime;
+ int i;
+
+ if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+ ptime = &ctx->param->check_time;
+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+ return 1;
+ else
+ ptime = NULL;
+
+ i = X509_cmp_time(X509_get_notBefore(x), ptime);
+ if (i == 0) {
+ ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (i > 0) {
+ ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ i = X509_cmp_time(X509_get_notAfter(x), ptime);
+ if (i == 0) {
+ ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (i < 0) {
+ ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int internal_verify(X509_STORE_CTX *ctx)
+{
+ int ok = 0, n;
+ X509 *xs, *xi;
+ EVP_PKEY *pkey = NULL;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+
+ cb = ctx->verify_cb;
+
+ n = sk_X509_num(ctx->chain);
+ ctx->error_depth = n - 1;
+ n--;
+ xi = sk_X509_value(ctx->chain, n);
+
+ if (ctx->check_issued(ctx, xi, xi))
+ xs = xi;
+ else {
+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+ xs = xi;
+ goto check_cert;
+ }
+ if (n <= 0) {
+ ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
+ ctx->current_cert = xi;
+ ok = cb(0, ctx);
+ goto end;
+ } else {
+ n--;
+ ctx->error_depth = n;
+ xs = sk_X509_value(ctx->chain, n);
+ }
+ }
+
+/* ctx->error=0; not needed */
+ while (n >= 0) {
+ ctx->error_depth = n;
+
+ /*
+ * Skip signature check for self signed certificates unless
+ * explicitly asked for. It doesn't add any security and just wastes
+ * time.
+ */
+ if (!xs->valid
+ && (xs != xi
+ || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
+ if ((pkey = X509_get_pubkey(xi)) == NULL) {
+ ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+ ctx->current_cert = xi;
+ ok = (*cb) (0, ctx);
+ if (!ok)
+ goto end;
+ } else if (X509_verify(xs, pkey) <= 0) {
+ ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
+ ctx->current_cert = xs;
+ ok = (*cb) (0, ctx);
+ if (!ok) {
+ EVP_PKEY_free(pkey);
+ goto end;
+ }
+ }
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ }
+
+ xs->valid = 1;
+
+ check_cert:
+ ok = check_cert_time(ctx, xs);
+ if (!ok)
+ goto end;
+
+ /* The last error (if any) is still in the error value */
+ ctx->current_issuer = xi;
+ ctx->current_cert = xs;
+ ok = (*cb) (1, ctx);
+ if (!ok)
+ goto end;
+
+ n--;
+ if (n >= 0) {
+ xi = xs;
+ xs = sk_X509_value(ctx->chain, n);
+ }
+ }
+ ok = 1;
+ end:
+ return ok;
+}
+
+int X509_cmp_current_time(const ASN1_TIME *ctm)
+{
+ return X509_cmp_time(ctm, NULL);
+}
+
+int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
+{
+ char *str;
+ ASN1_TIME atm;
+ long offset;
+ char buff1[24], buff2[24], *p;
+ int i, j, remaining;
+
+ p = buff1;
+ remaining = ctm->length;
+ str = (char *)ctm->data;
+ /*
+ * Note that the following (historical) code allows much more slack in the
+ * time format than RFC5280. In RFC5280, the representation is fixed:
+ * UTCTime: YYMMDDHHMMSSZ
+ * GeneralizedTime: YYYYMMDDHHMMSSZ
+ */
+ if (ctm->type == V_ASN1_UTCTIME) {
+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+ int min_length = sizeof("YYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
+ memcpy(p, str, 10);
+ p += 10;
+ str += 10;
+ remaining -= 10;
+ } else {
+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
+ memcpy(p, str, 12);
+ p += 12;
+ str += 12;
+ remaining -= 12;
+ }
+
+ if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
+ *(p++) = '0';
+ *(p++) = '0';
+ } else {
+ /* SS (seconds) */
+ if (remaining < 2)
+ return 0;
+ *(p++) = *(str++);
+ *(p++) = *(str++);
+ remaining -= 2;
+ /*
+ * Skip any (up to three) fractional seconds...
+ * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+ * Can we just kill them altogether?
+ */
+ if (remaining && *str == '.') {
+ str++;
+ remaining--;
+ for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
+ if (*str < '0' || *str > '9')
+ break;
+ }
+ }
+
+ }
+ *(p++) = 'Z';
+ *(p++) = '\0';
+
+ /* We now need either a terminating 'Z' or an offset. */
+ if (!remaining)
+ return 0;
+ if (*str == 'Z') {
+ if (remaining != 1)
+ return 0;
+ offset = 0;
+ } else {
+ /* (+-)HHMM */
+ if ((*str != '+') && (*str != '-'))
+ return 0;
+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+ if (remaining != 5)
+ return 0;
+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+ return 0;
+ offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
+ offset += (str[3] - '0') * 10 + (str[4] - '0');
+ if (*str == '-')
+ offset = -offset;
+ }
+ atm.type = ctm->type;
+ atm.flags = 0;
+ atm.length = sizeof(buff2);
+ atm.data = (unsigned char *)buff2;
+
+ if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
+ return 0;
+
+ if (ctm->type == V_ASN1_UTCTIME) {
+ i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
+ if (i < 50)
+ i += 100; /* cf. RFC 2459 */
+ j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
+ if (j < 50)
+ j += 100;
+
+ if (i < j)
+ return -1;
+ if (i > j)
+ return 1;
+ }
+ i = strcmp(buff1, buff2);
+ if (i == 0) /* wait a second then return younger :-) */
+ return -1;
+ else
+ return i;
+}
+
+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 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;
+
+ if (in_tm)
+ t = *in_tm;
+ else
+ time(&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)
+{
+ EVP_PKEY *ktmp = NULL, *ktmp2;
+ int i, j;
+
+ if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
+ return 1;
+
+ for (i = 0; i < sk_X509_num(chain); i++) {
+ ktmp = X509_get_pubkey(sk_X509_value(chain, i));
+ if (ktmp == NULL) {
+ X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
+ X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
+ return 0;
+ }
+ if (!EVP_PKEY_missing_parameters(ktmp))
+ break;
+ else {
+ EVP_PKEY_free(ktmp);
+ ktmp = NULL;
+ }
+ }
+ if (ktmp == NULL) {
+ X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
+ X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
+ return 0;
+ }
+
+ /* first, populate the other certs */
+ for (j = i - 1; j >= 0; j--) {
+ ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
+ EVP_PKEY_copy_parameters(ktmp2, ktmp);
+ EVP_PKEY_free(ktmp2);
+ }
+
+ if (pkey != NULL)
+ EVP_PKEY_copy_parameters(pkey, ktmp);
+ EVP_PKEY_free(ktmp);
+ return 1;
+}
+
+/* Make a delta CRL as the diff between two full CRLs */
+
+X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
+ EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
+{
+ X509_CRL *crl = NULL;
+ int i;
+ STACK_OF(X509_REVOKED) *revs = NULL;
+ /* CRLs can't be delta already */
+ if (base->base_crl_number || newer->base_crl_number) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_ALREADY_DELTA);
+ return NULL;
+ }
+ /* Base and new CRL must have a CRL number */
+ if (!base->crl_number || !newer->crl_number) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_NO_CRL_NUMBER);
+ return NULL;
+ }
+ /* Issuer names must match */
+ if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_ISSUER_MISMATCH);
+ return NULL;
+ }
+ /* AKID and IDP must match */
+ if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_AKID_MISMATCH);
+ return NULL;
+ }
+ if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_IDP_MISMATCH);
+ return NULL;
+ }
+ /* Newer CRL number must exceed full CRL number */
+ if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_NEWER_CRL_NOT_NEWER);
+ return NULL;
+ }
+ /* CRLs must verify */
+ if (skey && (X509_CRL_verify(base, skey) <= 0 ||
+ X509_CRL_verify(newer, skey) <= 0)) {
+ X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_VERIFY_FAILURE);
+ return NULL;
+ }
+ /* Create new CRL */
+ crl = X509_CRL_new();
+ if (!crl || !X509_CRL_set_version(crl, 1))
+ goto memerr;
+ /* Set issuer name */
+ if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
+ goto memerr;
+
+ if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
+ goto memerr;
+ if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
+ goto memerr;
+
+ /* Set base CRL number: must be critical */
+
+ if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
+ goto memerr;
+
+ /*
+ * Copy extensions across from newest CRL to delta: this will set CRL
+ * number to correct value too.
+ */
+
+ for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
+ X509_EXTENSION *ext;
+ ext = X509_CRL_get_ext(newer, i);
+ if (!X509_CRL_add_ext(crl, ext, -1))
+ goto memerr;
+ }
+
+ /* Go through revoked entries, copying as needed */
+
+ revs = X509_CRL_get_REVOKED(newer);
+
+ for (i = 0; i < sk_X509_REVOKED_num(revs); i++) {
+ X509_REVOKED *rvn, *rvtmp;
+ rvn = sk_X509_REVOKED_value(revs, i);
+ /*
+ * Add only if not also in base. TODO: need something cleverer here
+ * for some more complex CRLs covering multiple CAs.
+ */
+ if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
+ rvtmp = X509_REVOKED_dup(rvn);
+ if (!rvtmp)
+ goto memerr;
+ if (!X509_CRL_add0_revoked(crl, rvtmp)) {
+ X509_REVOKED_free(rvtmp);
+ goto memerr;
+ }
+ }
+ }
+ /* TODO: optionally prune deleted entries */
+
+ if (skey && md && !X509_CRL_sign(crl, skey, md))
+ goto memerr;
+
+ return crl;
+
+ memerr:
+ X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE);
+ if (crl)
+ X509_CRL_free(crl);
+ return NULL;
+}
+
+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)
+{
+ /*
+ * This function is (usually) called only once, by
+ * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
+ */
+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
+{
+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+}
+
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
+{
+ return CRYPTO_get_ex_data(&ctx->ex_data, idx);
+}
+
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
+{
+ return ctx->error;
+}
+
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
+{
+ ctx->error = err;
+}
+
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
+{
+ return ctx->error_depth;
+}
+
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
+{
+ return ctx->current_cert;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
+{
+ return ctx->chain;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
+{
+ if (!ctx->chain)
+ return NULL;
+ return X509_chain_up_ref(ctx->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;
+}
+
+void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+ ctx->untrusted = sk;
+}
+
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
+{
+ ctx->crls = sk;
+}
+
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
+{
+ return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
+}
+
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
+{
+ return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
+}
+
+/*
+ * This function is used to set the X509_STORE_CTX purpose and trust values.
+ * This is intended to be used when another structure has its own trust and
+ * purpose values which (if set) will be inherited by the ctx. If they aren't
+ * set then we will usually have a default purpose in mind which should then
+ * be used to set the trust value. An example of this is SSL use: an SSL
+ * structure will have its own purpose and trust settings which the
+ * application can set: if they aren't set then we use the default of SSL
+ * client/server.
+ */
+
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+ int purpose, int trust)
+{
+ int idx;
+ /* If purpose not set use default */
+ if (!purpose)
+ purpose = def_purpose;
+ /* If we have a purpose then check it is valid */
+ if (purpose) {
+ X509_PURPOSE *ptmp;
+ idx = X509_PURPOSE_get_by_id(purpose);
+ if (idx == -1) {
+ X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+ X509_R_UNKNOWN_PURPOSE_ID);
+ return 0;
+ }
+ ptmp = X509_PURPOSE_get0(idx);
+ if (ptmp->trust == X509_TRUST_DEFAULT) {
+ idx = X509_PURPOSE_get_by_id(def_purpose);
+ if (idx == -1) {
+ X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+ X509_R_UNKNOWN_PURPOSE_ID);
+ return 0;
+ }
+ ptmp = X509_PURPOSE_get0(idx);
+ }
+ /* If trust not set then get from purpose default */
+ if (!trust)
+ trust = ptmp->trust;
+ }
+ if (trust) {
+ idx = X509_TRUST_get_by_id(trust);
+ if (idx == -1) {
+ X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+ X509_R_UNKNOWN_TRUST_ID);
+ return 0;
+ }
+ }
+
+ if (purpose && !ctx->param->purpose)
+ ctx->param->purpose = purpose;
+ if (trust && !ctx->param->trust)
+ ctx->param->trust = trust;
+ return 1;
+}
+
+X509_STORE_CTX *X509_STORE_CTX_new(void)
+{
+ X509_STORE_CTX *ctx;
+ ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
+ if (!ctx) {
+ X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memset(ctx, 0, sizeof(X509_STORE_CTX));
+ return ctx;
+}
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
+{
+ if (!ctx)
+ return;
+ X509_STORE_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
+ STACK_OF(X509) *chain)
+{
+ int ret = 1;
+ ctx->ctx = store;
+ ctx->current_method = 0;
+ ctx->cert = x509;
+ ctx->untrusted = chain;
+ ctx->crls = NULL;
+ ctx->last_untrusted = 0;
+ ctx->other_ctx = NULL;
+ ctx->valid = 0;
+ ctx->chain = NULL;
+ ctx->error = 0;
+ ctx->explicit_policy = 0;
+ ctx->error_depth = 0;
+ ctx->current_cert = NULL;
+ ctx->current_issuer = NULL;
+ ctx->current_crl = NULL;
+ ctx->current_crl_score = 0;
+ ctx->current_reasons = 0;
+ ctx->tree = NULL;
+ ctx->parent = NULL;
+ /* Zero ex_data to make sure we're cleanup-safe */
+ memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
+
+ ctx->param = X509_VERIFY_PARAM_new();
+ if (!ctx->param) {
+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ /*
+ * Inherit callbacks and flags from X509_STORE if not set use defaults.
+ */
+ if (store)
+ ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
+ else
+ ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
+
+ if (store) {
+ ctx->verify_cb = store->verify_cb;
+ /* Seems to always be 0 in OpenSSL, else must be idempotent */
+ ctx->cleanup = store->cleanup;
+ } else
+ ctx->cleanup = 0;
+
+ if (ret)
+ ret = X509_VERIFY_PARAM_inherit(ctx->param,
+ X509_VERIFY_PARAM_lookup("default"));
+
+ if (ret == 0) {
+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (store && store->check_issued)
+ ctx->check_issued = store->check_issued;
+ else
+ ctx->check_issued = check_issued;
+
+ if (store && store->get_issuer)
+ ctx->get_issuer = store->get_issuer;
+ else
+ ctx->get_issuer = X509_STORE_CTX_get1_issuer;
+
+ if (store && store->verify_cb)
+ ctx->verify_cb = store->verify_cb;
+ else
+ ctx->verify_cb = null_callback;
+
+ if (store && store->verify)
+ ctx->verify = store->verify;
+ else
+ ctx->verify = internal_verify;
+
+ if (store && store->check_revocation)
+ ctx->check_revocation = store->check_revocation;
+ else
+ ctx->check_revocation = check_revocation;
+
+ if (store && store->get_crl)
+ ctx->get_crl = store->get_crl;
+ else
+ ctx->get_crl = NULL;
+
+ if (store && store->check_crl)
+ ctx->check_crl = store->check_crl;
+ else
+ ctx->check_crl = check_crl;
+
+ if (store && store->cert_crl)
+ ctx->cert_crl = store->cert_crl;
+ 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;
+
+ if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
+ &ctx->ex_data))
+ return 1;
+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+
+ err:
+ /*
+ * On error clean up allocated storage, if the store context was not
+ * allocated with X509_STORE_CTX_new() this is our last chance to do so.
+ */
+ X509_STORE_CTX_cleanup(ctx);
+ return 0;
+}
+
+/*
+ * Set alternative lookup method: just a STACK of trusted certificates. This
+ * avoids X509_STORE nastiness where it isn't needed.
+ */
+
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+ ctx->other_ctx = sk;
+ ctx->get_issuer = get_issuer_sk;
+}
+
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
+{
+ /*
+ * We need to be idempotent because, unfortunately, free() also calls
+ * cleanup(), so the natural call sequence new(), init(), cleanup(), free()
+ * calls cleanup() for the same object twice! Thus we must zero the
+ * pointers below after they're freed!
+ */
+ /* Seems to always be 0 in OpenSSL, do this at most once. */
+ if (ctx->cleanup != NULL) {
+ ctx->cleanup(ctx);
+ ctx->cleanup = NULL;
+ }
+ if (ctx->param != NULL) {
+ if (ctx->parent == NULL)
+ X509_VERIFY_PARAM_free(ctx->param);
+ ctx->param = NULL;
+ }
+ if (ctx->tree != NULL) {
+ X509_policy_tree_free(ctx->tree);
+ ctx->tree = NULL;
+ }
+ if (ctx->chain != NULL) {
+ sk_X509_pop_free(ctx->chain, X509_free);
+ ctx->chain = NULL;
+ }
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
+ memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
+}
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
+{
+ X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+}
+
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
+{
+ X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
+
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+ time_t t)
+{
+ X509_VERIFY_PARAM_set_time(ctx->param, t);
+}
+
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+ int (*verify_cb) (int, X509_STORE_CTX *))
+{
+ ctx->verify_cb = verify_cb;
+}
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
+{
+ return ctx->tree;
+}
+
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
+{
+ return ctx->explicit_policy;
+}
+
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
+{
+ const X509_VERIFY_PARAM *param;
+ param = X509_VERIFY_PARAM_lookup(name);
+ if (!param)
+ return 0;
+ return X509_VERIFY_PARAM_inherit(ctx->param, param);
+}
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
+{
+ return ctx->param;
+}
+
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
+{
+ if (ctx->param)
+ X509_VERIFY_PARAM_free(ctx->param);
+ ctx->param = param;
+}
+
+IMPLEMENT_STACK_OF(X509)
+
+IMPLEMENT_ASN1_SET_OF(X509)
+
+IMPLEMENT_STACK_OF(X509_NAME)
+
+IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
+
+IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c b/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c
new file mode 100644
index 00000000..1ac15a88
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c
@@ -0,0 +1,662 @@
+/* x509_vpm.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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 <stdio.h>
+
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "vpm_int.h"
+
+/* X509_VERIFY_PARAM functions */
+
+#define SET_HOST 0
+#define ADD_HOST 1
+
+static char *str_copy(const char *s)
+{
+ return OPENSSL_strdup(s);
+}
+
+static void str_free(char *s)
+{
+ OPENSSL_free(s);
+}
+
+#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
+
+static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
+ const char *name, size_t namelen)
+{
+ char *copy;
+
+ /*
+ * Refuse names with embedded NUL bytes, except perhaps as final byte.
+ * XXX: Do we need to push an error onto the error stack?
+ */
+ if (namelen == 0 || name == NULL)
+ namelen = name ? strlen(name) : 0;
+ else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen))
+ return 0;
+ if (namelen > 0 && name[namelen - 1] == '\0')
+ --namelen;
+
+ if (mode == SET_HOST && id->hosts) {
+ string_stack_free(id->hosts);
+ id->hosts = NULL;
+ }
+ if (name == NULL || namelen == 0)
+ return 1;
+
+ copy = BUF_strndup(name, namelen);
+ if (copy == NULL)
+ return 0;
+
+ if (id->hosts == NULL &&
+ (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
+ OPENSSL_free(copy);
+ return 0;
+ }
+
+ if (!sk_OPENSSL_STRING_push(id->hosts, copy)) {
+ OPENSSL_free(copy);
+ if (sk_OPENSSL_STRING_num(id->hosts) == 0) {
+ sk_OPENSSL_STRING_free(id->hosts);
+ id->hosts = NULL;
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
+{
+ X509_VERIFY_PARAM_ID *paramid;
+ if (!param)
+ return;
+ 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;
+ if (param->policies) {
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+ param->policies = NULL;
+ }
+ paramid = param->id;
+ if (paramid->hosts) {
+ string_stack_free(paramid->hosts);
+ paramid->hosts = NULL;
+ }
+ if (paramid->peername)
+ OPENSSL_free(paramid->peername);
+ paramid->peername = NULL;
+ if (paramid->email) {
+ OPENSSL_free(paramid->email);
+ paramid->email = NULL;
+ paramid->emaillen = 0;
+ }
+ if (paramid->ip) {
+ OPENSSL_free(paramid->ip);
+ paramid->ip = NULL;
+ paramid->iplen = 0;
+ }
+}
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
+{
+ X509_VERIFY_PARAM *param;
+ X509_VERIFY_PARAM_ID *paramid;
+
+ param = OPENSSL_malloc(sizeof *param);
+ if (!param)
+ return NULL;
+ memset(param, 0, sizeof(*param));
+
+ paramid = OPENSSL_malloc(sizeof(*paramid));
+ if (!paramid) {
+ OPENSSL_free(param);
+ return NULL;
+ }
+ memset(paramid, 0, sizeof(*paramid));
+ /* Exotic platforms may have non-zero bit representation of NULL */
+ paramid->hosts = NULL;
+ paramid->peername = NULL;
+ paramid->email = NULL;
+ paramid->ip = NULL;
+
+ param->id = paramid;
+ x509_verify_param_zero(param);
+ return param;
+}
+
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
+{
+ if (param == NULL)
+ return;
+ x509_verify_param_zero(param);
+ OPENSSL_free(param->id);
+ OPENSSL_free(param);
+}
+
+/*-
+ * This function determines how parameters are "inherited" from one structure
+ * to another. There are several different ways this can happen.
+ *
+ * 1. If a child structure needs to have its values initialized from a parent
+ * they are simply copied across. For example SSL_CTX copied to SSL.
+ * 2. If the structure should take on values only if they are currently unset.
+ * For example the values in an SSL structure will take appropriate value
+ * for SSL servers or clients but only if the application has not set new
+ * ones.
+ *
+ * The "inh_flags" field determines how this function behaves.
+ *
+ * Normally any values which are set in the default are not copied from the
+ * destination and verify flags are ORed together.
+ *
+ * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
+ * to the destination. Effectively the values in "to" become default values
+ * which will be used only if nothing new is set in "from".
+ *
+ * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
+ * they are set or not. Flags is still Ored though.
+ *
+ * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
+ * of ORed.
+ *
+ * If X509_VP_FLAG_LOCKED is set then no values are copied.
+ *
+ * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
+ * after the next call.
+ */
+
+/* Macro to test if a field should be copied from src to dest */
+
+#define test_x509_verify_param_copy(field, def) \
+ (to_overwrite || \
+ ((src->field != def) && (to_default || (dest->field == def))))
+
+/* As above but for ID fields */
+
+#define test_x509_verify_param_copy_id(idf, def) \
+ test_x509_verify_param_copy(id->idf, def)
+
+/* Macro to test and copy a field if necessary */
+
+#define x509_verify_param_copy(field, def) \
+ if (test_x509_verify_param_copy(field, def)) \
+ dest->field = src->field
+
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
+ const X509_VERIFY_PARAM *src)
+{
+ unsigned long inh_flags;
+ int to_default, to_overwrite;
+ X509_VERIFY_PARAM_ID *id;
+ if (!src)
+ return 1;
+ id = src->id;
+ inh_flags = dest->inh_flags | src->inh_flags;
+
+ if (inh_flags & X509_VP_FLAG_ONCE)
+ dest->inh_flags = 0;
+
+ if (inh_flags & X509_VP_FLAG_LOCKED)
+ return 1;
+
+ if (inh_flags & X509_VP_FLAG_DEFAULT)
+ to_default = 1;
+ else
+ to_default = 0;
+
+ if (inh_flags & X509_VP_FLAG_OVERWRITE)
+ to_overwrite = 1;
+ else
+ to_overwrite = 0;
+
+ x509_verify_param_copy(purpose, 0);
+ x509_verify_param_copy(trust, 0);
+ x509_verify_param_copy(depth, -1);
+
+ /* If overwrite or check time not set, copy across */
+
+ if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
+ dest->check_time = src->check_time;
+ dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
+ /* Don't need to copy flag: that is done below */
+ }
+
+ if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
+ dest->flags = 0;
+
+ dest->flags |= src->flags;
+
+ if (test_x509_verify_param_copy(policies, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
+ return 0;
+ }
+
+ /* Copy the host flags if and only if we're copying the host list */
+ if (test_x509_verify_param_copy_id(hosts, NULL)) {
+ if (dest->id->hosts) {
+ string_stack_free(dest->id->hosts);
+ dest->id->hosts = NULL;
+ }
+ if (id->hosts) {
+ dest->id->hosts =
+ sk_OPENSSL_STRING_deep_copy(id->hosts, str_copy, str_free);
+ if (dest->id->hosts == NULL)
+ return 0;
+ dest->id->hostflags = id->hostflags;
+ }
+ }
+
+ if (test_x509_verify_param_copy_id(email, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
+ return 0;
+ }
+
+ if (test_x509_verify_param_copy_id(ip, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
+ return 0;
+ }
+
+ return 1;
+}
+
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+ const X509_VERIFY_PARAM *from)
+{
+ unsigned long save_flags = to->inh_flags;
+ int ret;
+ to->inh_flags |= X509_VP_FLAG_DEFAULT;
+ ret = X509_VERIFY_PARAM_inherit(to, from);
+ to->inh_flags = save_flags;
+ return ret;
+}
+
+static int int_x509_param_set1(char **pdest, size_t *pdestlen,
+ const char *src, size_t srclen)
+{
+ void *tmp;
+ if (src) {
+ if (srclen == 0) {
+ tmp = BUF_strdup(src);
+ srclen = strlen(src);
+ } else
+ tmp = BUF_memdup(src, srclen);
+ if (!tmp)
+ return 0;
+ } else {
+ tmp = NULL;
+ srclen = 0;
+ }
+ if (*pdest)
+ OPENSSL_free(*pdest);
+ *pdest = tmp;
+ if (pdestlen)
+ *pdestlen = srclen;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
+{
+ if (param->name)
+ OPENSSL_free(param->name);
+ param->name = BUF_strdup(name);
+ if (param->name)
+ return 1;
+ return 0;
+}
+
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
+{
+ param->flags |= flags;
+ if (flags & X509_V_FLAG_POLICY_MASK)
+ param->flags |= X509_V_FLAG_POLICY_CHECK;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+ unsigned long flags)
+{
+ param->flags &= ~flags;
+ return 1;
+}
+
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
+{
+ return param->flags;
+}
+
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
+{
+ return X509_PURPOSE_set(&param->purpose, purpose);
+}
+
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
+{
+ return X509_TRUST_set(&param->trust, trust);
+}
+
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
+{
+ param->depth = depth;
+}
+
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
+{
+ param->check_time = t;
+ param->flags |= X509_V_FLAG_USE_CHECK_TIME;
+}
+
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+ ASN1_OBJECT *policy)
+{
+ if (!param->policies) {
+ param->policies = sk_ASN1_OBJECT_new_null();
+ if (!param->policies)
+ return 0;
+ }
+ if (!sk_ASN1_OBJECT_push(param->policies, policy))
+ return 0;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+ STACK_OF(ASN1_OBJECT) *policies)
+{
+ int i;
+ ASN1_OBJECT *oid, *doid;
+ if (!param)
+ return 0;
+ if (param->policies)
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+
+ if (!policies) {
+ param->policies = NULL;
+ return 1;
+ }
+
+ param->policies = sk_ASN1_OBJECT_new_null();
+ if (!param->policies)
+ return 0;
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
+ oid = sk_ASN1_OBJECT_value(policies, i);
+ doid = OBJ_dup(oid);
+ if (!doid)
+ return 0;
+ if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
+ ASN1_OBJECT_free(doid);
+ return 0;
+ }
+ }
+ param->flags |= X509_V_FLAG_POLICY_CHECK;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+ const char *name, size_t namelen)
+{
+ return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
+}
+
+int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
+ const char *name, size_t namelen)
+{
+ return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
+}
+
+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+ unsigned int flags)
+{
+ param->id->hostflags = flags;
+}
+
+char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
+{
+ return param->id->peername;
+}
+
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+ const char *email, size_t emaillen)
+{
+ return int_x509_param_set1(&param->id->email, &param->id->emaillen,
+ email, emaillen);
+}
+
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+ const unsigned char *ip, size_t iplen)
+{
+ if (iplen != 0 && iplen != 4 && iplen != 16)
+ return 0;
+ return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
+ (char *)ip, iplen);
+}
+
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
+{
+ unsigned char ipout[16];
+ size_t iplen;
+
+ iplen = (size_t)a2i_ipadd(ipout, ipasc);
+ if (iplen == 0)
+ return 0;
+ return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
+}
+
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
+{
+ return param->depth;
+}
+
+const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
+{
+ return param->name;
+}
+
+static X509_VERIFY_PARAM_ID _empty_id = { NULL, 0U, NULL, NULL, 0, NULL, 0 };
+
+#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
+
+/*
+ * Default verify parameters: these are used for various applications and can
+ * be overridden by the user specified table. NB: the 'name' field *must* be
+ * in alphabetical order because it will be searched using OBJ_search.
+ */
+
+static const X509_VERIFY_PARAM default_table[] = {
+ {
+ "default", /* X509 default parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ 0, /* purpose */
+ 0, /* trust */
+ 100, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ "pkcs7", /* S/MIME sign parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SMIME_SIGN, /* purpose */
+ X509_TRUST_EMAIL, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ "smime_sign", /* S/MIME sign parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SMIME_SIGN, /* purpose */
+ X509_TRUST_EMAIL, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ "ssl_client", /* SSL/TLS client parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SSL_CLIENT, /* purpose */
+ X509_TRUST_SSL_CLIENT, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ "ssl_server", /* SSL/TLS server parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SSL_SERVER, /* purpose */
+ X509_TRUST_SSL_SERVER, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id}
+};
+
+static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
+
+static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
+{
+ 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)
+{
+ return strcmp((*a)->name, (*b)->name);
+}
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
+{
+ int idx;
+ X509_VERIFY_PARAM *ptmp;
+ if (!param_table) {
+ param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
+ if (!param_table)
+ return 0;
+ } else {
+ idx = sk_X509_VERIFY_PARAM_find(param_table, param);
+ if (idx != -1) {
+ ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
+ X509_VERIFY_PARAM_free(ptmp);
+ (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
+ }
+ }
+ if (!sk_X509_VERIFY_PARAM_push(param_table, param))
+ return 0;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_get_count(void)
+{
+ int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ if (param_table)
+ num += sk_X509_VERIFY_PARAM_num(param_table);
+ return num;
+}
+
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
+{
+ int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ if (id < num)
+ return default_table + id;
+ return sk_X509_VERIFY_PARAM_value(param_table, id - num);
+}
+
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
+{
+ int idx;
+ X509_VERIFY_PARAM pm;
+
+ pm.name = (char *)name;
+ if (param_table) {
+ idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
+ if (idx != -1)
+ return sk_X509_VERIFY_PARAM_value(param_table, idx);
+ }
+ return OBJ_bsearch_table(&pm, default_table,
+ sizeof(default_table) /
+ sizeof(X509_VERIFY_PARAM));
+}
+
+void X509_VERIFY_PARAM_table_cleanup(void)
+{
+ if (param_table)
+ sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
+ param_table = NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509cset.c b/Cryptlib/OpenSSL/crypto/x509/x509cset.c
new file mode 100644
index 00000000..24ca35b5
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509cset.c
@@ -0,0 +1,167 @@
+/* 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.
+ *
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+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));
+}
+
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
+{
+ if ((x == NULL) || (x->crl == NULL))
+ return (0);
+ return (X509_NAME_set(&x->crl->issuer, name));
+}
+
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
+{
+ ASN1_TIME *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->crl->lastUpdate;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->crl->lastUpdate);
+ x->crl->lastUpdate = in;
+ }
+ }
+ return (in != NULL);
+}
+
+int X509_CRL_set_nextUpdate(X509_CRL *x, const 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) {
+ M_ASN1_TIME_free(x->crl->nextUpdate);
+ x->crl->nextUpdate = in;
+ }
+ }
+ 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; i < sk_X509_REVOKED_num(c->crl->revoked); i++) {
+ r = sk_X509_REVOKED_value(c->crl->revoked, i);
+ r->sequence = i;
+ }
+ c->crl->enc.modified = 1;
+ return 1;
+}
+
+int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
+{
+ ASN1_TIME *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->revocationDate;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->revocationDate);
+ x->revocationDate = in;
+ }
+ }
+ return (in != NULL);
+}
+
+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) {
+ in = M_ASN1_INTEGER_dup(serial);
+ if (in != NULL) {
+ M_ASN1_INTEGER_free(x->serialNumber);
+ x->serialNumber = in;
+ }
+ }
+ return (in != NULL);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509name.c b/Cryptlib/OpenSSL/crypto/x509/x509name.c
new file mode 100644
index 00000000..6ea601f9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509name.c
@@ -0,0 +1,397 @@
+/* crypto/x509/x509name.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 <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
+{
+ ASN1_OBJECT *obj;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-1);
+ return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
+}
+
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,
+ int len)
+{
+ int i;
+ ASN1_STRING *data;
+
+ i = X509_NAME_get_index_by_OBJ(name, obj, -1);
+ if (i < 0)
+ return (-1);
+ data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+ i = (data->length > (len - 1)) ? (len - 1) : data->length;
+ if (buf == NULL)
+ return (data->length);
+ memcpy(buf, data->data, i);
+ buf[i] = '\0';
+ return (i);
+}
+
+int X509_NAME_entry_count(X509_NAME *name)
+{
+ if (name == NULL)
+ return (0);
+ return (sk_X509_NAME_ENTRY_num(name->entries));
+}
+
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
+{
+ ASN1_OBJECT *obj;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-2);
+ return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
+}
+
+/* NOTE: you should be passsing -1, not 0 as lastpos */
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos)
+{
+ int n;
+ X509_NAME_ENTRY *ne;
+ STACK_OF(X509_NAME_ENTRY) *sk;
+
+ if (name == NULL)
+ return (-1);
+ if (lastpos < 0)
+ lastpos = -1;
+ sk = name->entries;
+ n = sk_X509_NAME_ENTRY_num(sk);
+ for (lastpos++; lastpos < n; lastpos++) {
+ ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
+ if (OBJ_cmp(ne->object, obj) == 0)
+ return (lastpos);
+ }
+ return (-1);
+}
+
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
+{
+ if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
+ || loc < 0)
+ return (NULL);
+ else
+ return (sk_X509_NAME_ENTRY_value(name->entries, loc));
+}
+
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
+{
+ X509_NAME_ENTRY *ret;
+ int i, n, set_prev, set_next;
+ STACK_OF(X509_NAME_ENTRY) *sk;
+
+ if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
+ || loc < 0)
+ return (NULL);
+ sk = name->entries;
+ ret = sk_X509_NAME_ENTRY_delete(sk, loc);
+ n = sk_X509_NAME_ENTRY_num(sk);
+ name->modified = 1;
+ if (loc == n)
+ return (ret);
+
+ /* else we need to fixup the set field */
+ if (loc != 0)
+ set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
+ else
+ set_prev = ret->set - 1;
+ set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+
+ /*-
+ * set_prev is the previous set
+ * set is the current set
+ * set_next is the following
+ * prev 1 1 1 1 1 1 1 1
+ * set 1 1 2 2
+ * next 1 1 2 2 2 2 3 2
+ * so basically only if prev and next differ by 2, then
+ * re-number down by 1
+ */
+ if (set_prev + 1 < set_next)
+ for (i = loc; i < n; i++)
+ sk_X509_NAME_ENTRY_value(sk, i)->set--;
+ return (ret);
+}
+
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+ unsigned char *bytes, int len, int loc,
+ int set)
+{
+ X509_NAME_ENTRY *ne;
+ int ret;
+ ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
+ if (!ne)
+ return 0;
+ ret = X509_NAME_add_entry(name, ne, loc, set);
+ X509_NAME_ENTRY_free(ne);
+ return ret;
+}
+
+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 *ne;
+ int ret;
+ ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
+ if (!ne)
+ return 0;
+ ret = X509_NAME_add_entry(name, ne, loc, set);
+ X509_NAME_ENTRY_free(ne);
+ return ret;
+}
+
+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)
+{
+ X509_NAME_ENTRY *ne;
+ int ret;
+ ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
+ if (!ne)
+ return 0;
+ ret = X509_NAME_add_entry(name, ne, loc, set);
+ X509_NAME_ENTRY_free(ne);
+ return ret;
+}
+
+/*
+ * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
+ * guy we are about to stomp on.
+ */
+int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
+ int set)
+{
+ X509_NAME_ENTRY *new_name = NULL;
+ int n, i, inc;
+ STACK_OF(X509_NAME_ENTRY) *sk;
+
+ if (name == NULL)
+ return (0);
+ sk = name->entries;
+ n = sk_X509_NAME_ENTRY_num(sk);
+ if (loc > n)
+ loc = n;
+ else if (loc < 0)
+ loc = n;
+
+ name->modified = 1;
+
+ if (set == -1) {
+ if (loc == 0) {
+ set = 0;
+ inc = 1;
+ } else {
+ set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
+ inc = 0;
+ }
+ } else { /* if (set >= 0) */
+
+ if (loc >= n) {
+ if (loc != 0)
+ set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
+ else
+ set = 0;
+ } else
+ set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+ inc = (set == 0) ? 1 : 0;
+ }
+
+ if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL)
+ goto err;
+ new_name->set = set;
+ if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
+ X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (inc) {
+ n = sk_X509_NAME_ENTRY_num(sk);
+ for (i = loc + 1; i < n; i++)
+ sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1;
+ }
+ return (1);
+ err:
+ if (new_name != NULL)
+ X509_NAME_ENTRY_free(new_name);
+ return (0);
+}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+ const char *field, int type,
+ const unsigned char *bytes,
+ int len)
+{
+ ASN1_OBJECT *obj;
+ X509_NAME_ENTRY *nentry;
+
+ obj = OBJ_txt2obj(field, 0);
+ if (obj == NULL) {
+ X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
+ X509_R_INVALID_FIELD_NAME);
+ ERR_add_error_data(2, "name=", field);
+ return (NULL);
+ }
+ nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+ ASN1_OBJECT_free(obj);
+ return nentry;
+}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+ int type, unsigned char *bytes,
+ int len)
+{
+ ASN1_OBJECT *obj;
+ X509_NAME_ENTRY *nentry;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL) {
+ X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+ ASN1_OBJECT_free(obj);
+ return nentry;
+}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+ ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes,
+ int len)
+{
+ X509_NAME_ENTRY *ret;
+
+ if ((ne == NULL) || (*ne == NULL)) {
+ if ((ret = X509_NAME_ENTRY_new()) == NULL)
+ return (NULL);
+ } else
+ ret = *ne;
+
+ if (!X509_NAME_ENTRY_set_object(ret, obj))
+ goto err;
+ if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
+ goto err;
+
+ if ((ne != NULL) && (*ne == NULL))
+ *ne = ret;
+ return (ret);
+ err:
+ if ((ne == NULL) || (ret != *ne))
+ X509_NAME_ENTRY_free(ret);
+ return (NULL);
+}
+
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
+{
+ if ((ne == NULL) || (obj == NULL)) {
+ X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ ASN1_OBJECT_free(ne->object);
+ ne->object = OBJ_dup(obj);
+ return ((ne->object == NULL) ? 0 : 1);
+}
+
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+ const unsigned char *bytes, int len)
+{
+ int i;
+
+ if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
+ return (0);
+ if ((type > 0) && (type & MBSTRING_FLAG))
+ return ASN1_STRING_set_by_NID(&ne->value, bytes,
+ len, type,
+ OBJ_obj2nid(ne->object)) ? 1 : 0;
+ 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) {
+ if (type == V_ASN1_APP_CHOOSE)
+ ne->value->type = ASN1_PRINTABLE_type(bytes, len);
+ else
+ ne->value->type = type;
+ }
+ return (1);
+}
+
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
+{
+ if (ne == NULL)
+ return (NULL);
+ return (ne->object);
+}
+
+ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
+{
+ if (ne == NULL)
+ return (NULL);
+ return (ne->value);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509rset.c b/Cryptlib/OpenSSL/crypto/x509/x509rset.c
new file mode 100644
index 00000000..80e273e6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509rset.c
@@ -0,0 +1,85 @@
+/* crypto/x509/x509rset.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_REQ_set_version(X509_REQ *x, long version)
+{
+ if (x == NULL)
+ return (0);
+ return (ASN1_INTEGER_set(x->req_info->version, version));
+}
+
+int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
+{
+ if ((x == NULL) || (x->req_info == NULL))
+ return (0);
+ return (X509_NAME_set(&x->req_info->subject, name));
+}
+
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
+{
+ if ((x == NULL) || (x->req_info == NULL))
+ return (0);
+ return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509spki.c b/Cryptlib/OpenSSL/crypto/x509/x509spki.c
new file mode 100644
index 00000000..2df84ead
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509spki.c
@@ -0,0 +1,123 @@
+/* x509spki.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
+{
+ if ((x == NULL) || (x->spkac == NULL))
+ return (0);
+ return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey));
+}
+
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
+{
+ if ((x == NULL) || (x->spkac == NULL))
+ return (NULL);
+ return (X509_PUBKEY_get(x->spkac->pubkey));
+}
+
+/* Load a Netscape SPKI from a base64 encoded string */
+
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len)
+{
+ unsigned char *spki_der;
+ const unsigned char *p;
+ int spki_len;
+ NETSCAPE_SPKI *spki;
+ if (len <= 0)
+ len = strlen(str);
+ if (!(spki_der = OPENSSL_malloc(len + 1))) {
+ X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
+ if (spki_len < 0) {
+ X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR);
+ OPENSSL_free(spki_der);
+ return NULL;
+ }
+ p = spki_der;
+ spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
+ OPENSSL_free(spki_der);
+ return spki;
+}
+
+/* Generate a base64 encoded string from an SPKI */
+
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
+{
+ unsigned char *der_spki, *p;
+ char *b64_str;
+ int der_len;
+ der_len = i2d_NETSCAPE_SPKI(spki, NULL);
+ der_spki = OPENSSL_malloc(der_len);
+ b64_str = OPENSSL_malloc(der_len * 2);
+ if (!der_spki || !b64_str) {
+ X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ p = der_spki;
+ i2d_NETSCAPE_SPKI(spki, &p);
+ EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
+ OPENSSL_free(der_spki);
+ return b64_str;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509type.c b/Cryptlib/OpenSSL/crypto/x509/x509type.c
new file mode 100644
index 00000000..9219f753
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x509type.c
@@ -0,0 +1,127 @@
+/* crypto/x509/x509type.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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
+{
+ EVP_PKEY *pk;
+ int ret = 0, i;
+
+ if (x == NULL)
+ return (0);
+
+ if (pkey == NULL)
+ pk = X509_get_pubkey(x);
+ else
+ pk = pkey;
+
+ if (pk == NULL)
+ return (0);
+
+ switch (pk->type) {
+ case EVP_PKEY_RSA:
+ ret = EVP_PK_RSA | EVP_PKT_SIGN;
+/* if (!sign only extension) */
+ ret |= EVP_PKT_ENC;
+ break;
+ case EVP_PKEY_DSA:
+ ret = EVP_PK_DSA | EVP_PKT_SIGN;
+ break;
+ case EVP_PKEY_EC:
+ ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
+ 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;
+ }
+
+ i = OBJ_obj2nid(x->sig_alg->algorithm);
+ if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
+
+ switch (i) {
+ case NID_rsaEncryption:
+ case NID_rsa:
+ ret |= EVP_PKS_RSA;
+ break;
+ case NID_dsa:
+ case NID_dsa_2:
+ ret |= EVP_PKS_DSA;
+ break;
+ case NID_X9_62_id_ecPublicKey:
+ ret |= EVP_PKS_EC;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (pkey == NULL)
+ EVP_PKEY_free(pk);
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x_all.c b/Cryptlib/OpenSSL/crypto/x509/x_all.c
new file mode 100644
index 00000000..0f26c546
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509/x_all.c
@@ -0,0 +1,558 @@
+/* crypto/x509/x_all.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 <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+int X509_verify(X509 *a, EVP_PKEY *r)
+{
+ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+ return 0;
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg,
+ a->signature, a->cert_info, r));
+}
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
+{
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
+ a->sig_alg, a->signature, a->req_info, r));
+}
+
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
+{
+ return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
+ a->sig_algor, a->signature, a->spkac, r));
+}
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+ x->cert_info->enc.modified = 1;
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
+ x->sig_alg, x->signature, x->cert_info, pkey, md));
+}
+
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
+{
+ x->cert_info->enc.modified = 1;
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
+ x->cert_info->signature,
+ x->sig_alg, x->signature, x->cert_info, ctx);
+}
+
+int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert)
+{
+ return OCSP_REQ_CTX_nbio_d2i(rctx,
+ (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509));
+}
+
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL,
+ x->signature, x->req_info, pkey, md));
+}
+
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
+{
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+ x->sig_alg, NULL, x->signature, x->req_info,
+ ctx);
+}
+
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+ x->crl->enc.modified = 1;
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
+ x->sig_alg, x->signature, x->crl, pkey, md));
+}
+
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
+{
+ x->crl->enc.modified = 1;
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
+ x->crl->sig_alg, x->sig_alg, x->signature,
+ x->crl, ctx);
+}
+
+int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl)
+{
+ return OCSP_REQ_CTX_nbio_d2i(rctx,
+ (ASN1_VALUE **)pcrl,
+ ASN1_ITEM_rptr(X509_CRL));
+}
+
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+ return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL,
+ x->signature, x->spkac, pkey, md));
+}
+
+#ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
+
+int i2d_X509_fp(FILE *fp, X509 *x509)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
+#endif
+
+X509 *d2i_X509_bio(BIO *bp, X509 **x509)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
+
+int i2d_X509_bio(BIO *bp, X509 *x509)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
+
+#ifndef OPENSSL_NO_FP_API
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
+
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
+#endif
+
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
+
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
+
+#ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+}
+
+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+}
+#endif
+
+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+}
+
+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+}
+
+#ifndef OPENSSL_NO_FP_API
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
+
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
+#endif
+
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
+
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
+
+#ifndef OPENSSL_NO_RSA
+
+# ifndef OPENSSL_NO_FP_API
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+}
+
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+}
+
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+}
+
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
+{
+ return ASN1_d2i_fp((void *(*)(void))
+ RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
+ (void **)rsa);
+}
+
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+}
+
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
+{
+ return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa);
+}
+# endif
+
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+}
+
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+}
+
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+}
+
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
+{
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
+}
+
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+}
+
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
+{
+ return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa);
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+# ifndef OPENSSL_NO_FP_API
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
+{
+ return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
+}
+
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
+{
+ return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
+}
+
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
+{
+ return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
+}
+
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
+{
+ return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa);
+}
+# endif
+
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
+{
+ return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
+}
+
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
+{
+ return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
+}
+
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
+{
+ return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
+}
+
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
+{
+ return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa);
+}
+
+#endif
+
+#ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_FP_API
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
+{
+ return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
+}
+
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
+{
+ return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
+}
+
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
+{
+ return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
+}
+
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
+{
+ return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
+}
+# endif
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
+{
+ return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
+}
+
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
+{
+ return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
+}
+
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
+{
+ return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
+}
+
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
+{
+ return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
+}
+#endif
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ ASN1_BIT_STRING *key;
+ key = X509_get0_pubkey_bitstr(data);
+ if (!key)
+ return 0;
+ return EVP_Digest(key->data, key->length, md, len, type, NULL);
+}
+
+int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
+ unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
+}
+
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
+}
+
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
+}
+
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
+}
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
+ const EVP_MD *type, unsigned char *md,
+ unsigned int *len)
+{
+ return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type,
+ (char *)data, md, len));
+}
+
+#ifndef OPENSSL_NO_FP_API
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
+{
+ return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
+}
+
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
+{
+ return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
+}
+#endif
+
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
+{
+ return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
+}
+
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
+{
+ return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
+}
+
+#ifndef OPENSSL_NO_FP_API
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+ PKCS8_PRIV_KEY_INFO **p8inf)
+{
+ return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+ d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
+}
+
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
+{
+ return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
+ p8inf);
+}
+
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
+{
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ int ret;
+ p8inf = EVP_PKEY2PKCS8(key);
+ if (!p8inf)
+ return 0;
+ ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return ret;
+}
+
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
+{
+ return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
+}
+
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
+{
+ return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
+}
+
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
+{
+ return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
+}
+
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
+{
+ return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
+}
+
+#endif
+
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+ PKCS8_PRIV_KEY_INFO **p8inf)
+{
+ return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+ d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
+}
+
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
+{
+ return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
+ p8inf);
+}
+
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
+{
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ int ret;
+ p8inf = EVP_PKEY2PKCS8(key);
+ if (!p8inf)
+ return 0;
+ ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return ret;
+}
+
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
+{
+ return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
+}
+
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
+{
+ return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
+}
+
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
+{
+ return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
+}
+
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
+{
+ return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/ext_dat.h b/Cryptlib/OpenSSL/crypto/x509v3/ext_dat.h
new file mode 100644
index 00000000..09ebbcae
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/ext_dat.h
@@ -0,0 +1,138 @@
+/* ext_dat.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 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).
+ *
+ */
+/* This file contains a table of "standard" extensions */
+
+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, 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, v3_idp;
+extern X509V3_EXT_METHOD v3_addr, v3_asid;
+extern X509V3_EXT_METHOD v3_ct_scts[];
+
+/*
+ * This table will be searched using OBJ_bsearch so it *must* kept in order
+ * of the ext_nid values.
+ */
+
+static const X509V3_EXT_METHOD *standard_exts[] = {
+ &v3_nscert,
+ &v3_ns_ia5_list[0],
+ &v3_ns_ia5_list[1],
+ &v3_ns_ia5_list[2],
+ &v3_ns_ia5_list[3],
+ &v3_ns_ia5_list[4],
+ &v3_ns_ia5_list[5],
+ &v3_ns_ia5_list[6],
+ &v3_skey_id,
+ &v3_key_usage,
+ &v3_pkey_usage_period,
+ &v3_alt[0],
+ &v3_alt[1],
+ &v3_bcons,
+ &v3_crl_num,
+ &v3_cpols,
+ &v3_akey_id,
+ &v3_crld,
+ &v3_ext_ku,
+ &v3_delta_crl,
+ &v3_crl_reason,
+#ifndef OPENSSL_NO_OCSP
+ &v3_crl_invdate,
+#endif
+ &v3_sxnet,
+ &v3_info,
+#ifndef OPENSSL_NO_RFC3779
+ &v3_addr,
+ &v3_asid,
+#endif
+#ifndef OPENSSL_NO_OCSP
+ &v3_ocsp_nonce,
+ &v3_ocsp_crlid,
+ &v3_ocsp_accresp,
+ &v3_ocsp_nocheck,
+ &v3_ocsp_acutoff,
+ &v3_ocsp_serviceloc,
+#endif
+ &v3_sinfo,
+ &v3_policy_constraints,
+#ifndef OPENSSL_NO_OCSP
+ &v3_crl_hold,
+#endif
+ &v3_pci,
+ &v3_name_constraints,
+ &v3_policy_mappings,
+ &v3_inhibit_anyp,
+ &v3_idp,
+ &v3_alt[2],
+ &v3_freshest_crl,
+#ifndef OPENSSL_NO_SCT
+ &v3_ct_scts[0],
+ &v3_ct_scts[1],
+#endif
+};
+
+/* Number of standard extensions */
+
+#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/pcy_cache.c b/Cryptlib/OpenSSL/crypto/x509v3/pcy_cache.c
new file mode 100644
index 00000000..c8f41f24
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_cache.c
@@ -0,0 +1,269 @@
+/* pcy_cache.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+static int policy_data_cmp(const X509_POLICY_DATA *const *a,
+ const X509_POLICY_DATA *const *b);
+static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
+
+/*
+ * Set cache entry according to CertificatePolicies extension. Note: this
+ * destroys the passed CERTIFICATEPOLICIES structure.
+ */
+
+static int policy_cache_create(X509 *x,
+ CERTIFICATEPOLICIES *policies, int crit)
+{
+ int i;
+ int ret = 0;
+ X509_POLICY_CACHE *cache = x->policy_cache;
+ X509_POLICY_DATA *data = NULL;
+ POLICYINFO *policy;
+ if (sk_POLICYINFO_num(policies) == 0)
+ goto bad_policy;
+ cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
+ if (!cache->data)
+ goto bad_policy;
+ for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
+ policy = sk_POLICYINFO_value(policies, i);
+ data = policy_data_new(policy, NULL, crit);
+ if (!data)
+ goto bad_policy;
+ /*
+ * Duplicate policy OIDs are illegal: reject if matches found.
+ */
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+ if (cache->anyPolicy) {
+ ret = -1;
+ goto bad_policy;
+ }
+ cache->anyPolicy = data;
+ } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
+ ret = -1;
+ goto bad_policy;
+ } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+ goto bad_policy;
+ data = NULL;
+ }
+ ret = 1;
+ bad_policy:
+ if (ret == -1)
+ x->ex_flags |= EXFLAG_INVALID_POLICY;
+ if (data)
+ policy_data_free(data);
+ sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
+ if (ret <= 0) {
+ sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+ cache->data = NULL;
+ }
+ return ret;
+}
+
+static int policy_cache_new(X509 *x)
+{
+ X509_POLICY_CACHE *cache;
+ ASN1_INTEGER *ext_any = NULL;
+ POLICY_CONSTRAINTS *ext_pcons = NULL;
+ CERTIFICATEPOLICIES *ext_cpols = NULL;
+ POLICY_MAPPINGS *ext_pmaps = NULL;
+ int i;
+ cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
+ if (!cache)
+ return 0;
+ cache->anyPolicy = NULL;
+ cache->data = NULL;
+ cache->any_skip = -1;
+ cache->explicit_skip = -1;
+ cache->map_skip = -1;
+
+ x->policy_cache = cache;
+
+ /*
+ * Handle requireExplicitPolicy *first*. Need to process this even if we
+ * don't have any policies.
+ */
+ ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
+
+ if (!ext_pcons) {
+ if (i != -1)
+ goto bad_cache;
+ } else {
+ if (!ext_pcons->requireExplicitPolicy
+ && !ext_pcons->inhibitPolicyMapping)
+ goto bad_cache;
+ if (!policy_cache_set_int(&cache->explicit_skip,
+ ext_pcons->requireExplicitPolicy))
+ goto bad_cache;
+ if (!policy_cache_set_int(&cache->map_skip,
+ ext_pcons->inhibitPolicyMapping))
+ goto bad_cache;
+ }
+
+ /* Process CertificatePolicies */
+
+ ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
+ /*
+ * If no CertificatePolicies extension or problem decoding then there is
+ * no point continuing because the valid policies will be NULL.
+ */
+ if (!ext_cpols) {
+ /* If not absent some problem with extension */
+ if (i != -1)
+ goto bad_cache;
+ return 1;
+ }
+
+ i = policy_cache_create(x, ext_cpols, i);
+
+ /* NB: ext_cpols freed by policy_cache_set_policies */
+
+ if (i <= 0)
+ return i;
+
+ ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
+
+ if (!ext_pmaps) {
+ /* If not absent some problem with extension */
+ if (i != -1)
+ goto bad_cache;
+ } else {
+ i = policy_cache_set_mapping(x, ext_pmaps);
+ if (i <= 0)
+ goto bad_cache;
+ }
+
+ ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
+
+ if (!ext_any) {
+ if (i != -1)
+ goto bad_cache;
+ } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+ goto bad_cache;
+
+ if (0) {
+ bad_cache:
+ x->ex_flags |= EXFLAG_INVALID_POLICY;
+ }
+
+ if (ext_pcons)
+ POLICY_CONSTRAINTS_free(ext_pcons);
+
+ if (ext_any)
+ ASN1_INTEGER_free(ext_any);
+
+ return 1;
+
+}
+
+void policy_cache_free(X509_POLICY_CACHE *cache)
+{
+ if (!cache)
+ return;
+ if (cache->anyPolicy)
+ policy_data_free(cache->anyPolicy);
+ if (cache->data)
+ sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+ OPENSSL_free(cache);
+}
+
+const X509_POLICY_CACHE *policy_cache_set(X509 *x)
+{
+
+ if (x->policy_cache == NULL) {
+ CRYPTO_w_lock(CRYPTO_LOCK_X509);
+ policy_cache_new(x);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+ }
+
+ return x->policy_cache;
+
+}
+
+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
+ const ASN1_OBJECT *id)
+{
+ int idx;
+ X509_POLICY_DATA tmp;
+ tmp.valid_policy = (ASN1_OBJECT *)id;
+ idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
+ if (idx == -1)
+ return NULL;
+ return sk_X509_POLICY_DATA_value(cache->data, idx);
+}
+
+static int policy_data_cmp(const X509_POLICY_DATA *const *a,
+ const X509_POLICY_DATA *const *b)
+{
+ return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
+}
+
+static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
+{
+ if (value == NULL)
+ return 1;
+ if (value->type == V_ASN1_NEG_INTEGER)
+ return 0;
+ *out = ASN1_INTEGER_get(value);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/pcy_data.c b/Cryptlib/OpenSSL/crypto/x509v3/pcy_data.c
new file mode 100644
index 00000000..90e9970e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_data.c
@@ -0,0 +1,129 @@
+/* pcy_data.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Policy Node routines */
+
+void policy_data_free(X509_POLICY_DATA *data)
+{
+ ASN1_OBJECT_free(data->valid_policy);
+ /* Don't free qualifiers if shared */
+ if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
+ sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free);
+ sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
+ OPENSSL_free(data);
+}
+
+/*
+ * Create a data based on an existing policy. If 'id' is NULL use the oid in
+ * the policy, otherwise use 'id'. This behaviour covers the two types of
+ * data in RFC3280: data with from a CertificatePolcies extension and
+ * additional data with just the qualifiers of anyPolicy and ID from another
+ * source.
+ */
+
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
+ const ASN1_OBJECT *cid, int crit)
+{
+ X509_POLICY_DATA *ret;
+ ASN1_OBJECT *id;
+ if (!policy && !cid)
+ return NULL;
+ if (cid) {
+ id = OBJ_dup(cid);
+ if (!id)
+ return NULL;
+ } else
+ id = NULL;
+ ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
+ if (!ret)
+ return NULL;
+ ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
+ if (!ret->expected_policy_set) {
+ OPENSSL_free(ret);
+ if (id)
+ ASN1_OBJECT_free(id);
+ return NULL;
+ }
+
+ if (crit)
+ ret->flags = POLICY_DATA_FLAG_CRITICAL;
+ else
+ ret->flags = 0;
+
+ if (id)
+ ret->valid_policy = id;
+ else {
+ ret->valid_policy = policy->policyid;
+ policy->policyid = NULL;
+ }
+
+ if (policy) {
+ ret->qualifier_set = policy->qualifiers;
+ policy->qualifiers = NULL;
+ } else
+ ret->qualifier_set = NULL;
+
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/pcy_int.h b/Cryptlib/OpenSSL/crypto/x509v3/pcy_int.h
new file mode 100644
index 00000000..b5075f9e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_int.h
@@ -0,0 +1,217 @@
+/* pcy_int.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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).
+ *
+ */
+
+typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
+
+DECLARE_STACK_OF(X509_POLICY_DATA)
+
+/* Internal structures */
+
+/*
+ * This structure and the field names correspond to the Policy 'node' of
+ * RFC3280. NB this structure contains no pointers to parent or child data:
+ * X509_POLICY_NODE contains that. This means that the main policy data can
+ * be kept static and cached with the certificate.
+ */
+
+struct X509_POLICY_DATA_st {
+ unsigned int flags;
+ /* Policy OID and qualifiers for this data */
+ ASN1_OBJECT *valid_policy;
+ STACK_OF(POLICYQUALINFO) *qualifier_set;
+ STACK_OF(ASN1_OBJECT) *expected_policy_set;
+};
+
+/* X509_POLICY_DATA flags values */
+
+/*
+ * This flag indicates the structure has been mapped using a policy mapping
+ * extension. If policy mapping is not active its references get deleted.
+ */
+
+#define POLICY_DATA_FLAG_MAPPED 0x1
+
+/*
+ * This flag indicates the data doesn't correspond to a policy in Certificate
+ * Policies: it has been mapped to any policy.
+ */
+
+#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
+
+/* AND with flags to see if any mapping has occurred */
+
+#define POLICY_DATA_FLAG_MAP_MASK 0x3
+
+/* qualifiers are shared and shouldn't be freed */
+
+#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
+
+/* Parent node is an extra node and should be freed */
+
+#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
+
+/* Corresponding CertificatePolicies is critical */
+
+#define POLICY_DATA_FLAG_CRITICAL 0x10
+
+/* This structure is cached with a certificate */
+
+struct X509_POLICY_CACHE_st {
+ /* anyPolicy data or NULL if no anyPolicy */
+ X509_POLICY_DATA *anyPolicy;
+ /* other policy data */
+ STACK_OF(X509_POLICY_DATA) *data;
+ /* If InhibitAnyPolicy present this is its value or -1 if absent. */
+ long any_skip;
+ /*
+ * If policyConstraints and requireExplicitPolicy present this is its
+ * value or -1 if absent.
+ */
+ long explicit_skip;
+ /*
+ * If policyConstraints and policyMapping present this is its value or -1
+ * if absent.
+ */
+ long map_skip;
+};
+
+/*
+ * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL
+ */
+
+/* This structure represents the relationship between nodes */
+
+struct X509_POLICY_NODE_st {
+ /* node data this refers to */
+ const X509_POLICY_DATA *data;
+ /* Parent node */
+ X509_POLICY_NODE *parent;
+ /* Number of child nodes */
+ int nchild;
+};
+
+struct X509_POLICY_LEVEL_st {
+ /* Cert for this level */
+ X509 *cert;
+ /* nodes at this level */
+ STACK_OF(X509_POLICY_NODE) *nodes;
+ /* anyPolicy node */
+ X509_POLICY_NODE *anyPolicy;
+ /* Extra data */
+ /*
+ * STACK_OF(X509_POLICY_DATA) *extra_data;
+ */
+ unsigned int flags;
+};
+
+struct X509_POLICY_TREE_st {
+ /* This is the tree 'level' data */
+ X509_POLICY_LEVEL *levels;
+ int nlevel;
+ /*
+ * Extra policy data when additional nodes (not from the certificate) are
+ * required.
+ */
+ STACK_OF(X509_POLICY_DATA) *extra_data;
+ /* This is the authority constained policy set */
+ STACK_OF(X509_POLICY_NODE) *auth_policies;
+ STACK_OF(X509_POLICY_NODE) *user_policies;
+ unsigned int flags;
+};
+
+/* Set if anyPolicy present in user policies */
+#define POLICY_FLAG_ANY_POLICY 0x2
+
+/* Useful macros */
+
+#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
+#define node_critical(node) node_data_critical(node->data)
+
+/* Internal functions */
+
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
+ int crit);
+void policy_data_free(X509_POLICY_DATA *data);
+
+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
+ const ASN1_OBJECT *id);
+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
+
+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
+
+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,
+ 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/Cryptlib/OpenSSL/crypto/x509v3/pcy_lib.c b/Cryptlib/OpenSSL/crypto/x509v3/pcy_lib.c
new file mode 100644
index 00000000..dbb29835
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_lib.c
@@ -0,0 +1,167 @@
+/* pcy_lib.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* accessor functions */
+
+/* X509_POLICY_TREE stuff */
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
+{
+ if (!tree)
+ return 0;
+ return tree->nlevel;
+}
+
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+ int i)
+{
+ if (!tree || (i < 0) || (i >= tree->nlevel))
+ return NULL;
+ return tree->levels + i;
+}
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+ X509_POLICY_TREE
+ *tree)
+{
+ if (!tree)
+ return NULL;
+ return tree->auth_policies;
+}
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+ X509_POLICY_TREE
+ *tree)
+{
+ if (!tree)
+ return NULL;
+ if (tree->flags & POLICY_FLAG_ANY_POLICY)
+ return tree->auth_policies;
+ else
+ return tree->user_policies;
+}
+
+/* X509_POLICY_LEVEL stuff */
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
+{
+ int n;
+ if (!level)
+ return 0;
+ if (level->anyPolicy)
+ n = 1;
+ else
+ n = 0;
+ if (level->nodes)
+ n += sk_X509_POLICY_NODE_num(level->nodes);
+ return n;
+}
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
+{
+ if (!level)
+ return NULL;
+ if (level->anyPolicy) {
+ if (i == 0)
+ return level->anyPolicy;
+ i--;
+ }
+ return sk_X509_POLICY_NODE_value(level->nodes, i);
+}
+
+/* X509_POLICY_NODE stuff */
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
+{
+ if (!node)
+ return NULL;
+ return node->data->valid_policy;
+}
+
+#if 0
+int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
+{
+ if (node_critical(node))
+ return 1;
+ return 0;
+}
+#endif
+
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+ X509_POLICY_NODE
+ *node)
+{
+ if (!node)
+ return NULL;
+ return node->data->qualifier_set;
+}
+
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+ *node)
+{
+ if (!node)
+ return NULL;
+ return node->parent;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/pcy_map.c b/Cryptlib/OpenSSL/crypto/x509v3/pcy_map.c
new file mode 100644
index 00000000..b99eb91c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_map.c
@@ -0,0 +1,130 @@
+/* pcy_map.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/*
+ * Set policy mapping entries in cache. Note: this modifies the passed
+ * POLICY_MAPPINGS structure
+ */
+
+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
+{
+ POLICY_MAPPING *map;
+ X509_POLICY_DATA *data;
+ X509_POLICY_CACHE *cache = x->policy_cache;
+ int i;
+ int ret = 0;
+ if (sk_POLICY_MAPPING_num(maps) == 0) {
+ ret = -1;
+ goto bad_mapping;
+ }
+ for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
+ map = sk_POLICY_MAPPING_value(maps, i);
+ /* Reject if map to or from anyPolicy */
+ if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
+ || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
+ 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 */
+ if (!data && !cache->anyPolicy)
+ continue;
+
+ /* Create a NODE from anyPolicy */
+ if (!data) {
+ data = policy_data_new(NULL, map->issuerDomainPolicy,
+ cache->anyPolicy->flags
+ & POLICY_DATA_FLAG_CRITICAL);
+ if (!data)
+ goto bad_mapping;
+ data->qualifier_set = cache->anyPolicy->qualifier_set;
+ /*
+ * 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)) {
+ policy_data_free(data);
+ goto bad_mapping;
+ }
+ } else
+ data->flags |= POLICY_DATA_FLAG_MAPPED;
+ if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
+ map->subjectDomainPolicy))
+ goto bad_mapping;
+ map->subjectDomainPolicy = NULL;
+
+ }
+
+ ret = 1;
+ bad_mapping:
+ if (ret == -1)
+ x->ex_flags |= EXFLAG_INVALID_POLICY;
+ sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
+ return ret;
+
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/pcy_node.c b/Cryptlib/OpenSSL/crypto/x509v3/pcy_node.c
new file mode 100644
index 00000000..d6c91765
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_node.c
@@ -0,0 +1,190 @@
+/* pcy_node.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+static int node_cmp(const X509_POLICY_NODE *const *a,
+ const X509_POLICY_NODE *const *b)
+{
+ return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
+}
+
+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
+{
+ return sk_X509_POLICY_NODE_new(node_cmp);
+}
+
+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
+ const ASN1_OBJECT *id)
+{
+ 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);
+
+}
+
+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+ const X509_POLICY_NODE *parent,
+ const ASN1_OBJECT *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,
+ const 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)
+{
+ 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/Cryptlib/OpenSSL/crypto/x509v3/pcy_tree.c b/Cryptlib/OpenSSL/crypto/x509v3/pcy_tree.c
new file mode 100644
index 00000000..09b8691c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/pcy_tree.c
@@ -0,0 +1,831 @@
+/* pcy_tree.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#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 occurred.
+ * -1 Inconsistent or invalid extensions in certificates.
+ * 1 Tree initialized OK.
+ * 2 Policy tree is empty.
+ * 5 Tree OK and requireExplicitPolicy true.
+ * 6 Tree empty and requireExplicitPolicy true.
+ */
+
+static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
+ unsigned int flags)
+{
+ X509_POLICY_TREE *tree;
+ X509_POLICY_LEVEL *level;
+ const X509_POLICY_CACHE *cache;
+ X509_POLICY_DATA *data = NULL;
+ X509 *x;
+ int ret = 1;
+ int i, n;
+ int explicit_policy;
+ int any_skip;
+ int map_skip;
+ *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;
+ else
+ explicit_policy = n + 1;
+
+ if (flags & X509_V_FLAG_INHIBIT_ANY)
+ any_skip = 0;
+ else
+ any_skip = n + 1;
+
+ if (flags & X509_V_FLAG_INHIBIT_MAP)
+ map_skip = 0;
+ else
+ map_skip = n + 1;
+
+ /* Can't do anything with just a trust anchor */
+ if (n == 1)
+ return 1;
+ /*
+ * First setup policy cache in all certificates apart from the trust
+ * anchor. Note any bad cache results on the way. Also can calculate
+ * explicit_policy value at this point.
+ */
+ for (i = n - 2; i >= 0; i--) {
+ x = sk_X509_value(certs, i);
+ X509_check_purpose(x, -1, -1);
+ cache = policy_cache_set(x);
+ /* If cache NULL something bad happened: return immediately */
+ if (cache == NULL)
+ return 0;
+ /*
+ * If inconsistent extensions keep a note of it but continue
+ */
+ if (x->ex_flags & EXFLAG_INVALID_POLICY)
+ ret = -1;
+ /*
+ * Otherwise if we have no data (hence no CertificatePolicies) and
+ * haven't already set an inconsistent code note it.
+ */
+ else if ((ret == 1) && !cache->data)
+ ret = 2;
+ if (explicit_policy > 0) {
+ if (!(x->ex_flags & EXFLAG_SI))
+ explicit_policy--;
+ if ((cache->explicit_skip != -1)
+ && (cache->explicit_skip < explicit_policy))
+ explicit_policy = cache->explicit_skip;
+ }
+ }
+
+ if (ret != 1) {
+ if (ret == 2 && !explicit_policy)
+ return 6;
+ return ret;
+ }
+
+ /* If we get this far initialize the tree */
+
+ tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
+
+ if (!tree)
+ return 0;
+
+ tree->flags = 0;
+ tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
+ tree->nlevel = 0;
+ tree->extra_data = NULL;
+ tree->auth_policies = NULL;
+ tree->user_policies = NULL;
+
+ if (!tree->levels) {
+ OPENSSL_free(tree);
+ return 0;
+ }
+
+ memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
+
+ tree->nlevel = n;
+
+ level = tree->levels;
+
+ /* Root data: initialize to anyPolicy */
+
+ data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
+
+ if (!data || !level_add_node(level, data, NULL, tree))
+ goto bad_tree;
+
+ for (i = n - 2; i >= 0; i--) {
+ level++;
+ x = sk_X509_value(certs, i);
+ cache = policy_cache_set(x);
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ level->cert = x;
+
+ if (!cache->anyPolicy)
+ level->flags |= X509_V_FLAG_INHIBIT_ANY;
+
+ /* Determine inhibit any and inhibit map flags */
+ if (any_skip == 0) {
+ /*
+ * Any matching allowed if certificate is self issued and not the
+ * last in the chain.
+ */
+ if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
+ level->flags |= X509_V_FLAG_INHIBIT_ANY;
+ } else {
+ if (!(x->ex_flags & EXFLAG_SI))
+ any_skip--;
+ if ((cache->any_skip >= 0)
+ && (cache->any_skip < any_skip))
+ any_skip = cache->any_skip;
+ }
+
+ if (map_skip == 0)
+ level->flags |= X509_V_FLAG_INHIBIT_MAP;
+ else {
+ 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;
+
+ if (explicit_policy)
+ return 1;
+ else
+ return 5;
+
+ bad_tree:
+
+ X509_policy_tree_free(tree);
+
+ return 0;
+
+}
+
+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.
+ */
+
+static int tree_link_nodes(X509_POLICY_LEVEL *curr,
+ const X509_POLICY_CACHE *cache)
+{
+ int i;
+ X509_POLICY_DATA *data;
+
+ for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
+ data = sk_X509_POLICY_DATA_value(cache->data, i);
+ /*
+ * If a node is mapped any it doesn't have a corresponding
+ * CertificatePolicies entry. However such an identical node would
+ * be created if anyPolicy matching is enabled because there would be
+ * no match with the parent valid_policy_set. So we create 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;
+#endif
+ /* Look for matching nodes in previous level */
+ if (!tree_link_matching_nodes(curr, data))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * 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_NODE *node;
+ 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.
+ * Note: need something better for policy mapping because each node
+ * may have multiple children
+ */
+ if (node->nchild)
+ continue;
+
+ /*
+ * Create a new node with qualifiers from anyPolicy and id from
+ * unmatched node.
+ */
+ data = policy_data_new(NULL, node->data->valid_policy,
+ 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;
+ }
+#endif
+
+ }
+ /* Finally add link to anyPolicy */
+ if (last->anyPolicy) {
+ if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Prune the tree: delete any child mapped child data on the current level
+ * then proceed up the tree deleting any data with no children. If we ever
+ * have no data on a level we can halt because the tree will be empty.
+ */
+
+static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+{
+ STACK_OF(X509_POLICY_NODE) *nodes;
+ X509_POLICY_NODE *node;
+ int i;
+ nodes = curr->nodes;
+ if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; 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;
+ nodes = curr->nodes;
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; 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(nodes, i);
+ }
+ }
+ if (curr->anyPolicy && !curr->anyPolicy->nchild) {
+ if (curr->anyPolicy->parent)
+ curr->anyPolicy->parent->nchild--;
+ OPENSSL_free(curr->anyPolicy);
+ curr->anyPolicy = NULL;
+ }
+ if (curr == tree->levels) {
+ /* If we zapped anyPolicy at top then tree is empty */
+ if (!curr->anyPolicy)
+ return 2;
+ return 1;
+ }
+ }
+
+ return 1;
+
+}
+
+static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
+ X509_POLICY_NODE *pcy)
+{
+ if (!*pnodes) {
+ *pnodes = policy_node_cmp_new();
+ if (!*pnodes)
+ return 0;
+ } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
+ return 1;
+
+ if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
+ return 0;
+
+ return 1;
+
+}
+
+/*
+ * Calculate the authority set based on policy tree. The 'pnodes' parameter
+ * is used as a store for the set of policy nodes used to calculate the user
+ * set. If the authority set is not anyPolicy then pnodes will just point to
+ * the authority set. If however the authority set is anyPolicy then the set
+ * of valid policies (other than anyPolicy) is store in pnodes. The return
+ * value of '2' is used in this case to indicate that pnodes should be freed.
+ */
+
+static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
+ STACK_OF(X509_POLICY_NODE) **pnodes)
+{
+ X509_POLICY_LEVEL *curr;
+ X509_POLICY_NODE *node, *anyptr;
+ STACK_OF(X509_POLICY_NODE) **addnodes;
+ int i, j;
+ curr = tree->levels + tree->nlevel - 1;
+
+ /* If last level contains anyPolicy set is anyPolicy */
+ if (curr->anyPolicy) {
+ if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
+ return 0;
+ addnodes = pnodes;
+ } else
+ /* Add policies to authority set */
+ addnodes = &tree->auth_policies;
+
+ curr = tree->levels;
+ for (i = 1; i < tree->nlevel; i++) {
+ /*
+ * If no anyPolicy node on this this level it can't appear on lower
+ * levels so end search.
+ */
+ if (!(anyptr = curr->anyPolicy))
+ break;
+ curr++;
+ for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
+ node = sk_X509_POLICY_NODE_value(curr->nodes, j);
+ if ((node->parent == anyptr)
+ && !tree_add_auth_node(addnodes, node))
+ return 0;
+ }
+ }
+
+ if (addnodes == pnodes)
+ return 2;
+
+ *pnodes = tree->auth_policies;
+
+ return 1;
+}
+
+static int tree_calculate_user_set(X509_POLICY_TREE *tree,
+ STACK_OF(ASN1_OBJECT) *policy_oids,
+ STACK_OF(X509_POLICY_NODE) *auth_nodes)
+{
+ int i;
+ X509_POLICY_NODE *node;
+ ASN1_OBJECT *oid;
+
+ X509_POLICY_NODE *anyPolicy;
+ X509_POLICY_DATA *extra;
+
+ /*
+ * Check if anyPolicy present in authority constrained policy set: this
+ * will happen if it is a leaf node.
+ */
+
+ if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
+ return 1;
+
+ anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+ oid = sk_ASN1_OBJECT_value(policy_oids, i);
+ if (OBJ_obj2nid(oid) == NID_any_policy) {
+ tree->flags |= POLICY_FLAG_ANY_POLICY;
+ return 1;
+ }
+ }
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+ oid = sk_ASN1_OBJECT_value(policy_oids, i);
+ node = tree_find_sk(auth_nodes, oid);
+ if (!node) {
+ if (!anyPolicy)
+ continue;
+ /*
+ * Create a new node with policy ID from user set and qualifiers
+ * from anyPolicy.
+ */
+ extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
+ if (!extra)
+ return 0;
+ extra->qualifier_set = anyPolicy->data->qualifier_set;
+ extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
+ | POLICY_DATA_FLAG_EXTRA_NODE;
+ node = level_add_node(NULL, extra, anyPolicy->parent, tree);
+ }
+ if (!tree->user_policies) {
+ tree->user_policies = sk_X509_POLICY_NODE_new_null();
+ if (!tree->user_policies)
+ return 1;
+ }
+ if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
+ return 0;
+ }
+ return 1;
+
+}
+
+static int tree_evaluate(X509_POLICY_TREE *tree)
+{
+ int ret, i;
+ X509_POLICY_LEVEL *curr = tree->levels + 1;
+ const X509_POLICY_CACHE *cache;
+
+ for (i = 1; i < tree->nlevel; i++, curr++) {
+ cache = policy_cache_set(curr->cert);
+ if (!tree_link_nodes(curr, cache))
+ return 0;
+
+ 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;
+ }
+
+ return 1;
+
+}
+
+static void exnode_free(X509_POLICY_NODE *node)
+{
+ if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
+ OPENSSL_free(node);
+}
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree)
+{
+ X509_POLICY_LEVEL *curr;
+ int i;
+
+ if (!tree)
+ return;
+
+ sk_X509_POLICY_NODE_free(tree->auth_policies);
+ sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
+
+ for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
+ if (curr->cert)
+ X509_free(curr->cert);
+ if (curr->nodes)
+ sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
+ if (curr->anyPolicy)
+ policy_node_free(curr->anyPolicy);
+ }
+
+ if (tree->extra_data)
+ sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
+
+ OPENSSL_free(tree->levels);
+ OPENSSL_free(tree);
+
+}
+
+/*-
+ * Application policy checking function.
+ * Return codes:
+ * 0 Internal Error.
+ * 1 Successful.
+ * -1 One or more certificates contain invalid or inconsistent extensions
+ * -2 User constrained policy set empty and requireExplicit true.
+ */
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+ STACK_OF(X509) *certs,
+ STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
+{
+ int ret;
+ X509_POLICY_TREE *tree = NULL;
+ STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
+ *ptree = NULL;
+
+ *pexplicit_policy = 0;
+ ret = tree_init(&tree, certs, flags);
+
+ switch (ret) {
+
+ /* Tree empty requireExplicit False: OK */
+ case 2:
+ return 1;
+
+ /* Some internal error */
+ case -1:
+ return -1;
+
+ /* Some internal error */
+ case 0:
+ return 0;
+
+ /* Tree empty requireExplicit True: Error */
+
+ case 6:
+ *pexplicit_policy = 1;
+ return -2;
+
+ /* Tree OK requireExplicit True: OK and continue */
+ case 5:
+ *pexplicit_policy = 1;
+ break;
+
+ /* Tree OK: continue */
+
+ case 1:
+ if (!tree)
+ /*
+ * tree_init() returns success and a null tree
+ * if it's just looking at a trust anchor.
+ * I'm not sure that returning success here is
+ * correct, but I'm sure that reporting this
+ * as an internal error which our caller
+ * interprets as a malloc failure is wrong.
+ */
+ return 1;
+ break;
+ }
+
+ if (!tree)
+ goto error;
+ ret = tree_evaluate(tree);
+
+ tree_print("tree_evaluate()", tree, NULL);
+
+ if (ret <= 0)
+ goto error;
+
+ /* Return value 2 means tree empty */
+ if (ret == 2) {
+ X509_policy_tree_free(tree);
+ if (*pexplicit_policy)
+ return -2;
+ else
+ return 1;
+ }
+
+ /* Tree is not empty: continue */
+
+ ret = tree_calculate_authority_set(tree, &auth_nodes);
+
+ if (!ret)
+ goto error;
+
+ if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
+ goto error;
+
+ if (ret == 2)
+ sk_X509_POLICY_NODE_free(auth_nodes);
+
+ if (tree)
+ *ptree = tree;
+
+ if (*pexplicit_policy) {
+ nodes = X509_policy_tree_get0_user_policies(tree);
+ if (sk_X509_POLICY_NODE_num(nodes) <= 0)
+ return -2;
+ }
+
+ return 1;
+
+ error:
+
+ X509_policy_tree_free(tree);
+
+ return 0;
+
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c
new file mode 100644
index 00000000..94cfed05
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c
@@ -0,0 +1,1344 @@
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * 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).
+ */
+
+/*
+ * Implementation of RFC 3779 section 2.2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/buffer.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
+ */
+
+ASN1_SEQUENCE(IPAddressRange) = {
+ ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
+ ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(IPAddressRange)
+
+ASN1_CHOICE(IPAddressOrRange) = {
+ ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
+ ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange)
+} ASN1_CHOICE_END(IPAddressOrRange)
+
+ASN1_CHOICE(IPAddressChoice) = {
+ ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL),
+ ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
+} ASN1_CHOICE_END(IPAddressChoice)
+
+ASN1_SEQUENCE(IPAddressFamily) = {
+ ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
+} ASN1_SEQUENCE_END(IPAddressFamily)
+
+ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
+ IPAddrBlocks, IPAddressFamily)
+ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
+
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * How much buffer space do we need for a raw address?
+ */
+# define ADDR_RAW_BUF_LEN 16
+
+/*
+ * What's the address length associated with this AFI?
+ */
+static int length_from_afi(const unsigned afi)
+{
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ return 4;
+ case IANA_AFI_IPV6:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * Extract the AFI from an IPAddressFamily.
+ */
+unsigned int v3_addr_get_afi(const IPAddressFamily *f)
+{
+ return ((f != NULL &&
+ f->addressFamily != NULL && f->addressFamily->data != NULL)
+ ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1]))
+ : 0);
+}
+
+/*
+ * Expand the bitstring form of an address into a raw byte array.
+ * At the moment this is coded for simplicity, not speed.
+ */
+static int addr_expand(unsigned char *addr,
+ const ASN1_BIT_STRING *bs,
+ const int length, const unsigned char fill)
+{
+ if (bs->length < 0 || bs->length > length)
+ return 0;
+ if (bs->length > 0) {
+ memcpy(addr, bs->data, bs->length);
+ if ((bs->flags & 7) != 0) {
+ unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
+ if (fill == 0)
+ addr[bs->length - 1] &= ~mask;
+ else
+ addr[bs->length - 1] |= mask;
+ }
+ }
+ memset(addr + bs->length, fill, length - bs->length);
+ return 1;
+}
+
+/*
+ * Extract the prefix length from a bitstring.
+ */
+# define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
+
+/*
+ * i2r handler for one address bitstring.
+ */
+static int i2r_address(BIO *out,
+ const unsigned afi,
+ const unsigned char fill, const ASN1_BIT_STRING *bs)
+{
+ unsigned char addr[ADDR_RAW_BUF_LEN];
+ int i, n;
+
+ if (bs->length < 0)
+ return 0;
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ if (!addr_expand(addr, bs, 4, fill))
+ return 0;
+ BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+ break;
+ case IANA_AFI_IPV6:
+ if (!addr_expand(addr, bs, 16, fill))
+ return 0;
+ for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00;
+ n -= 2) ;
+ for (i = 0; i < n; i += 2)
+ BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1],
+ (i < 14 ? ":" : ""));
+ if (i < 16)
+ BIO_puts(out, ":");
+ if (i == 0)
+ BIO_puts(out, ":");
+ break;
+ default:
+ for (i = 0; i < bs->length; i++)
+ BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
+ BIO_printf(out, "[%d]", (int)(bs->flags & 7));
+ break;
+ }
+ return 1;
+}
+
+/*
+ * i2r handler for a sequence of addresses and ranges.
+ */
+static int i2r_IPAddressOrRanges(BIO *out,
+ const int indent,
+ const IPAddressOrRanges *aors,
+ const unsigned afi)
+{
+ int i;
+ for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
+ const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
+ BIO_printf(out, "%*s", indent, "");
+ switch (aor->type) {
+ case IPAddressOrRange_addressPrefix:
+ if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
+ return 0;
+ BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
+ continue;
+ case IPAddressOrRange_addressRange:
+ if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
+ return 0;
+ BIO_puts(out, "-");
+ if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
+ return 0;
+ BIO_puts(out, "\n");
+ continue;
+ }
+ }
+ return 1;
+}
+
+/*
+ * i2r handler for an IPAddrBlocks extension.
+ */
+static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
+ void *ext, BIO *out, int indent)
+{
+ const IPAddrBlocks *addr = ext;
+ int i;
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ const unsigned int afi = v3_addr_get_afi(f);
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ BIO_printf(out, "%*sIPv4", indent, "");
+ break;
+ case IANA_AFI_IPV6:
+ BIO_printf(out, "%*sIPv6", indent, "");
+ break;
+ default:
+ BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
+ break;
+ }
+ if (f->addressFamily->length > 2) {
+ switch (f->addressFamily->data[2]) {
+ case 1:
+ BIO_puts(out, " (Unicast)");
+ break;
+ case 2:
+ BIO_puts(out, " (Multicast)");
+ break;
+ case 3:
+ BIO_puts(out, " (Unicast/Multicast)");
+ break;
+ case 4:
+ BIO_puts(out, " (MPLS)");
+ break;
+ case 64:
+ BIO_puts(out, " (Tunnel)");
+ break;
+ case 65:
+ BIO_puts(out, " (VPLS)");
+ break;
+ case 66:
+ BIO_puts(out, " (BGP MDT)");
+ break;
+ case 128:
+ BIO_puts(out, " (MPLS-labeled VPN)");
+ break;
+ default:
+ BIO_printf(out, " (Unknown SAFI %u)",
+ (unsigned)f->addressFamily->data[2]);
+ break;
+ }
+ }
+ switch (f->ipAddressChoice->type) {
+ case IPAddressChoice_inherit:
+ BIO_puts(out, ": inherit\n");
+ break;
+ case IPAddressChoice_addressesOrRanges:
+ BIO_puts(out, ":\n");
+ if (!i2r_IPAddressOrRanges(out,
+ indent + 2,
+ f->ipAddressChoice->
+ u.addressesOrRanges, afi))
+ return 0;
+ break;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Sort comparison function for a sequence of IPAddressOrRange
+ * elements.
+ *
+ * There's no sane answer we can give if addr_expand() fails, and an
+ * assertion failure on externally supplied data is seriously uncool,
+ * so we just arbitrarily declare that if given invalid inputs this
+ * function returns -1. If this messes up your preferred sort order
+ * for garbage input, tough noogies.
+ */
+static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
+ const IPAddressOrRange *b, const int length)
+{
+ unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
+ int prefixlen_a = 0, prefixlen_b = 0;
+ int r;
+
+ switch (a->type) {
+ case IPAddressOrRange_addressPrefix:
+ if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
+ return -1;
+ prefixlen_a = addr_prefixlen(a->u.addressPrefix);
+ break;
+ case IPAddressOrRange_addressRange:
+ if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
+ return -1;
+ prefixlen_a = length * 8;
+ break;
+ }
+
+ switch (b->type) {
+ case IPAddressOrRange_addressPrefix:
+ if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
+ return -1;
+ prefixlen_b = addr_prefixlen(b->u.addressPrefix);
+ break;
+ case IPAddressOrRange_addressRange:
+ if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
+ return -1;
+ prefixlen_b = length * 8;
+ break;
+ }
+
+ if ((r = memcmp(addr_a, addr_b, length)) != 0)
+ return r;
+ else
+ return prefixlen_a - prefixlen_b;
+}
+
+/*
+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
+ const IPAddressOrRange *const *b)
+{
+ return IPAddressOrRange_cmp(*a, *b, 4);
+}
+
+/*
+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
+ const IPAddressOrRange *const *b)
+{
+ return IPAddressOrRange_cmp(*a, *b, 16);
+}
+
+/*
+ * Calculate whether a range collapses to a prefix.
+ * See last paragraph of RFC 3779 2.2.3.7.
+ */
+static int range_should_be_prefix(const unsigned char *min,
+ const unsigned char *max, const int length)
+{
+ unsigned char mask;
+ int i, j;
+
+ OPENSSL_assert(memcmp(min, max, length) <= 0);
+ for (i = 0; i < length && min[i] == max[i]; i++) ;
+ for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ;
+ if (i < j)
+ return -1;
+ if (i > j)
+ return i * 8;
+ mask = min[i] ^ max[i];
+ switch (mask) {
+ case 0x01:
+ j = 7;
+ break;
+ case 0x03:
+ j = 6;
+ break;
+ case 0x07:
+ j = 5;
+ break;
+ case 0x0F:
+ j = 4;
+ break;
+ case 0x1F:
+ j = 3;
+ break;
+ case 0x3F:
+ j = 2;
+ break;
+ case 0x7F:
+ j = 1;
+ break;
+ default:
+ return -1;
+ }
+ if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
+ return -1;
+ else
+ return i * 8 + j;
+}
+
+/*
+ * Construct a prefix.
+ */
+static int make_addressPrefix(IPAddressOrRange **result,
+ unsigned char *addr, const int prefixlen)
+{
+ int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
+ IPAddressOrRange *aor = IPAddressOrRange_new();
+
+ if (aor == NULL)
+ return 0;
+ aor->type = IPAddressOrRange_addressPrefix;
+ if (aor->u.addressPrefix == NULL &&
+ (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
+ goto err;
+ if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
+ goto err;
+ aor->u.addressPrefix->flags &= ~7;
+ aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (bitlen > 0) {
+ aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
+ aor->u.addressPrefix->flags |= 8 - bitlen;
+ }
+
+ *result = aor;
+ return 1;
+
+ err:
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Construct a range. If it can be expressed as a prefix,
+ * return a prefix instead. Doing this here simplifies
+ * the rest of the code considerably.
+ */
+static int make_addressRange(IPAddressOrRange **result,
+ unsigned char *min,
+ unsigned char *max, const int length)
+{
+ IPAddressOrRange *aor;
+ int i, prefixlen;
+
+ if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
+ return make_addressPrefix(result, min, prefixlen);
+
+ if ((aor = IPAddressOrRange_new()) == NULL)
+ return 0;
+ aor->type = IPAddressOrRange_addressRange;
+ OPENSSL_assert(aor->u.addressRange == NULL);
+ if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
+ goto err;
+ if (aor->u.addressRange->min == NULL &&
+ (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
+ goto err;
+ if (aor->u.addressRange->max == NULL &&
+ (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
+ goto err;
+
+ for (i = length; i > 0 && min[i - 1] == 0x00; --i) ;
+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
+ goto err;
+ aor->u.addressRange->min->flags &= ~7;
+ aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (i > 0) {
+ unsigned char b = min[i - 1];
+ int j = 1;
+ while ((b & (0xFFU >> j)) != 0)
+ ++j;
+ aor->u.addressRange->min->flags |= 8 - j;
+ }
+
+ for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ;
+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
+ goto err;
+ aor->u.addressRange->max->flags &= ~7;
+ aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (i > 0) {
+ unsigned char b = max[i - 1];
+ int j = 1;
+ while ((b & (0xFFU >> j)) != (0xFFU >> j))
+ ++j;
+ aor->u.addressRange->max->flags |= 8 - j;
+ }
+
+ *result = aor;
+ return 1;
+
+ err:
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Construct a new address family or find an existing one.
+ */
+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi)
+{
+ IPAddressFamily *f;
+ unsigned char key[3];
+ unsigned keylen;
+ int i;
+
+ key[0] = (afi >> 8) & 0xFF;
+ key[1] = afi & 0xFF;
+ if (safi != NULL) {
+ key[2] = *safi & 0xFF;
+ keylen = 3;
+ } else {
+ keylen = 2;
+ }
+
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ f = sk_IPAddressFamily_value(addr, i);
+ OPENSSL_assert(f->addressFamily->data != NULL);
+ if (f->addressFamily->length == keylen &&
+ !memcmp(f->addressFamily->data, key, keylen))
+ return f;
+ }
+
+ if ((f = IPAddressFamily_new()) == NULL)
+ goto err;
+ if (f->ipAddressChoice == NULL &&
+ (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
+ goto err;
+ if (f->addressFamily == NULL &&
+ (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
+ goto err;
+ if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
+ goto err;
+ if (!sk_IPAddressFamily_push(addr, f))
+ goto err;
+
+ return f;
+
+ err:
+ IPAddressFamily_free(f);
+ return NULL;
+}
+
+/*
+ * Add an inheritance element.
+ */
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+ const unsigned afi, const unsigned *safi)
+{
+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+ if (f == NULL ||
+ f->ipAddressChoice == NULL ||
+ (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+ f->ipAddressChoice->u.addressesOrRanges != NULL))
+ return 0;
+ if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+ f->ipAddressChoice->u.inherit != NULL)
+ return 1;
+ if (f->ipAddressChoice->u.inherit == NULL &&
+ (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
+ return 0;
+ f->ipAddressChoice->type = IPAddressChoice_inherit;
+ return 1;
+}
+
+/*
+ * Construct an IPAddressOrRange sequence, or return an existing one.
+ */
+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi)
+{
+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+ IPAddressOrRanges *aors = NULL;
+
+ if (f == NULL ||
+ f->ipAddressChoice == NULL ||
+ (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+ f->ipAddressChoice->u.inherit != NULL))
+ return NULL;
+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
+ aors = f->ipAddressChoice->u.addressesOrRanges;
+ if (aors != NULL)
+ return aors;
+ if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
+ return NULL;
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+ break;
+ case IANA_AFI_IPV6:
+ (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+ break;
+ }
+ f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
+ f->ipAddressChoice->u.addressesOrRanges = aors;
+ return aors;
+}
+
+/*
+ * Add a prefix.
+ */
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi,
+ unsigned char *a, const int prefixlen)
+{
+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+ IPAddressOrRange *aor;
+ if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
+ return 0;
+ if (sk_IPAddressOrRange_push(aors, aor))
+ return 1;
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Add a range.
+ */
+int v3_addr_add_range(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi,
+ unsigned char *min, unsigned char *max)
+{
+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+ IPAddressOrRange *aor;
+ int length = length_from_afi(afi);
+ if (aors == NULL)
+ return 0;
+ if (!make_addressRange(&aor, min, max, length))
+ return 0;
+ if (sk_IPAddressOrRange_push(aors, aor))
+ return 1;
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Extract min and max values from an IPAddressOrRange.
+ */
+static int extract_min_max(IPAddressOrRange *aor,
+ unsigned char *min, unsigned char *max, int length)
+{
+ if (aor == NULL || min == NULL || max == NULL)
+ return 0;
+ switch (aor->type) {
+ case IPAddressOrRange_addressPrefix:
+ return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
+ addr_expand(max, aor->u.addressPrefix, length, 0xFF));
+ case IPAddressOrRange_addressRange:
+ return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
+ addr_expand(max, aor->u.addressRange->max, length, 0xFF));
+ }
+ return 0;
+}
+
+/*
+ * Public wrapper for extract_min_max().
+ */
+int v3_addr_get_range(IPAddressOrRange *aor,
+ const unsigned afi,
+ unsigned char *min,
+ unsigned char *max, const int length)
+{
+ int afi_length = length_from_afi(afi);
+ if (aor == NULL || min == NULL || max == NULL ||
+ afi_length == 0 || length < afi_length ||
+ (aor->type != IPAddressOrRange_addressPrefix &&
+ aor->type != IPAddressOrRange_addressRange) ||
+ !extract_min_max(aor, min, max, afi_length))
+ return 0;
+
+ return afi_length;
+}
+
+/*
+ * Sort comparision function for a sequence of IPAddressFamily.
+ *
+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
+ * the ordering: I can read it as meaning that IPv6 without a SAFI
+ * comes before IPv4 with a SAFI, which seems pretty weird. The
+ * examples in appendix B suggest that the author intended the
+ * null-SAFI rule to apply only within a single AFI, which is what I
+ * would have expected and is what the following code implements.
+ */
+static int IPAddressFamily_cmp(const IPAddressFamily *const *a_,
+ const IPAddressFamily *const *b_)
+{
+ const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
+ const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
+ int len = ((a->length <= b->length) ? a->length : b->length);
+ int cmp = memcmp(a->data, b->data, len);
+ return cmp ? cmp : a->length - b->length;
+}
+
+/*
+ * Check whether an IPAddrBLocks is in canonical form.
+ */
+int v3_addr_is_canonical(IPAddrBlocks *addr)
+{
+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+ IPAddressOrRanges *aors;
+ int i, j, k;
+
+ /*
+ * Empty extension is cannonical.
+ */
+ if (addr == NULL)
+ return 1;
+
+ /*
+ * Check whether the top-level list is in order.
+ */
+ for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
+ const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
+ const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
+ if (IPAddressFamily_cmp(&a, &b) >= 0)
+ return 0;
+ }
+
+ /*
+ * Top level's ok, now check each address family.
+ */
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ int length = length_from_afi(v3_addr_get_afi(f));
+
+ /*
+ * Inheritance is canonical. Anything other than inheritance or
+ * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
+ */
+ if (f == NULL || f->ipAddressChoice == NULL)
+ return 0;
+ switch (f->ipAddressChoice->type) {
+ case IPAddressChoice_inherit:
+ continue;
+ case IPAddressChoice_addressesOrRanges:
+ break;
+ default:
+ return 0;
+ }
+
+ /*
+ * It's an IPAddressOrRanges sequence, check it.
+ */
+ aors = f->ipAddressChoice->u.addressesOrRanges;
+ if (sk_IPAddressOrRange_num(aors) == 0)
+ return 0;
+ for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
+
+ if (!extract_min_max(a, a_min, a_max, length) ||
+ !extract_min_max(b, b_min, b_max, length))
+ return 0;
+
+ /*
+ * Punt misordered list, overlapping start, or inverted range.
+ */
+ if (memcmp(a_min, b_min, length) >= 0 ||
+ memcmp(a_min, a_max, length) > 0 ||
+ memcmp(b_min, b_max, length) > 0)
+ return 0;
+
+ /*
+ * Punt if adjacent or overlapping. Check for adjacency by
+ * subtracting one from b_min first.
+ */
+ for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ;
+ if (memcmp(a_max, b_min, length) >= 0)
+ return 0;
+
+ /*
+ * Check for range that should be expressed as a prefix.
+ */
+ if (a->type == IPAddressOrRange_addressRange &&
+ range_should_be_prefix(a_min, a_max, length) >= 0)
+ return 0;
+ }
+
+ /*
+ * Check range to see if it's inverted or should be a
+ * prefix.
+ */
+ j = sk_IPAddressOrRange_num(aors) - 1;
+ {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+ if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+ if (!extract_min_max(a, a_min, a_max, length))
+ return 0;
+ if (memcmp(a_min, a_max, length) > 0 ||
+ range_should_be_prefix(a_min, a_max, length) >= 0)
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * If we made it through all that, we're happy.
+ */
+ return 1;
+}
+
+/*
+ * Whack an IPAddressOrRanges into canonical form.
+ */
+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
+ const unsigned afi)
+{
+ int i, j, length = length_from_afi(afi);
+
+ /*
+ * Sort the IPAddressOrRanges sequence.
+ */
+ sk_IPAddressOrRange_sort(aors);
+
+ /*
+ * Clean up representation issues, punt on duplicates or overlaps.
+ */
+ for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+
+ if (!extract_min_max(a, a_min, a_max, length) ||
+ !extract_min_max(b, b_min, b_max, length))
+ return 0;
+
+ /*
+ * Punt inverted ranges.
+ */
+ if (memcmp(a_min, a_max, length) > 0 ||
+ memcmp(b_min, b_max, length) > 0)
+ return 0;
+
+ /*
+ * Punt overlaps.
+ */
+ if (memcmp(a_max, b_min, length) >= 0)
+ return 0;
+
+ /*
+ * Merge if a and b are adjacent. We check for
+ * adjacency by subtracting one from b_min first.
+ */
+ for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ;
+ if (memcmp(a_max, b_min, length) == 0) {
+ IPAddressOrRange *merged;
+ if (!make_addressRange(&merged, a_min, b_max, length))
+ return 0;
+ (void)sk_IPAddressOrRange_set(aors, i, merged);
+ (void)sk_IPAddressOrRange_delete(aors, i + 1);
+ IPAddressOrRange_free(a);
+ IPAddressOrRange_free(b);
+ --i;
+ continue;
+ }
+ }
+
+ /*
+ * Check for inverted final range.
+ */
+ j = sk_IPAddressOrRange_num(aors) - 1;
+ {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+ if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+ extract_min_max(a, a_min, a_max, length);
+ if (memcmp(a_min, a_max, length) > 0)
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Whack an IPAddrBlocks extension into canonical form.
+ */
+int v3_addr_canonize(IPAddrBlocks *addr)
+{
+ int i;
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+ !IPAddressOrRanges_canonize(f->ipAddressChoice->
+ u.addressesOrRanges,
+ v3_addr_get_afi(f)))
+ return 0;
+ }
+ (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
+ sk_IPAddressFamily_sort(addr);
+ OPENSSL_assert(v3_addr_is_canonical(addr));
+ return 1;
+}
+
+/*
+ * v2i handler for the IPAddrBlocks extension.
+ */
+static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
+ struct v3_ext_ctx *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ static const char v4addr_chars[] = "0123456789.";
+ static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
+ IPAddrBlocks *addr = NULL;
+ char *s = NULL, *t;
+ int i;
+
+ if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+ unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
+ unsigned afi, *safi = NULL, safi_;
+ const char *addr_chars;
+ int prefixlen, i1, i2, delim, length;
+
+ if (!name_cmp(val->name, "IPv4")) {
+ afi = IANA_AFI_IPV4;
+ } else if (!name_cmp(val->name, "IPv6")) {
+ afi = IANA_AFI_IPV6;
+ } else if (!name_cmp(val->name, "IPv4-SAFI")) {
+ afi = IANA_AFI_IPV4;
+ safi = &safi_;
+ } else if (!name_cmp(val->name, "IPv6-SAFI")) {
+ afi = IANA_AFI_IPV6;
+ safi = &safi_;
+ } else {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_EXTENSION_NAME_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ addr_chars = v4addr_chars;
+ break;
+ case IANA_AFI_IPV6:
+ addr_chars = v6addr_chars;
+ break;
+ }
+
+ length = length_from_afi(afi);
+
+ /*
+ * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
+ * the other input values.
+ */
+ if (safi != NULL) {
+ *safi = strtoul(val->value, &t, 0);
+ t += strspn(t, " \t");
+ if (*safi > 0xFF || *t++ != ':') {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ t += strspn(t, " \t");
+ s = BUF_strdup(t);
+ } else {
+ s = BUF_strdup(val->value);
+ }
+ if (s == NULL) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * Check for inheritance. Not worth additional complexity to
+ * optimize this (seldom-used) case.
+ */
+ if (!strcmp(s, "inherit")) {
+ if (!v3_addr_add_inherit(addr, afi, safi)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_INVALID_INHERITANCE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ OPENSSL_free(s);
+ s = NULL;
+ continue;
+ }
+
+ i1 = strspn(s, addr_chars);
+ i2 = i1 + strspn(s + i1, " \t");
+ delim = s[i2++];
+ s[i1] = '\0';
+
+ if (a2i_ipadd(min, s) != length) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ switch (delim) {
+ case '/':
+ prefixlen = (int)strtoul(s + i2, &t, 10);
+ if (t == s + i2 || *t != '\0') {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ case '-':
+ i1 = i2 + strspn(s + i2, " \t");
+ i2 = i1 + strspn(s + i1, addr_chars);
+ if (i1 == i2 || s[i2] != '\0') {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (a2i_ipadd(max, s + i1) != length) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_INVALID_IPADDRESS);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (memcmp(min, max, length_from_afi(afi)) > 0) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!v3_addr_add_range(addr, afi, safi, min, max)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ case '\0':
+ if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ default:
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ OPENSSL_free(s);
+ s = NULL;
+ }
+
+ /*
+ * Canonize the result, then we're done.
+ */
+ if (!v3_addr_canonize(addr))
+ goto err;
+ return addr;
+
+ err:
+ OPENSSL_free(s);
+ sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+ return NULL;
+}
+
+/*
+ * OpenSSL dispatch
+ */
+const X509V3_EXT_METHOD v3_addr = {
+ NID_sbgp_ipAddrBlock, /* nid */
+ 0, /* flags */
+ ASN1_ITEM_ref(IPAddrBlocks), /* template */
+ 0, 0, 0, 0, /* old functions, ignored */
+ 0, /* i2s */
+ 0, /* s2i */
+ 0, /* i2v */
+ v2i_IPAddrBlocks, /* v2i */
+ i2r_IPAddrBlocks, /* i2r */
+ 0, /* r2i */
+ NULL /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension sues inheritance.
+ */
+int v3_addr_inherits(IPAddrBlocks *addr)
+{
+ int i;
+ if (addr == NULL)
+ return 0;
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ if (f->ipAddressChoice->type == IPAddressChoice_inherit)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int addr_contains(IPAddressOrRanges *parent,
+ IPAddressOrRanges *child, int length)
+{
+ unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
+ unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
+ int p, c;
+
+ if (child == NULL || parent == child)
+ return 1;
+ if (parent == NULL)
+ return 0;
+
+ p = 0;
+ for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
+ if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
+ c_min, c_max, length))
+ return -1;
+ for (;; p++) {
+ if (p >= sk_IPAddressOrRange_num(parent))
+ return 0;
+ if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
+ p_min, p_max, length))
+ return 0;
+ if (memcmp(p_max, c_max, length) < 0)
+ continue;
+ if (memcmp(p_min, c_min, length) > 0)
+ return 0;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Test whether a is a subset of b.
+ */
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
+{
+ int i;
+ if (a == NULL || a == 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);
+ for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
+ IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
+ int j = sk_IPAddressFamily_find(b, fa);
+ IPAddressFamily *fb;
+ fb = sk_IPAddressFamily_value(b, j);
+ if (fb == NULL)
+ return 0;
+ if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
+ fa->ipAddressChoice->u.addressesOrRanges,
+ length_from_afi(v3_addr_get_afi(fb))))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Validation error handling via callback.
+ */
+# define validation_err(_err_) \
+ do { \
+ if (ctx != NULL) { \
+ ctx->error = _err_; \
+ ctx->error_depth = i; \
+ ctx->current_cert = x; \
+ ret = ctx->verify_cb(0, ctx); \
+ } else { \
+ ret = 0; \
+ } \
+ if (!ret) \
+ goto done; \
+ } while (0)
+
+/*
+ * Core code for RFC 3779 2.3 path validation.
+ */
+static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
+ STACK_OF(X509) *chain,
+ IPAddrBlocks *ext)
+{
+ IPAddrBlocks *child = NULL;
+ int i, j, ret = 1;
+ X509 *x;
+
+ OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+ OPENSSL_assert(ctx != NULL || ext != NULL);
+ OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+ /*
+ * Figure out where to start. If we don't have an extension to
+ * check, we're done. Otherwise, check canonical form and
+ * set up for walking up the chain.
+ */
+ if (ext != NULL) {
+ i = -1;
+ x = NULL;
+ } else {
+ i = 0;
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if ((ext = x->rfc3779_addr) == NULL)
+ goto done;
+ }
+ if (!v3_addr_is_canonical(ext))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ (void)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;
+ goto done;
+ }
+
+ /*
+ * Now walk up the chain. No cert may list resources that its
+ * parent doesn't list.
+ */
+ for (i++; i < sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if (!v3_addr_is_canonical(x->rfc3779_addr))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ if (x->rfc3779_addr == NULL) {
+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+ if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ break;
+ }
+ }
+ continue;
+ }
+ (void)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);
+ IPAddressFamily *fp =
+ sk_IPAddressFamily_value(x->rfc3779_addr, k);
+ if (fp == NULL) {
+ if (fc->ipAddressChoice->type ==
+ IPAddressChoice_addressesOrRanges) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ break;
+ }
+ continue;
+ }
+ if (fp->ipAddressChoice->type ==
+ IPAddressChoice_addressesOrRanges) {
+ if (fc->ipAddressChoice->type == IPAddressChoice_inherit
+ || addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
+ fc->ipAddressChoice->u.addressesOrRanges,
+ length_from_afi(v3_addr_get_afi(fc))))
+ sk_IPAddressFamily_set(child, j, fp);
+ else
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+ }
+
+ /*
+ * 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);
+ if (fp->ipAddressChoice->type == IPAddressChoice_inherit
+ && sk_IPAddressFamily_find(child, fp) >= 0)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+
+ done:
+ sk_IPAddressFamily_free(child);
+ return ret;
+}
+
+# undef validation_err
+
+/*
+ * RFC 3779 2.3 path validation -- called from X509_verify_cert().
+ */
+int v3_addr_validate_path(X509_STORE_CTX *ctx)
+{
+ return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 2.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+ IPAddrBlocks *ext, int allow_inheritance)
+{
+ if (ext == NULL)
+ return 1;
+ if (chain == NULL || sk_X509_num(chain) == 0)
+ return 0;
+ if (!allow_inheritance && v3_addr_inherits(ext))
+ return 0;
+ return v3_addr_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_akey.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_akey.c
new file mode 100644
index 00000000..e920270e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_akey.c
@@ -0,0 +1,205 @@
+/* v3_akey.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+ AUTHORITY_KEYID *akeyid,
+ STACK_OF(CONF_VALUE)
+ *extlist);
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_akey_id = {
+ NID_authority_key_identifier,
+ X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
+ (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
+ 0, 0,
+ NULL
+};
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+ AUTHORITY_KEYID *akeyid,
+ STACK_OF(CONF_VALUE)
+ *extlist)
+{
+ char *tmp;
+ if (akeyid->keyid) {
+ tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
+ X509V3_add_value("keyid", tmp, &extlist);
+ OPENSSL_free(tmp);
+ }
+ if (akeyid->issuer)
+ extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
+ if (akeyid->serial) {
+ tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length);
+ X509V3_add_value("serial", tmp, &extlist);
+ OPENSSL_free(tmp);
+ }
+ return extlist;
+}
+
+/*-
+ * Currently two options:
+ * keyid: use the issuers subject keyid, the value 'always' means its is
+ * an error if the issuer certificate doesn't have a key id.
+ * issuer: use the issuers cert issuer and serial number. The default is
+ * to only use this if keyid is not present. With the option 'always'
+ * this is always included.
+ */
+
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ char keyid = 0, issuer = 0;
+ int i;
+ CONF_VALUE *cnf;
+ ASN1_OCTET_STRING *ikeyid = NULL;
+ X509_NAME *isname = NULL;
+ GENERAL_NAMES *gens = NULL;
+ GENERAL_NAME *gen = NULL;
+ ASN1_INTEGER *serial = NULL;
+ X509_EXTENSION *ext;
+ X509 *cert;
+ AUTHORITY_KEYID *akeyid;
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ cnf = sk_CONF_VALUE_value(values, i);
+ if (!strcmp(cnf->name, "keyid")) {
+ keyid = 1;
+ if (cnf->value && !strcmp(cnf->value, "always"))
+ keyid = 2;
+ } else if (!strcmp(cnf->name, "issuer")) {
+ issuer = 1;
+ if (cnf->value && !strcmp(cnf->value, "always"))
+ issuer = 2;
+ } else {
+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION);
+ ERR_add_error_data(2, "name=", cnf->name);
+ return NULL;
+ }
+ }
+
+ if (!ctx || !ctx->issuer_cert) {
+ if (ctx && (ctx->flags == CTX_TEST))
+ return AUTHORITY_KEYID_new();
+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
+ X509V3_R_NO_ISSUER_CERTIFICATE);
+ return NULL;
+ }
+
+ cert = ctx->issuer_cert;
+
+ if (keyid) {
+ i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
+ if ((i >= 0) && (ext = X509_get_ext(cert, i)))
+ ikeyid = X509V3_EXT_d2i(ext);
+ if (keyid == 2 && !ikeyid) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
+ X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+ return NULL;
+ }
+ }
+
+ if ((issuer && !ikeyid) || (issuer == 2)) {
+ isname = X509_NAME_dup(X509_get_issuer_name(cert));
+ serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+ if (!isname || !serial) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
+ X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+ goto err;
+ }
+ }
+
+ if (!(akeyid = AUTHORITY_KEYID_new()))
+ goto err;
+
+ if (isname) {
+ if (!(gens = sk_GENERAL_NAME_new_null())
+ || !(gen = GENERAL_NAME_new())
+ || !sk_GENERAL_NAME_push(gens, gen)) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen->type = GEN_DIRNAME;
+ gen->d.dirn = isname;
+ }
+
+ akeyid->issuer = gens;
+ akeyid->serial = serial;
+ akeyid->keyid = ikeyid;
+
+ return akeyid;
+
+ err:
+ X509_NAME_free(isname);
+ M_ASN1_INTEGER_free(serial);
+ M_ASN1_OCTET_STRING_free(ikeyid);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_akeya.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_akeya.c
new file mode 100644
index 00000000..2cc85b76
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_akeya.c
@@ -0,0 +1,73 @@
+/* v3_akey_asn1.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(AUTHORITY_KEYID) = {
+ ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
+ ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
+ ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
+} ASN1_SEQUENCE_END(AUTHORITY_KEYID)
+
+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_alt.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_alt.c
new file mode 100644
index 00000000..22ec2028
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_alt.c
@@ -0,0 +1,609 @@
+/* v3_alt.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
+static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
+static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
+
+const X509V3_EXT_METHOD v3_alt[] = {
+ {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+ (X509V3_EXT_V2I)v2i_subject_alt,
+ NULL, NULL, NULL},
+
+ {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+ 0, 0, 0, 0,
+ 0, 0,
+ (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,
+ GENERAL_NAMES *gens,
+ STACK_OF(CONF_VALUE) *ret)
+{
+ int i;
+ GENERAL_NAME *gen;
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ gen = sk_GENERAL_NAME_value(gens, i);
+ ret = i2v_GENERAL_NAME(method, gen, ret);
+ }
+ if (!ret)
+ return sk_CONF_VALUE_new_null();
+ return ret;
+}
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
+ GENERAL_NAME *gen,
+ STACK_OF(CONF_VALUE) *ret)
+{
+ unsigned char *p;
+ char oline[256], htmp[5];
+ int i;
+ switch (gen->type) {
+ case GEN_OTHERNAME:
+ X509V3_add_value("othername", "<unsupported>", &ret);
+ break;
+
+ case GEN_X400:
+ X509V3_add_value("X400Name", "<unsupported>", &ret);
+ break;
+
+ case GEN_EDIPARTY:
+ X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
+ break;
+
+ case GEN_EMAIL:
+ X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
+ break;
+
+ case GEN_DNS:
+ X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
+ break;
+
+ case GEN_URI:
+ X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
+ break;
+
+ case GEN_DIRNAME:
+ X509_NAME_oneline(gen->d.dirn, oline, 256);
+ X509V3_add_value("DirName", oline, &ret);
+ break;
+
+ case GEN_IPADD:
+ p = gen->d.ip->data;
+ if (gen->d.ip->length == 4)
+ BIO_snprintf(oline, sizeof oline,
+ "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ else if (gen->d.ip->length == 16) {
+ oline[0] = 0;
+ for (i = 0; i < 8; i++) {
+ BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
+ p += 2;
+ strcat(oline, htmp);
+ if (i != 7)
+ strcat(oline, ":");
+ }
+ } else {
+ X509V3_add_value("IP Address", "<invalid>", &ret);
+ break;
+ }
+ X509V3_add_value("IP Address", oline, &ret);
+ break;
+
+ case GEN_RID:
+ i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
+ X509V3_add_value("Registered ID", oline, &ret);
+ break;
+ }
+ return ret;
+}
+
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
+{
+ unsigned char *p;
+ int i;
+ switch (gen->type) {
+ case GEN_OTHERNAME:
+ BIO_printf(out, "othername:<unsupported>");
+ break;
+
+ case GEN_X400:
+ BIO_printf(out, "X400Name:<unsupported>");
+ break;
+
+ case GEN_EDIPARTY:
+ /* Maybe fix this: it is supported now */
+ BIO_printf(out, "EdiPartyName:<unsupported>");
+ break;
+
+ case GEN_EMAIL:
+ BIO_printf(out, "email:%s", gen->d.ia5->data);
+ break;
+
+ case GEN_DNS:
+ BIO_printf(out, "DNS:%s", gen->d.ia5->data);
+ break;
+
+ case GEN_URI:
+ BIO_printf(out, "URI:%s", gen->d.ia5->data);
+ break;
+
+ case GEN_DIRNAME:
+ BIO_printf(out, "DirName: ");
+ X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
+ break;
+
+ case GEN_IPADD:
+ p = gen->d.ip->data;
+ if (gen->d.ip->length == 4)
+ BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ else if (gen->d.ip->length == 16) {
+ BIO_printf(out, "IP Address");
+ for (i = 0; i < 8; i++) {
+ BIO_printf(out, ":%X", p[0] << 8 | p[1]);
+ p += 2;
+ }
+ BIO_puts(out, "\n");
+ } else {
+ BIO_printf(out, "IP Address:<invalid>");
+ break;
+ }
+ break;
+
+ case GEN_RID:
+ BIO_printf(out, "Registered ID");
+ i2a_ASN1_OBJECT(out, gen->d.rid);
+ break;
+ }
+ return 1;
+}
+
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
+{
+ GENERAL_NAMES *gens = NULL;
+ CONF_VALUE *cnf;
+ int i;
+ if (!(gens = sk_GENERAL_NAME_new_null())) {
+ X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!name_cmp(cnf->name, "issuer") && cnf->value &&
+ !strcmp(cnf->value, "copy")) {
+ if (!copy_issuer(ctx, gens))
+ goto err;
+ } else {
+ GENERAL_NAME *gen;
+ if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_GENERAL_NAME_push(gens, gen);
+ }
+ }
+ return gens;
+ err:
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
+}
+
+/* Append subject altname of issuer to issuer alt name of subject */
+
+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
+{
+ GENERAL_NAMES *ialt;
+ GENERAL_NAME *gen;
+ X509_EXTENSION *ext;
+ int i;
+ if (ctx && (ctx->flags == CTX_TEST))
+ return 1;
+ if (!ctx || !ctx->issuer_cert) {
+ X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS);
+ goto err;
+ }
+ i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
+ if (i < 0)
+ return 1;
+ if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
+ !(ialt = X509V3_EXT_d2i(ext))) {
+ X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR);
+ goto err;
+ }
+
+ for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
+ gen = sk_GENERAL_NAME_value(ialt, i);
+ if (!sk_GENERAL_NAME_push(gens, gen)) {
+ X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ sk_GENERAL_NAME_free(ialt);
+
+ return 1;
+
+ err:
+ return 0;
+
+}
+
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
+{
+ GENERAL_NAMES *gens = NULL;
+ CONF_VALUE *cnf;
+ int i;
+ if (!(gens = sk_GENERAL_NAME_new_null())) {
+ X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!name_cmp(cnf->name, "email") && cnf->value &&
+ !strcmp(cnf->value, "copy")) {
+ if (!copy_email(ctx, gens, 0))
+ goto err;
+ } else if (!name_cmp(cnf->name, "email") && cnf->value &&
+ !strcmp(cnf->value, "move")) {
+ if (!copy_email(ctx, gens, 1))
+ goto err;
+ } else {
+ GENERAL_NAME *gen;
+ if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_GENERAL_NAME_push(gens, gen);
+ }
+ }
+ return gens;
+ err:
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
+}
+
+/*
+ * Copy any email addresses in a certificate or request to GENERAL_NAMES
+ */
+
+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
+{
+ X509_NAME *nm;
+ ASN1_IA5STRING *email = NULL;
+ X509_NAME_ENTRY *ne;
+ GENERAL_NAME *gen = NULL;
+ int i;
+ if (ctx != NULL && ctx->flags == CTX_TEST)
+ return 1;
+ if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
+ X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS);
+ goto err;
+ }
+ /* Find the subject name */
+ if (ctx->subject_cert)
+ nm = X509_get_subject_name(ctx->subject_cert);
+ else
+ nm = X509_REQ_get_subject_name(ctx->subject_req);
+
+ /* Now add any email address(es) to STACK */
+ i = -1;
+ while ((i = X509_NAME_get_index_by_NID(nm,
+ NID_pkcs9_emailAddress, i)) >= 0) {
+ ne = X509_NAME_get_entry(nm, i);
+ email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
+ if (move_p) {
+ X509_NAME_delete_entry(nm, i);
+ X509_NAME_ENTRY_free(ne);
+ i--;
+ }
+ if (!email || !(gen = GENERAL_NAME_new())) {
+ X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen->d.ia5 = email;
+ email = NULL;
+ gen->type = GEN_EMAIL;
+ if (!sk_GENERAL_NAME_push(gens, gen)) {
+ X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen = NULL;
+ }
+
+ return 1;
+
+ err:
+ GENERAL_NAME_free(gen);
+ M_ASN1_IA5STRING_free(email);
+ return 0;
+
+}
+
+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;
+ CONF_VALUE *cnf;
+ int i;
+ if (!(gens = sk_GENERAL_NAME_new_null())) {
+ X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_GENERAL_NAME_push(gens, gen);
+ }
+ return gens;
+ err:
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
+}
+
+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 *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;
+ GENERAL_NAME *gen = NULL;
+
+ if (!value) {
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE);
+ return NULL;
+ }
+
+ if (out)
+ gen = out;
+ else {
+ gen = GENERAL_NAME_new();
+ if (gen == NULL) {
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ }
+
+ switch (gen_type) {
+ case GEN_URI:
+ case GEN_EMAIL:
+ case GEN_DNS:
+ is_string = 1;
+ break;
+
+ case GEN_RID:
+ {
+ ASN1_OBJECT *obj;
+ if (!(obj = OBJ_txt2obj(value, 0))) {
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT);
+ ERR_add_error_data(2, "value=", value);
+ goto err;
+ }
+ gen->d.rid = obj;
+ }
+ 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_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
+ ERR_add_error_data(2, "value=", value);
+ goto err;
+ }
+ break;
+
+ case GEN_DIRNAME:
+ if (!do_dirname(gen, value, ctx)) {
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
+ goto err;
+ }
+ break;
+
+ case GEN_OTHERNAME:
+ if (!do_othername(gen, value, ctx)) {
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
+ goto err;
+ }
+ break;
+ default:
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
+ goto err;
+ }
+
+ if (is_string) {
+ if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
+ !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
+ strlen(value))) {
+ X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ gen->type = gen_type;
+
+ return gen;
+
+ err:
+ if (!out)
+ GENERAL_NAME_free(gen);
+ 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;
+ int objlen;
+ if (!(p = strchr(value, ';')))
+ return 0;
+ if (!(gen->d.otherName = OTHERNAME_new()))
+ return 0;
+ /*
+ * Free this up because we will overwrite it. no need to free type_id
+ * because it is static
+ */
+ ASN1_TYPE_free(gen->d.otherName->value);
+ if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
+ return 0;
+ objlen = p - value;
+ objtmp = OPENSSL_malloc(objlen + 1);
+ strncpy(objtmp, value, objlen);
+ objtmp[objlen] = 0;
+ gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
+ OPENSSL_free(objtmp);
+ if (!gen->d.otherName->type_id)
+ return 0;
+ return 1;
+}
+
+static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
+{
+ int ret = 0;
+ STACK_OF(CONF_VALUE) *sk = NULL;
+ X509_NAME *nm = NULL;
+ if (!(nm = X509_NAME_new()))
+ goto err;
+ sk = X509V3_get_section(ctx, value);
+ if (!sk) {
+ X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
+ ERR_add_error_data(2, "section=", value);
+ goto err;
+ }
+ /* FIXME: should allow other character types... */
+ ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
+ if (!ret)
+ goto err;
+ gen->d.dirn = nm;
+
+err:
+ if (ret == 0)
+ X509_NAME_free(nm);
+ X509V3_section_free(ctx, sk);
+ return ret;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_asid.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_asid.c
new file mode 100644
index 00000000..2a32c9d0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_asid.c
@@ -0,0 +1,896 @@
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * 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).
+ */
+
+/*
+ * Implementation of RFC 3779 section 3.2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
+ */
+
+ASN1_SEQUENCE(ASRange) = {
+ ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
+ ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ASRange)
+
+ASN1_CHOICE(ASIdOrRange) = {
+ ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER),
+ ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
+} ASN1_CHOICE_END(ASIdOrRange)
+
+ASN1_CHOICE(ASIdentifierChoice) = {
+ ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL),
+ ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
+} ASN1_CHOICE_END(ASIdentifierChoice)
+
+ASN1_SEQUENCE(ASIdentifiers) = {
+ ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
+ ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1)
+} ASN1_SEQUENCE_END(ASIdentifiers)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
+
+/*
+ * i2r method for an ASIdentifierChoice.
+ */
+static int i2r_ASIdentifierChoice(BIO *out,
+ ASIdentifierChoice *choice,
+ int indent, const char *msg)
+{
+ int i;
+ char *s;
+ if (choice == NULL)
+ return 1;
+ BIO_printf(out, "%*s%s:\n", indent, "", msg);
+ switch (choice->type) {
+ case ASIdentifierChoice_inherit:
+ BIO_printf(out, "%*sinherit\n", indent + 2, "");
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
+ ASIdOrRange *aor =
+ sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ switch (aor->type) {
+ case ASIdOrRange_id:
+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
+ return 0;
+ BIO_printf(out, "%*s%s\n", indent + 2, "", s);
+ OPENSSL_free(s);
+ break;
+ case ASIdOrRange_range:
+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
+ return 0;
+ BIO_printf(out, "%*s%s-", indent + 2, "", s);
+ OPENSSL_free(s);
+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
+ return 0;
+ BIO_printf(out, "%s\n", s);
+ OPENSSL_free(s);
+ break;
+ default:
+ return 0;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * i2r method for an ASIdentifier extension.
+ */
+static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
+ void *ext, BIO *out, int indent)
+{
+ ASIdentifiers *asid = ext;
+ return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
+ "Autonomous System Numbers") &&
+ i2r_ASIdentifierChoice(out, asid->rdi, indent,
+ "Routing Domain Identifiers"));
+}
+
+/*
+ * Sort comparision function for a sequence of ASIdOrRange elements.
+ */
+static int ASIdOrRange_cmp(const ASIdOrRange *const *a_,
+ const ASIdOrRange *const *b_)
+{
+ const ASIdOrRange *a = *a_, *b = *b_;
+
+ OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
+ (a->type == ASIdOrRange_range && a->u.range != NULL &&
+ a->u.range->min != NULL && a->u.range->max != NULL));
+
+ OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
+ (b->type == ASIdOrRange_range && b->u.range != NULL &&
+ b->u.range->min != NULL && b->u.range->max != NULL));
+
+ if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
+ return ASN1_INTEGER_cmp(a->u.id, b->u.id);
+
+ if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
+ int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
+ return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max,
+ b->u.range->max);
+ }
+
+ if (a->type == ASIdOrRange_id)
+ return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
+ else
+ return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
+}
+
+/*
+ * Add an inherit element.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which)
+{
+ ASIdentifierChoice **choice;
+ if (asid == NULL)
+ return 0;
+ switch (which) {
+ case V3_ASID_ASNUM:
+ choice = &asid->asnum;
+ break;
+ case V3_ASID_RDI:
+ choice = &asid->rdi;
+ break;
+ default:
+ return 0;
+ }
+ if (*choice == NULL) {
+ if ((*choice = ASIdentifierChoice_new()) == NULL)
+ return 0;
+ OPENSSL_assert((*choice)->u.inherit == NULL);
+ if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
+ return 0;
+ (*choice)->type = ASIdentifierChoice_inherit;
+ }
+ return (*choice)->type == ASIdentifierChoice_inherit;
+}
+
+/*
+ * Add an ID or range to an ASIdentifierChoice.
+ */
+int v3_asid_add_id_or_range(ASIdentifiers *asid,
+ int which, ASN1_INTEGER *min, ASN1_INTEGER *max)
+{
+ ASIdentifierChoice **choice;
+ ASIdOrRange *aor;
+ if (asid == NULL)
+ return 0;
+ switch (which) {
+ case V3_ASID_ASNUM:
+ choice = &asid->asnum;
+ break;
+ case V3_ASID_RDI:
+ choice = &asid->rdi;
+ break;
+ default:
+ return 0;
+ }
+ if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
+ return 0;
+ if (*choice == NULL) {
+ if ((*choice = ASIdentifierChoice_new()) == NULL)
+ return 0;
+ OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
+ (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
+ if ((*choice)->u.asIdsOrRanges == NULL)
+ return 0;
+ (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
+ }
+ if ((aor = ASIdOrRange_new()) == NULL)
+ return 0;
+ if (max == NULL) {
+ aor->type = ASIdOrRange_id;
+ aor->u.id = min;
+ } else {
+ aor->type = ASIdOrRange_range;
+ if ((aor->u.range = ASRange_new()) == NULL)
+ goto err;
+ ASN1_INTEGER_free(aor->u.range->min);
+ aor->u.range->min = min;
+ ASN1_INTEGER_free(aor->u.range->max);
+ aor->u.range->max = max;
+ }
+ if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
+ goto err;
+ return 1;
+
+ err:
+ ASIdOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Extract min and max values from an ASIdOrRange.
+ */
+static void extract_min_max(ASIdOrRange *aor,
+ ASN1_INTEGER **min, ASN1_INTEGER **max)
+{
+ OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+ switch (aor->type) {
+ case ASIdOrRange_id:
+ *min = aor->u.id;
+ *max = aor->u.id;
+ return;
+ case ASIdOrRange_range:
+ *min = aor->u.range->min;
+ *max = aor->u.range->max;
+ return;
+ }
+}
+
+/*
+ * Check whether an ASIdentifierChoice is in canonical form.
+ */
+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
+{
+ ASN1_INTEGER *a_max_plus_one = NULL;
+ BIGNUM *bn = NULL;
+ int i, ret = 0;
+
+ /*
+ * Empty element or inheritance is canonical.
+ */
+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+ return 1;
+
+ /*
+ * If not a list, or if empty list, it's broken.
+ */
+ if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
+ return 0;
+
+ /*
+ * It's a list, check it.
+ */
+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+ ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+ extract_min_max(a, &a_min, &a_max);
+ extract_min_max(b, &b_min, &b_max);
+
+ /*
+ * Punt misordered list, overlapping start, or inverted range.
+ */
+ if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
+ ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+ ASN1_INTEGER_cmp(b_min, b_max) > 0)
+ goto done;
+
+ /*
+ * Calculate a_max + 1 to check for adjacency.
+ */
+ if ((bn == NULL && (bn = BN_new()) == NULL) ||
+ ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+ !BN_add_word(bn, 1) ||
+ (a_max_plus_one =
+ BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
+ ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ /*
+ * Punt if adjacent or overlapping.
+ */
+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
+ goto done;
+ }
+
+ /*
+ * Check for inverted range.
+ */
+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+ {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASN1_INTEGER *a_min, *a_max;
+ if (a != NULL && a->type == ASIdOrRange_range) {
+ extract_min_max(a, &a_min, &a_max);
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+ goto done;
+ }
+ }
+
+ ret = 1;
+
+ done:
+ ASN1_INTEGER_free(a_max_plus_one);
+ BN_free(bn);
+ return ret;
+}
+
+/*
+ * Check whether an ASIdentifier extension is in canonical form.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid)
+{
+ return (asid == NULL ||
+ (ASIdentifierChoice_is_canonical(asid->asnum) &&
+ ASIdentifierChoice_is_canonical(asid->rdi)));
+}
+
+/*
+ * Whack an ASIdentifierChoice into canonical form.
+ */
+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
+{
+ ASN1_INTEGER *a_max_plus_one = NULL;
+ BIGNUM *bn = NULL;
+ int i, ret = 0;
+
+ /*
+ * Nothing to do for empty element or inheritance.
+ */
+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+ return 1;
+
+ /*
+ * If not a list, or if empty list, it's broken.
+ */
+ if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ return 0;
+ }
+
+ /*
+ * We have a non-empty list. Sort it.
+ */
+ sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
+
+ /*
+ * Now check for errors and suboptimal encoding, rejecting the
+ * former and fixing the latter.
+ */
+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+ ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+ extract_min_max(a, &a_min, &a_max);
+ extract_min_max(b, &b_min, &b_max);
+
+ /*
+ * Make sure we're properly sorted (paranoia).
+ */
+ OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
+
+ /*
+ * Punt inverted ranges.
+ */
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+ ASN1_INTEGER_cmp(b_min, b_max) > 0)
+ goto done;
+
+ /*
+ * Check for overlaps.
+ */
+ if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ goto done;
+ }
+
+ /*
+ * Calculate a_max + 1 to check for adjacency.
+ */
+ if ((bn == NULL && (bn = BN_new()) == NULL) ||
+ ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+ !BN_add_word(bn, 1) ||
+ (a_max_plus_one =
+ BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ /*
+ * If a and b are adjacent, merge them.
+ */
+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
+ ASRange *r;
+ switch (a->type) {
+ case ASIdOrRange_id:
+ if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+ r->min = a_min;
+ r->max = b_max;
+ a->type = ASIdOrRange_range;
+ a->u.range = r;
+ break;
+ case ASIdOrRange_range:
+ ASN1_INTEGER_free(a->u.range->max);
+ a->u.range->max = b_max;
+ break;
+ }
+ switch (b->type) {
+ case ASIdOrRange_id:
+ b->u.id = NULL;
+ break;
+ case ASIdOrRange_range:
+ b->u.range->max = NULL;
+ break;
+ }
+ ASIdOrRange_free(b);
+ (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+ i--;
+ continue;
+ }
+ }
+
+ /*
+ * Check for final inverted range.
+ */
+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+ {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASN1_INTEGER *a_min, *a_max;
+ if (a != NULL && a->type == ASIdOrRange_range) {
+ extract_min_max(a, &a_min, &a_max);
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+ goto done;
+ }
+ }
+
+ OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
+
+ ret = 1;
+
+ done:
+ ASN1_INTEGER_free(a_max_plus_one);
+ BN_free(bn);
+ return ret;
+}
+
+/*
+ * Whack an ASIdentifier extension into canonical form.
+ */
+int v3_asid_canonize(ASIdentifiers *asid)
+{
+ return (asid == NULL ||
+ (ASIdentifierChoice_canonize(asid->asnum) &&
+ ASIdentifierChoice_canonize(asid->rdi)));
+}
+
+/*
+ * v2i method for an ASIdentifier extension.
+ */
+static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
+ struct v3_ext_ctx *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ ASN1_INTEGER *min = NULL, *max = NULL;
+ ASIdentifiers *asid = NULL;
+ int i;
+
+ if ((asid = ASIdentifiers_new()) == NULL) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+ int i1, i2, i3, is_range, which;
+
+ /*
+ * Figure out whether this is an AS or an RDI.
+ */
+ if (!name_cmp(val->name, "AS")) {
+ which = V3_ASID_ASNUM;
+ } else if (!name_cmp(val->name, "RDI")) {
+ which = V3_ASID_RDI;
+ } else {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+ X509V3_R_EXTENSION_NAME_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ /*
+ * Handle inheritance.
+ */
+ if (!strcmp(val->value, "inherit")) {
+ if (v3_asid_add_inherit(asid, which))
+ continue;
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+ X509V3_R_INVALID_INHERITANCE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ /*
+ * Number, range, or mistake, pick it apart and figure out which.
+ */
+ i1 = strspn(val->value, "0123456789");
+ if (val->value[i1] == '\0') {
+ is_range = 0;
+ } else {
+ is_range = 1;
+ i2 = i1 + strspn(val->value + i1, " \t");
+ if (val->value[i2] != '-') {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+ X509V3_R_INVALID_ASNUMBER);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ i2++;
+ i2 = i2 + strspn(val->value + i2, " \t");
+ i3 = i2 + strspn(val->value + i2, "0123456789");
+ if (val->value[i3] != '\0') {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+ X509V3_R_INVALID_ASRANGE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+
+ /*
+ * Syntax is ok, read and add it.
+ */
+ if (!is_range) {
+ if (!X509V3_get_value_int(val, &min)) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else {
+ char *s = BUF_strdup(val->value);
+ if (s == NULL) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s[i1] = '\0';
+ min = s2i_ASN1_INTEGER(NULL, s);
+ max = s2i_ASN1_INTEGER(NULL, s + i2);
+ OPENSSL_free(s);
+ if (min == NULL || max == NULL) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (ASN1_INTEGER_cmp(min, max) > 0) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ goto err;
+ }
+ }
+ if (!v3_asid_add_id_or_range(asid, which, min, max)) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ min = max = NULL;
+ }
+
+ /*
+ * Canonize the result, then we're done.
+ */
+ if (!v3_asid_canonize(asid))
+ goto err;
+ return asid;
+
+ err:
+ ASIdentifiers_free(asid);
+ ASN1_INTEGER_free(min);
+ ASN1_INTEGER_free(max);
+ return NULL;
+}
+
+/*
+ * OpenSSL dispatch.
+ */
+const X509V3_EXT_METHOD v3_asid = {
+ NID_sbgp_autonomousSysNum, /* nid */
+ 0, /* flags */
+ ASN1_ITEM_ref(ASIdentifiers), /* template */
+ 0, 0, 0, 0, /* old functions, ignored */
+ 0, /* i2s */
+ 0, /* s2i */
+ 0, /* i2v */
+ v2i_ASIdentifiers, /* v2i */
+ i2r_ASIdentifiers, /* i2r */
+ 0, /* r2i */
+ NULL /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension uses inheritance.
+ */
+int v3_asid_inherits(ASIdentifiers *asid)
+{
+ return (asid != NULL &&
+ ((asid->asnum != NULL &&
+ asid->asnum->type == ASIdentifierChoice_inherit) ||
+ (asid->rdi != NULL &&
+ asid->rdi->type == ASIdentifierChoice_inherit)));
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
+{
+ ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
+ int p, c;
+
+ if (child == NULL || parent == child)
+ return 1;
+ if (parent == NULL)
+ return 0;
+
+ p = 0;
+ for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
+ extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
+ for (;; p++) {
+ if (p >= sk_ASIdOrRange_num(parent))
+ return 0;
+ extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
+ if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
+ continue;
+ if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
+ return 0;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Test whether a is a subet of b.
+ */
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
+{
+ return (a == NULL ||
+ a == b ||
+ (b != NULL &&
+ !v3_asid_inherits(a) &&
+ !v3_asid_inherits(b) &&
+ asid_contains(b->asnum->u.asIdsOrRanges,
+ a->asnum->u.asIdsOrRanges) &&
+ asid_contains(b->rdi->u.asIdsOrRanges,
+ a->rdi->u.asIdsOrRanges)));
+}
+
+/*
+ * Validation error handling via callback.
+ */
+# define validation_err(_err_) \
+ do { \
+ if (ctx != NULL) { \
+ ctx->error = _err_; \
+ ctx->error_depth = i; \
+ ctx->current_cert = x; \
+ ret = ctx->verify_cb(0, ctx); \
+ } else { \
+ ret = 0; \
+ } \
+ if (!ret) \
+ goto done; \
+ } while (0)
+
+/*
+ * Core code for RFC 3779 3.3 path validation.
+ */
+static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
+ STACK_OF(X509) *chain,
+ ASIdentifiers *ext)
+{
+ ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
+ int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
+ X509 *x;
+
+ OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+ OPENSSL_assert(ctx != NULL || ext != NULL);
+ OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+ /*
+ * Figure out where to start. If we don't have an extension to
+ * check, we're done. Otherwise, check canonical form and
+ * set up for walking up the chain.
+ */
+ if (ext != NULL) {
+ i = -1;
+ x = NULL;
+ } else {
+ i = 0;
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if ((ext = x->rfc3779_asid) == NULL)
+ goto done;
+ }
+ if (!v3_asid_is_canonical(ext))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ if (ext->asnum != NULL) {
+ switch (ext->asnum->type) {
+ case ASIdentifierChoice_inherit:
+ inherit_as = 1;
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ child_as = ext->asnum->u.asIdsOrRanges;
+ break;
+ }
+ }
+ if (ext->rdi != NULL) {
+ switch (ext->rdi->type) {
+ case ASIdentifierChoice_inherit:
+ inherit_rdi = 1;
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ child_rdi = ext->rdi->u.asIdsOrRanges;
+ break;
+ }
+ }
+
+ /*
+ * Now walk up the chain. Extensions must be in canonical form, no
+ * cert may list resources that its parent doesn't list.
+ */
+ for (i++; i < sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if (x->rfc3779_asid == NULL) {
+ if (child_as != NULL || child_rdi != NULL)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ continue;
+ }
+ if (!v3_asid_is_canonical(x->rfc3779_asid))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ child_as = NULL;
+ inherit_as = 0;
+ }
+ if (x->rfc3779_asid->asnum != NULL &&
+ x->rfc3779_asid->asnum->type ==
+ ASIdentifierChoice_asIdsOrRanges) {
+ if (inherit_as
+ || asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges,
+ child_as)) {
+ child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+ inherit_as = 0;
+ } else {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+ if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ child_rdi = NULL;
+ inherit_rdi = 0;
+ }
+ if (x->rfc3779_asid->rdi != NULL &&
+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
+ if (inherit_rdi ||
+ asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges,
+ child_rdi)) {
+ child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+ inherit_rdi = 0;
+ } else {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+ }
+
+ /*
+ * Trust anchor can't inherit.
+ */
+ OPENSSL_assert(x != NULL);
+ if (x->rfc3779_asid != NULL) {
+ if (x->rfc3779_asid->asnum != NULL &&
+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ if (x->rfc3779_asid->rdi != NULL &&
+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+
+ done:
+ return ret;
+}
+
+# undef validation_err
+
+/*
+ * RFC 3779 3.3 path validation -- called from X509_verify_cert().
+ */
+int v3_asid_validate_path(X509_STORE_CTX *ctx)
+{
+ return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 3.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+ ASIdentifiers *ext, int allow_inheritance)
+{
+ if (ext == NULL)
+ return 1;
+ if (chain == NULL || sk_X509_num(chain) == 0)
+ return 0;
+ if (!allow_inheritance && v3_asid_inherits(ext))
+ return 0;
+ return v3_asid_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_bcons.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_bcons.c
new file mode 100644
index 00000000..dc00b9cb
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_bcons.c
@@ -0,0 +1,132 @@
+/* v3_bcons.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+ BASIC_CONSTRAINTS *bcons,
+ STACK_OF(CONF_VALUE)
+ *extlist);
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_bcons = {
+ NID_basic_constraints, 0,
+ ASN1_ITEM_ref(BASIC_CONSTRAINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS,
+ (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
+ NULL, NULL,
+ NULL
+};
+
+ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
+ ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
+ ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
+
+IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+ BASIC_CONSTRAINTS *bcons,
+ STACK_OF(CONF_VALUE)
+ *extlist)
+{
+ X509V3_add_value_bool("CA", bcons->ca, &extlist);
+ X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
+ return extlist;
+}
+
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ BASIC_CONSTRAINTS *bcons = NULL;
+ CONF_VALUE *val;
+ int i;
+ if (!(bcons = BASIC_CONSTRAINTS_new())) {
+ X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ val = sk_CONF_VALUE_value(values, i);
+ if (!strcmp(val->name, "CA")) {
+ if (!X509V3_get_value_bool(val, &bcons->ca))
+ goto err;
+ } else if (!strcmp(val->name, "pathlen")) {
+ if (!X509V3_get_value_int(val, &bcons->pathlen))
+ goto err;
+ } else {
+ X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+ return bcons;
+ err:
+ BASIC_CONSTRAINTS_free(bcons);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_bitst.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_bitst.c
new file mode 100644
index 00000000..b7bb3b55
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_bitst.c
@@ -0,0 +1,142 @@
+/* v3_bitst.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static BIT_STRING_BITNAME ns_cert_type_table[] = {
+ {0, "SSL Client", "client"},
+ {1, "SSL Server", "server"},
+ {2, "S/MIME", "email"},
+ {3, "Object Signing", "objsign"},
+ {4, "Unused", "reserved"},
+ {5, "SSL CA", "sslCA"},
+ {6, "S/MIME CA", "emailCA"},
+ {7, "Object Signing CA", "objCA"},
+ {-1, NULL, NULL}
+};
+
+static BIT_STRING_BITNAME key_usage_type_table[] = {
+ {0, "Digital Signature", "digitalSignature"},
+ {1, "Non Repudiation", "nonRepudiation"},
+ {2, "Key Encipherment", "keyEncipherment"},
+ {3, "Data Encipherment", "dataEncipherment"},
+ {4, "Key Agreement", "keyAgreement"},
+ {5, "Certificate Sign", "keyCertSign"},
+ {6, "CRL Sign", "cRLSign"},
+ {7, "Encipher Only", "encipherOnly"},
+ {8, "Decipher Only", "decipherOnly"},
+ {-1, NULL, NULL}
+};
+
+const X509V3_EXT_METHOD v3_nscert =
+EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
+const X509V3_EXT_METHOD v3_key_usage =
+EXT_BITSTRING(NID_key_usage, key_usage_type_table);
+
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+ ASN1_BIT_STRING *bits,
+ STACK_OF(CONF_VALUE) *ret)
+{
+ BIT_STRING_BITNAME *bnam;
+ for (bnam = method->usr_data; bnam->lname; bnam++) {
+ if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
+ X509V3_add_value(bnam->lname, NULL, &ret);
+ }
+ return ret;
+}
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
+{
+ CONF_VALUE *val;
+ ASN1_BIT_STRING *bs;
+ int i;
+ BIT_STRING_BITNAME *bnam;
+ if (!(bs = M_ASN1_BIT_STRING_new())) {
+ X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ for (bnam = method->usr_data; bnam->lname; bnam++) {
+ if (!strcmp(bnam->sname, val->name) ||
+ !strcmp(bnam->lname, val->name)) {
+ if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
+ X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
+ ERR_R_MALLOC_FAILURE);
+ M_ASN1_BIT_STRING_free(bs);
+ return NULL;
+ }
+ break;
+ }
+ }
+ if (!bnam->lname) {
+ X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
+ X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+ X509V3_conf_err(val);
+ M_ASN1_BIT_STRING_free(bs);
+ return NULL;
+ }
+ }
+ return bs;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_conf.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_conf.c
new file mode 100644
index 00000000..eeff8bd1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_conf.c
@@ -0,0 +1,532 @@
+/* v3_conf.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-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
+ * 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).
+ *
+ */
+/* extension creation utilities */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+static int v3_check_critical(char **value);
+static int v3_check_generic(char **value);
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+ int crit, char *value);
+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(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)
+{
+ int crit;
+ int ext_type;
+ X509_EXTENSION *ret;
+ crit = v3_check_critical(&value);
+ if ((ext_type = v3_check_generic(&value)))
+ return v3_generic_extension(name, value, crit, ext_type, ctx);
+ ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
+ if (!ret) {
+ X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION);
+ ERR_add_error_data(4, "name=", name, ", value=", value);
+ }
+ return ret;
+}
+
+/* CONF *conf: Config file */
+/* char *value: Value */
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+ char *value)
+{
+ int crit;
+ int ext_type;
+ crit = v3_check_critical(&value);
+ if ((ext_type = v3_check_generic(&value)))
+ return v3_generic_extension(OBJ_nid2sn(ext_nid),
+ value, crit, ext_type, ctx);
+ return do_ext_nconf(conf, ctx, ext_nid, crit, value);
+}
+
+/* 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)
+{
+ const X509V3_EXT_METHOD *method;
+ X509_EXTENSION *ext;
+ STACK_OF(CONF_VALUE) *nval;
+ void *ext_struc;
+ if (ext_nid == NID_undef) {
+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME);
+ return NULL;
+ }
+ if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION);
+ return NULL;
+ }
+ /* Now get internal extension representation based on type */
+ if (method->v2i) {
+ if (*value == '@')
+ nval = NCONF_get_section(conf, value + 1);
+ else
+ nval = X509V3_parse_list(value);
+ if (sk_CONF_VALUE_num(nval) <= 0) {
+ X509V3err(X509V3_F_DO_EXT_NCONF,
+ X509V3_R_INVALID_EXTENSION_STRING);
+ ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
+ value);
+ return NULL;
+ }
+ ext_struc = method->v2i(method, ctx, nval);
+ if (*value != '@')
+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+ if (!ext_struc)
+ return NULL;
+ } else if (method->s2i) {
+ if (!(ext_struc = method->s2i(method, ctx, value)))
+ return NULL;
+ } else if (method->r2i) {
+ if (!ctx->db || !ctx->db_meth) {
+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE);
+ return NULL;
+ }
+ if (!(ext_struc = method->r2i(method, ctx, value)))
+ return NULL;
+ } else {
+ X509V3err(X509V3_F_DO_EXT_NCONF,
+ X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+ ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
+ return NULL;
+ }
+
+ ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
+ if (method->it)
+ ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
+ else
+ method->ext_free(ext_struc);
+ return ext;
+
+}
+
+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;
+ ASN1_OCTET_STRING *ext_oct;
+ X509_EXTENSION *ext;
+ /* Convert internal representation to DER */
+ if (method->it) {
+ ext_der = NULL;
+ ext_len =
+ ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
+ if (ext_len < 0)
+ goto merr;
+ } else {
+ unsigned char *p;
+ ext_len = method->i2d(ext_struc, NULL);
+ if (!(ext_der = OPENSSL_malloc(ext_len)))
+ goto merr;
+ p = ext_der;
+ method->i2d(ext_struc, &p);
+ }
+ if (!(ext_oct = M_ASN1_OCTET_STRING_new()))
+ goto merr;
+ ext_oct->data = ext_der;
+ ext_oct->length = ext_len;
+
+ ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
+ if (!ext)
+ goto merr;
+ M_ASN1_OCTET_STRING_free(ext_oct);
+
+ return ext;
+
+ merr:
+ X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE);
+ return NULL;
+
+}
+
+/* Given an internal structure, nid and critical flag create an extension */
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
+{
+ const X509V3_EXT_METHOD *method;
+ if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+ X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION);
+ return NULL;
+ }
+ return do_ext_i2d(method, ext_nid, crit, ext_struc);
+}
+
+/* Check the extension string for critical flag */
+static int v3_check_critical(char **value)
+{
+ char *p = *value;
+ if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
+ return 0;
+ p += 9;
+ while (isspace((unsigned char)*p))
+ p++;
+ *value = p;
+ return 1;
+}
+
+/* Check extension string for generic extension and return the type */
+static int v3_check_generic(char **value)
+{
+ int gen_type = 0;
+ char *p = *value;
+ if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
+ p += 4;
+ gen_type = 1;
+ } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
+ p += 5;
+ gen_type = 2;
+ } else
+ return 0;
+
+ while (isspace((unsigned char)*p))
+ p++;
+ *value = p;
+ return gen_type;
+}
+
+/* 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)
+{
+ unsigned char *ext_der = NULL;
+ long ext_len;
+ ASN1_OBJECT *obj = NULL;
+ ASN1_OCTET_STRING *oct = NULL;
+ X509_EXTENSION *extension = NULL;
+ if (!(obj = OBJ_txt2obj(ext, 0))) {
+ X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
+ X509V3_R_EXTENSION_NAME_ERROR);
+ ERR_add_error_data(2, "name=", ext);
+ goto err;
+ }
+
+ if (gen_type == 1)
+ ext_der = string_to_hex(value, &ext_len);
+ else if (gen_type == 2)
+ ext_der = generic_asn1(value, ctx, &ext_len);
+
+ if (ext_der == NULL) {
+ X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ ERR_add_error_data(2, "value=", value);
+ goto err;
+ }
+
+ if (!(oct = M_ASN1_OCTET_STRING_new())) {
+ X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ oct->data = ext_der;
+ oct->length = ext_len;
+ ext_der = NULL;
+
+ extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
+
+ err:
+ ASN1_OBJECT_free(obj);
+ M_ASN1_OCTET_STRING_free(oct);
+ if (ext_der)
+ OPENSSL_free(ext_der);
+ return extension;
+
+}
+
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
+ long *ext_len)
+{
+ ASN1_TYPE *typ;
+ unsigned char *ext_der = NULL;
+ typ = ASN1_generate_v3(value, ctx);
+ if (typ == NULL)
+ return NULL;
+ *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
+ ASN1_TYPE_free(typ);
+ return ext_der;
+}
+
+/*
+ * This is the main function: add a bunch of extensions based on a config
+ * file section to an extension STACK.
+ */
+
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
+ STACK_OF(X509_EXTENSION) **sk)
+{
+ X509_EXTENSION *ext;
+ STACK_OF(CONF_VALUE) *nval;
+ CONF_VALUE *val;
+ int i;
+ if (!(nval = NCONF_get_section(conf, section)))
+ return 0;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
+ return 0;
+ if (sk)
+ X509v3_add_ext(sk, ext, -1);
+ X509_EXTENSION_free(ext);
+ }
+ return 1;
+}
+
+/*
+ * 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)
+{
+ STACK_OF(X509_EXTENSION) **sk = NULL;
+ if (cert)
+ sk = &cert->cert_info->extensions;
+ return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
+
+/* Same as above but for a CRL */
+
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+ X509_CRL *crl)
+{
+ STACK_OF(X509_EXTENSION) **sk = NULL;
+ if (crl)
+ sk = &crl->crl->extensions;
+ return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
+
+/* Add extensions to certificate request */
+
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+ X509_REQ *req)
+{
+ STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
+ int i;
+ if (req)
+ sk = &extlist;
+ i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+ if (!i || !sk)
+ return i;
+ i = X509_REQ_add_extensions(req, extlist);
+ sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
+ return i;
+}
+
+/* Config database functions */
+
+char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
+{
+ if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
+ X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED);
+ return NULL;
+ }
+ if (ctx->db_meth->get_string)
+ return ctx->db_meth->get_string(ctx->db, name, section);
+ return NULL;
+}
+
+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section)
+{
+ if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
+ X509V3err(X509V3_F_X509V3_GET_SECTION,
+ X509V3_R_OPERATION_NOT_DEFINED);
+ return NULL;
+ }
+ if (ctx->db_meth->get_section)
+ return ctx->db_meth->get_section(ctx->db, section);
+ return NULL;
+}
+
+void X509V3_string_free(X509V3_CTX *ctx, char *str)
+{
+ if (!str)
+ return;
+ if (ctx->db_meth->free_string)
+ ctx->db_meth->free_string(ctx->db, str);
+}
+
+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
+{
+ if (!section)
+ return;
+ if (ctx->db_meth->free_section)
+ ctx->db_meth->free_section(ctx->db, section);
+}
+
+static char *nconf_get_string(void *db, char *section, char *value)
+{
+ return NCONF_get_string(db, section, value);
+}
+
+static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
+{
+ return NCONF_get_section(db, section);
+}
+
+static X509V3_CONF_METHOD nconf_method = {
+ nconf_get_string,
+ nconf_get_section,
+ NULL,
+ NULL
+};
+
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
+{
+ ctx->db_meth = &nconf_method;
+ ctx->db = conf;
+}
+
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
+ X509_CRL *crl, int flags)
+{
+ ctx->issuer_cert = issuer;
+ ctx->subject_cert = subj;
+ ctx->crl = crl;
+ ctx->subject_req = req;
+ ctx->flags = flags;
+}
+
+/* Old conf compatibility functions */
+
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ char *name, char *value)
+{
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ return X509V3_EXT_nconf(&ctmp, ctx, name, value);
+}
+
+/* LHASH *conf: Config file */
+/* char *value: 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);
+ return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
+}
+
+static char *conf_lhash_get_string(void *db, char *section, char *value)
+{
+ return CONF_get_string(db, section, value);
+}
+
+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
+{
+ return CONF_get_section(db, section);
+}
+
+static X509V3_CONF_METHOD conf_lhash_method = {
+ conf_lhash_get_string,
+ conf_lhash_get_section,
+ NULL,
+ NULL
+};
+
+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_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ char *section, X509 *cert)
+{
+ CONF ctmp;
+ CONF_set_nconf(&ctmp, conf);
+ return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
+}
+
+/* Same as above but for a 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);
+ return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
+}
+
+/* Add extensions to certificate request */
+
+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);
+ return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_cpols.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_cpols.c
new file mode 100644
index 00000000..d97f6226
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_cpols.c
@@ -0,0 +1,491 @@
+/* v3_cpols.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Certificate policies extension support: this one is a bit complex... */
+
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+ BIO *out, int indent);
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *value);
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+ int indent);
+static void print_notice(BIO *out, USERNOTICE *notice, int indent);
+static POLICYINFO *policy_section(X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *polstrs, int ia5org);
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *unot, int ia5org);
+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
+
+const X509V3_EXT_METHOD v3_cpols = {
+ NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2R)i2r_certpol,
+ (X509V3_EXT_R2I)r2i_certpol,
+ NULL
+};
+
+ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
+ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
+
+IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+
+ASN1_SEQUENCE(POLICYINFO) = {
+ ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
+ ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
+} ASN1_SEQUENCE_END(POLICYINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
+
+ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
+
+ASN1_ADB(POLICYQUALINFO) = {
+ ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
+ ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
+} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
+
+ASN1_SEQUENCE(POLICYQUALINFO) = {
+ ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
+ ASN1_ADB_OBJECT(POLICYQUALINFO)
+} ASN1_SEQUENCE_END(POLICYQUALINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
+
+ASN1_SEQUENCE(USERNOTICE) = {
+ ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
+ ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
+} ASN1_SEQUENCE_END(USERNOTICE)
+
+IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
+
+ASN1_SEQUENCE(NOTICEREF) = {
+ ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
+ ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(NOTICEREF)
+
+IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
+
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *value)
+{
+ STACK_OF(POLICYINFO) *pols = NULL;
+ char *pstr;
+ POLICYINFO *pol;
+ ASN1_OBJECT *pobj;
+ STACK_OF(CONF_VALUE) *vals;
+ CONF_VALUE *cnf;
+ int i, ia5org;
+ pols = sk_POLICYINFO_new_null();
+ if (pols == NULL) {
+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ vals = X509V3_parse_list(value);
+ if (vals == NULL) {
+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
+ goto err;
+ }
+ ia5org = 0;
+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+ cnf = sk_CONF_VALUE_value(vals, i);
+ if (cnf->value || !cnf->name) {
+ X509V3err(X509V3_F_R2I_CERTPOL,
+ X509V3_R_INVALID_POLICY_IDENTIFIER);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pstr = cnf->name;
+ if (!strcmp(pstr, "ia5org")) {
+ ia5org = 1;
+ continue;
+ } else if (*pstr == '@') {
+ STACK_OF(CONF_VALUE) *polsect;
+ polsect = X509V3_get_section(ctx, pstr + 1);
+ if (!polsect) {
+ X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION);
+
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pol = policy_section(ctx, polsect, ia5org);
+ X509V3_section_free(ctx, polsect);
+ if (!pol)
+ goto err;
+ } else {
+ if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
+ X509V3err(X509V3_F_R2I_CERTPOL,
+ X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pol = POLICYINFO_new();
+ if (pol == NULL) {
+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ pol->policyid = pobj;
+ }
+ if (!sk_POLICYINFO_push(pols, pol)) {
+ POLICYINFO_free(pol);
+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ return pols;
+ err:
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
+ return NULL;
+}
+
+static POLICYINFO *policy_section(X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *polstrs, int ia5org)
+{
+ int i;
+ CONF_VALUE *cnf;
+ POLICYINFO *pol;
+ POLICYQUALINFO *qual;
+ if (!(pol = POLICYINFO_new()))
+ goto merr;
+ for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
+ cnf = sk_CONF_VALUE_value(polstrs, i);
+ if (!strcmp(cnf->name, "policyIdentifier")) {
+ ASN1_OBJECT *pobj;
+ if (!(pobj = OBJ_txt2obj(cnf->value, 0))) {
+ X509V3err(X509V3_F_POLICY_SECTION,
+ X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pol->policyid = pobj;
+
+ } else if (!name_cmp(cnf->name, "CPS")) {
+ if (!pol->qualifiers)
+ pol->qualifiers = sk_POLICYQUALINFO_new_null();
+ if (!(qual = POLICYQUALINFO_new()))
+ goto merr;
+ if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+ goto merr;
+ if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) {
+ X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (!(qual->d.cpsuri = M_ASN1_IA5STRING_new()))
+ goto merr;
+ if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
+ strlen(cnf->value)))
+ goto merr;
+ } else if (!name_cmp(cnf->name, "userNotice")) {
+ STACK_OF(CONF_VALUE) *unot;
+ if (*cnf->value != '@') {
+ X509V3err(X509V3_F_POLICY_SECTION,
+ X509V3_R_EXPECTED_A_SECTION_NAME);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ unot = X509V3_get_section(ctx, cnf->value + 1);
+ if (!unot) {
+ X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION);
+
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ qual = notice_section(ctx, unot, ia5org);
+ X509V3_section_free(ctx, unot);
+ if (!qual)
+ goto err;
+ if (!pol->qualifiers)
+ pol->qualifiers = sk_POLICYQUALINFO_new_null();
+ if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+ goto merr;
+ } else {
+ X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION);
+
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+ if (!pol->policyid) {
+ X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER);
+ goto err;
+ }
+
+ return pol;
+
+ merr:
+ X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE);
+
+ err:
+ POLICYINFO_free(pol);
+ return NULL;
+
+}
+
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *unot, int ia5org)
+{
+ int i, ret;
+ CONF_VALUE *cnf;
+ USERNOTICE *not;
+ POLICYQUALINFO *qual;
+ if (!(qual = POLICYQUALINFO_new()))
+ goto merr;
+ if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) {
+ X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (!(not = USERNOTICE_new()))
+ goto merr;
+ qual->d.usernotice = not;
+ for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
+ cnf = sk_CONF_VALUE_value(unot, i);
+ if (!strcmp(cnf->name, "explicitText")) {
+ if (!(not->exptext = M_ASN1_VISIBLESTRING_new()))
+ goto merr;
+ if (!ASN1_STRING_set(not->exptext, cnf->value,
+ strlen(cnf->value)))
+ goto merr;
+ } else if (!strcmp(cnf->name, "organization")) {
+ NOTICEREF *nref;
+ if (!not->noticeref) {
+ if (!(nref = NOTICEREF_new()))
+ goto merr;
+ not->noticeref = nref;
+ } else
+ nref = not->noticeref;
+ if (ia5org)
+ nref->organization->type = V_ASN1_IA5STRING;
+ else
+ nref->organization->type = V_ASN1_VISIBLESTRING;
+ if (!ASN1_STRING_set(nref->organization, cnf->value,
+ strlen(cnf->value)))
+ goto merr;
+ } else if (!strcmp(cnf->name, "noticeNumbers")) {
+ NOTICEREF *nref;
+ STACK_OF(CONF_VALUE) *nos;
+ if (!not->noticeref) {
+ if (!(nref = NOTICEREF_new()))
+ goto merr;
+ not->noticeref = nref;
+ } else
+ nref = not->noticeref;
+ nos = X509V3_parse_list(cnf->value);
+ if (!nos || !sk_CONF_VALUE_num(nos)) {
+ X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ ret = nref_nos(nref->noticenos, nos);
+ sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
+ if (!ret)
+ goto err;
+ } else {
+ X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+
+ if (not->noticeref &&
+ (!not->noticeref->noticenos || !not->noticeref->organization)) {
+ X509V3err(X509V3_F_NOTICE_SECTION,
+ X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+ goto err;
+ }
+
+ return qual;
+
+ merr:
+ X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE);
+
+ err:
+ POLICYQUALINFO_free(qual);
+ return NULL;
+}
+
+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
+{
+ CONF_VALUE *cnf;
+ ASN1_INTEGER *aint;
+
+ int i;
+
+ for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
+ cnf = sk_CONF_VALUE_value(nos, i);
+ if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
+ X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER);
+ goto err;
+ }
+ if (!sk_ASN1_INTEGER_push(nnums, aint))
+ goto merr;
+ }
+ return 1;
+
+ merr:
+ X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE);
+
+ err:
+ sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
+ return 0;
+}
+
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+ BIO *out, int indent)
+{
+ int i;
+ POLICYINFO *pinfo;
+ /* First print out the policy OIDs */
+ for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
+ pinfo = sk_POLICYINFO_value(pol, i);
+ BIO_printf(out, "%*sPolicy: ", indent, "");
+ i2a_ASN1_OBJECT(out, pinfo->policyid);
+ BIO_puts(out, "\n");
+ if (pinfo->qualifiers)
+ print_qualifiers(out, pinfo->qualifiers, indent + 2);
+ }
+ return 1;
+}
+
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+ int indent)
+{
+ POLICYQUALINFO *qualinfo;
+ int i;
+ for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
+ qualinfo = sk_POLICYQUALINFO_value(quals, i);
+ switch (OBJ_obj2nid(qualinfo->pqualid)) {
+ case NID_id_qt_cps:
+ BIO_printf(out, "%*sCPS: %s\n", indent, "",
+ qualinfo->d.cpsuri->data);
+ break;
+
+ case NID_id_qt_unotice:
+ BIO_printf(out, "%*sUser Notice:\n", indent, "");
+ print_notice(out, qualinfo->d.usernotice, indent + 2);
+ break;
+
+ default:
+ BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, "");
+
+ i2a_ASN1_OBJECT(out, qualinfo->pqualid);
+ BIO_puts(out, "\n");
+ break;
+ }
+ }
+}
+
+static void print_notice(BIO *out, USERNOTICE *notice, int indent)
+{
+ int i;
+ if (notice->noticeref) {
+ NOTICEREF *ref;
+ ref = notice->noticeref;
+ BIO_printf(out, "%*sOrganization: %s\n", indent, "",
+ ref->organization->data);
+ BIO_printf(out, "%*sNumber%s: ", indent, "",
+ sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
+ for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
+ ASN1_INTEGER *num;
+ char *tmp;
+ num = sk_ASN1_INTEGER_value(ref->noticenos, i);
+ if (i)
+ BIO_puts(out, ", ");
+ tmp = i2s_ASN1_INTEGER(NULL, num);
+ BIO_puts(out, tmp);
+ OPENSSL_free(tmp);
+ }
+ BIO_puts(out, "\n");
+ }
+ if (notice->exptext)
+ BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
+ notice->exptext->data);
+}
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
+{
+ const X509_POLICY_DATA *dat = node->data;
+
+ BIO_printf(out, "%*sPolicy: ", indent, "");
+
+ i2a_ASN1_OBJECT(out, dat->valid_policy);
+ BIO_puts(out, "\n");
+ BIO_printf(out, "%*s%s\n", indent + 2, "",
+ node_data_critical(dat) ? "Critical" : "Non Critical");
+ if (dat->qualifier_set)
+ print_qualifiers(out, dat->qualifier_set, indent + 2);
+ else
+ BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
+}
+
+
+IMPLEMENT_STACK_OF(X509_POLICY_NODE)
+
+IMPLEMENT_STACK_OF(X509_POLICY_DATA)
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_crld.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_crld.c
new file mode 100644
index 00000000..d3e1d1b0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_crld.c
@@ -0,0 +1,562 @@
+/* v3_crld.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+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 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, "<EMPTY>\n");
+ else
+ BIO_puts(out, "\n");
+ return 1;
+}
+
+static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
+{
+ int i;
+ 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;
+ }
+ }
+
+ return point;
+
+ err:
+ if (point)
+ DIST_POINT_free(point);
+ return NULL;
+}
+
+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;
+ CONF_VALUE *cnf;
+ int i;
+ if (!(crld = sk_DIST_POINT_new_null()))
+ goto merr;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ DIST_POINT *point;
+ cnf = sk_CONF_VALUE_value(nval, i);
+ 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;
+
+ merr:
+ X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE);
+ err:
+ GENERAL_NAME_free(gen);
+ GENERAL_NAMES_free(gens);
+ sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
+ return NULL;
+}
+
+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_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_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
+
+
+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
+
+ASN1_SEQUENCE(DIST_POINT) = {
+ ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+ ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
+ ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
+} ASN1_SEQUENCE_END(DIST_POINT)
+
+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
+
+ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
+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<EMPTY>\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/Cryptlib/OpenSSL/crypto/x509v3/v3_enum.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_enum.c
new file mode 100644
index 00000000..7678664f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_enum.c
@@ -0,0 +1,100 @@
+/* v3_enum.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+static ENUMERATED_NAMES crl_reasons[] = {
+ {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}
+};
+
+const X509V3_EXT_METHOD v3_crl_reason = {
+ NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
+ 0,
+ 0, 0, 0, 0,
+ crl_reasons
+};
+
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e)
+{
+ ENUMERATED_NAMES *enam;
+ long strval;
+ strval = ASN1_ENUMERATED_get(e);
+ for (enam = method->usr_data; enam->lname; enam++) {
+ if (strval == enam->bitnum)
+ return BUF_strdup(enam->lname);
+ }
+ return i2s_ASN1_ENUMERATED(method, e);
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_extku.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_extku.c
new file mode 100644
index 00000000..6092c2e4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_extku.c
@@ -0,0 +1,149 @@
+/* v3_extku.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+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 = {
+ NID_ext_key_usage, 0,
+ ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_EXTENDED_KEY_USAGE,
+ v2i_EXTENDED_KEY_USAGE,
+ 0, 0,
+ NULL
+};
+
+/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
+const X509V3_EXT_METHOD v3_ocsp_accresp = {
+ NID_id_pkix_OCSP_acceptableResponses, 0,
+ ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_EXTENDED_KEY_USAGE,
+ v2i_EXTENDED_KEY_USAGE,
+ 0, 0,
+ NULL
+};
+
+ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
+ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
+
+IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+
+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;
+ ASN1_OBJECT *obj;
+ char obj_tmp[80];
+ for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+ obj = sk_ASN1_OBJECT_value(eku, i);
+ i2t_ASN1_OBJECT(obj_tmp, 80, obj);
+ X509V3_add_value(NULL, obj_tmp, &ext_list);
+ }
+ return ext_list;
+}
+
+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;
+ ASN1_OBJECT *objtmp;
+ CONF_VALUE *val;
+ int i;
+
+ if (!(extku = sk_ASN1_OBJECT_new_null())) {
+ X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (val->value)
+ extval = val->value;
+ else
+ extval = val->name;
+ if (!(objtmp = OBJ_txt2obj(extval, 0))) {
+ sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
+ X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,
+ X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return NULL;
+ }
+ sk_ASN1_OBJECT_push(extku, objtmp);
+ }
+ return extku;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c
new file mode 100644
index 00000000..7f40bfab
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c
@@ -0,0 +1,250 @@
+/* v3_genn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(OTHERNAME) = {
+ ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
+ /* Maybe have a true ANY DEFINED BY later */
+ ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
+} ASN1_SEQUENCE_END(OTHERNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
+
+ASN1_SEQUENCE(EDIPARTYNAME) = {
+ ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
+ ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
+} ASN1_SEQUENCE_END(EDIPARTYNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
+
+ASN1_CHOICE(GENERAL_NAME) = {
+ ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
+ ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
+ ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
+ /* Don't decode this */
+ ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
+ /* X509_NAME is a CHOICE type so use EXPLICIT */
+ ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
+ ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
+ ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
+ ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
+ ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
+} ASN1_CHOICE_END(GENERAL_NAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
+
+ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
+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/Cryptlib/OpenSSL/crypto/x509v3/v3_ia5.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_ia5.c
new file mode 100644
index 00000000..c170a55f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_ia5.c
@@ -0,0 +1,119 @@
+/* v3_ia5.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+ ASN1_IA5STRING *ia5);
+static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
+ EXT_IA5STRING(NID_netscape_base_url),
+ EXT_IA5STRING(NID_netscape_revocation_url),
+ EXT_IA5STRING(NID_netscape_ca_revocation_url),
+ EXT_IA5STRING(NID_netscape_renewal_url),
+ EXT_IA5STRING(NID_netscape_ca_policy_url),
+ EXT_IA5STRING(NID_netscape_ssl_server_name),
+ EXT_IA5STRING(NID_netscape_comment),
+ EXT_END
+};
+
+static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+ ASN1_IA5STRING *ia5)
+{
+ char *tmp;
+ if (!ia5 || !ia5->length)
+ return NULL;
+ if (!(tmp = OPENSSL_malloc(ia5->length + 1))) {
+ X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memcpy(tmp, ia5->data, ia5->length);
+ tmp[ia5->length] = 0;
+ return tmp;
+}
+
+static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str)
+{
+ ASN1_IA5STRING *ia5;
+ if (!str) {
+ X509V3err(X509V3_F_S2I_ASN1_IA5STRING,
+ X509V3_R_INVALID_NULL_ARGUMENT);
+ return NULL;
+ }
+ if (!(ia5 = M_ASN1_IA5STRING_new()))
+ goto err;
+ if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str,
+ strlen(str))) {
+ M_ASN1_IA5STRING_free(ia5);
+ goto err;
+ }
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(ia5->data, ia5->data, ia5->length);
+#endif /* CHARSET_EBCDIC */
+ return ia5;
+ err:
+ X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_info.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_info.c
new file mode 100644
index 00000000..e052a34b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_info.c
@@ -0,0 +1,210 @@
+/* v3_info.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method, AUTHORITY_INFO_ACCESS
+ *ainfo, STACK_OF(CONF_VALUE)
+ *ret);
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE)
+ *nval);
+
+const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
+ ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+ (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+ 0, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
+ ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+ (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+ 0, 0,
+ NULL
+};
+
+ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
+ ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
+ ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
+} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
+
+IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+
+ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
+ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
+
+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method, AUTHORITY_INFO_ACCESS
+ *ainfo, STACK_OF(CONF_VALUE)
+ *ret)
+{
+ ACCESS_DESCRIPTION *desc;
+ int i, nlen;
+ char objtmp[80], *ntmp;
+ CONF_VALUE *vtmp;
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+ desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
+ ret = i2v_GENERAL_NAME(method, desc->location, ret);
+ if (!ret)
+ break;
+ vtmp = sk_CONF_VALUE_value(ret, i);
+ i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
+ nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
+ ntmp = OPENSSL_malloc(nlen);
+ if (!ntmp) {
+ X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ BUF_strlcpy(ntmp, objtmp, nlen);
+ BUF_strlcat(ntmp, " - ", nlen);
+ BUF_strlcat(ntmp, vtmp->name, nlen);
+ OPENSSL_free(vtmp->name);
+ vtmp->name = ntmp;
+
+ }
+ if (!ret)
+ return sk_CONF_VALUE_new_null();
+ return ret;
+}
+
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE)
+ *nval)
+{
+ AUTHORITY_INFO_ACCESS *ainfo = NULL;
+ CONF_VALUE *cnf, ctmp;
+ ACCESS_DESCRIPTION *acc;
+ int i, objlen;
+ char *objtmp, *ptmp;
+ if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!(acc = ACCESS_DESCRIPTION_new())
+ || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ptmp = strchr(cnf->name, ';');
+ if (!ptmp) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+ X509V3_R_INVALID_SYNTAX);
+ goto err;
+ }
+ objlen = ptmp - cnf->name;
+ ctmp.name = ptmp + 1;
+ ctmp.value = cnf->value;
+ if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
+ goto err;
+ if (!(objtmp = OPENSSL_malloc(objlen + 1))) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ strncpy(objtmp, cnf->name, objlen);
+ objtmp[objlen] = 0;
+ acc->method = OBJ_txt2obj(objtmp, 0);
+ if (!acc->method) {
+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+ X509V3_R_BAD_OBJECT);
+ ERR_add_error_data(2, "value=", objtmp);
+ OPENSSL_free(objtmp);
+ goto err;
+ }
+ OPENSSL_free(objtmp);
+
+ }
+ return ainfo;
+ err:
+ sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
+ return NULL;
+}
+
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a)
+{
+ i2a_ASN1_OBJECT(bp, a->method);
+#ifdef UNDEF
+ i2a_GENERAL_NAME(bp, a->location);
+#endif
+ return 2;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_int.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_int.c
new file mode 100644
index 00000000..8bfdb37e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_int.c
@@ -0,0 +1,92 @@
+/* v3_int.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+const X509V3_EXT_METHOD v3_crl_num = {
+ NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+ 0,
+ 0, 0, 0, 0, NULL
+};
+
+const X509V3_EXT_METHOD v3_delta_crl = {
+ NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+ 0,
+ 0, 0, 0, 0, NULL
+};
+
+static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx,
+ char *value)
+{
+ return s2i_ASN1_INTEGER(meth, value);
+}
+
+const X509V3_EXT_METHOD v3_inhibit_anyp = {
+ NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+ (X509V3_EXT_S2I)s2i_asn1_int,
+ 0, 0, 0, 0, NULL
+};
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_lib.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_lib.c
new file mode 100644
index 00000000..8350429a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_lib.c
@@ -0,0 +1,363 @@
+/* v3_lib.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+#include "ext_dat.h"
+
+static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
+
+static int ext_cmp(const X509V3_EXT_METHOD *const *a,
+ const X509V3_EXT_METHOD *const *b);
+static void ext_list_free(X509V3_EXT_METHOD *ext);
+
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
+{
+ if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
+ X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
+ X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ return 1;
+}
+
+static int ext_cmp(const X509V3_EXT_METHOD *const *a,
+ const X509V3_EXT_METHOD *const *b)
+{
+ return ((*a)->ext_nid - (*b)->ext_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;
+ const X509V3_EXT_METHOD *t = &tmp, *const *ret;
+ int idx;
+ if (nid < 0)
+ return NULL;
+ tmp.ext_nid = nid;
+ 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);
+ if (idx == -1)
+ return NULL;
+ return sk_X509V3_EXT_METHOD_value(ext_list, idx);
+}
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
+{
+ int nid;
+ if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
+ return NULL;
+ return X509V3_EXT_get_nid(nid);
+}
+
+int X509V3_EXT_free(int nid, void *ext_data)
+{
+ const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
+ if (ext_method == NULL) {
+ X509V3err(X509V3_F_X509V3_EXT_FREE,
+ X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ return 0;
+ }
+
+ if (ext_method->it != NULL)
+ ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
+ else if (ext_method->ext_free != NULL)
+ ext_method->ext_free(ext_data);
+ else {
+ X509V3err(X509V3_F_X509V3_EXT_FREE,
+ X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ return 0;
+ }
+
+ return 1;
+}
+
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
+{
+ for (; extlist->ext_nid != -1; extlist++)
+ if (!X509V3_EXT_add(extlist))
+ return 0;
+ return 1;
+}
+
+int X509V3_EXT_add_alias(int nid_to, int nid_from)
+{
+ 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;
+ }
+ if (!
+ (tmpext =
+ (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
+ X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ *tmpext = *ext;
+ tmpext->ext_nid = nid_to;
+ tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
+ return X509V3_EXT_add(tmpext);
+}
+
+void X509V3_EXT_cleanup(void)
+{
+ sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
+ ext_list = NULL;
+}
+
+static void ext_list_free(X509V3_EXT_METHOD *ext)
+{
+ if (ext->ext_flags & X509V3_EXT_DYNAMIC)
+ OPENSSL_free(ext);
+}
+
+/*
+ * Legacy function: we don't need to add standard extensions any more because
+ * they are now kept in ext_dat.h.
+ */
+
+int X509V3_add_standard_extensions(void)
+{
+ return 1;
+}
+
+/* Return an extension internal structure */
+
+void *X509V3_EXT_d2i(X509_EXTENSION *ext)
+{
+ const X509V3_EXT_METHOD *method;
+ const unsigned char *p;
+
+ if (!(method = X509V3_EXT_get(ext)))
+ return NULL;
+ p = ext->value->data;
+ if (method->it)
+ return ASN1_item_d2i(NULL, &p, ext->value->length,
+ ASN1_ITEM_ptr(method->it));
+ return method->d2i(NULL, &p, ext->value->length);
+}
+
+/*-
+ * Get critical flag and decoded version of extension from a NID.
+ * The "idx" variable returns the last found extension and can
+ * be used to retrieve multiple extensions of the same NID.
+ * However multiple extensions with the same NID is usually
+ * due to a badly encoded certificate so if idx is NULL we
+ * choke if multiple extensions exist.
+ * The "crit" variable is set to the critical value.
+ * The return value is the decoded extension or NULL on
+ * error. The actual error can have several different causes,
+ * the value of *crit reflects the cause:
+ * >= 0, extension found but not decoded (reflects critical value).
+ * -1 extension not found.
+ * -2 extension occurs more than once.
+ */
+
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+ int *idx)
+{
+ int lastpos, i;
+ X509_EXTENSION *ex, *found_ex = NULL;
+ if (!x) {
+ if (idx)
+ *idx = -1;
+ if (crit)
+ *crit = -1;
+ return NULL;
+ }
+ if (idx)
+ lastpos = *idx + 1;
+ else
+ lastpos = 0;
+ if (lastpos < 0)
+ lastpos = 0;
+ for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
+ ex = sk_X509_EXTENSION_value(x, i);
+ if (OBJ_obj2nid(ex->object) == nid) {
+ if (idx) {
+ *idx = i;
+ found_ex = ex;
+ break;
+ } else if (found_ex) {
+ /* Found more than one */
+ if (crit)
+ *crit = -2;
+ return NULL;
+ }
+ found_ex = ex;
+ }
+ }
+ if (found_ex) {
+ /* Found it */
+ if (crit)
+ *crit = X509_EXTENSION_get_critical(found_ex);
+ return X509V3_EXT_d2i(found_ex);
+ }
+
+ /* Extension not found */
+ if (idx)
+ *idx = -1;
+ if (crit)
+ *crit = -1;
+ return NULL;
+}
+
+/*
+ * This function is a general extension append, replace and delete utility.
+ * The precise operation is governed by the 'flags' value. The 'crit' and
+ * 'value' arguments (if relevant) are the extensions internal structure.
+ */
+
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
+ int crit, unsigned long flags)
+{
+ int extidx = -1;
+ int errcode;
+ X509_EXTENSION *ext, *extmp;
+ unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
+
+ /*
+ * If appending we don't care if it exists, otherwise look for existing
+ * extension.
+ */
+ if (ext_op != X509V3_ADD_APPEND)
+ extidx = X509v3_get_ext_by_NID(*x, nid, -1);
+
+ /* See if extension exists */
+ if (extidx >= 0) {
+ /* If keep existing, nothing to do */
+ if (ext_op == X509V3_ADD_KEEP_EXISTING)
+ return 1;
+ /* If default then its an error */
+ if (ext_op == X509V3_ADD_DEFAULT) {
+ errcode = X509V3_R_EXTENSION_EXISTS;
+ goto err;
+ }
+ /* If delete, just delete it */
+ if (ext_op == X509V3_ADD_DELETE) {
+ if (!sk_X509_EXTENSION_delete(*x, extidx))
+ return -1;
+ return 1;
+ }
+ } else {
+ /*
+ * If replace existing or delete, error since extension must exist
+ */
+ if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
+ (ext_op == X509V3_ADD_DELETE)) {
+ errcode = X509V3_R_EXTENSION_NOT_FOUND;
+ goto err;
+ }
+ }
+
+ /*
+ * If we get this far then we have to create an extension: could have
+ * some flags for alternative encoding schemes...
+ */
+
+ ext = X509V3_EXT_i2d(nid, crit, value);
+
+ if (!ext) {
+ X509V3err(X509V3_F_X509V3_ADD1_I2D,
+ X509V3_R_ERROR_CREATING_EXTENSION);
+ return 0;
+ }
+
+ /* If extension exists replace it.. */
+ if (extidx >= 0) {
+ extmp = sk_X509_EXTENSION_value(*x, extidx);
+ X509_EXTENSION_free(extmp);
+ if (!sk_X509_EXTENSION_set(*x, extidx, ext))
+ return -1;
+ return 1;
+ }
+
+ if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
+ return -1;
+ if (!sk_X509_EXTENSION_push(*x, ext))
+ return -1;
+
+ return 1;
+
+ err:
+ if (!(flags & X509V3_ADD_SILENT))
+ X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
+ return 0;
+}
+
+IMPLEMENT_STACK_OF(X509V3_EXT_METHOD)
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_ncons.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_ncons.c
new file mode 100644
index 00000000..28552696
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_ncons.c
@@ -0,0 +1,479 @@
+/* v3_ncons.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+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(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),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, v2i_NAME_CONSTRAINTS,
+ i2r_NAME_CONSTRAINTS, 0,
+ NULL
+};
+
+ASN1_SEQUENCE(GENERAL_SUBTREE) = {
+ ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
+ ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
+ ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
+} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
+
+ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
+ ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
+ GENERAL_SUBTREE, 0),
+ ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
+ GENERAL_SUBTREE, 1),
+} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
+
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+ int i;
+ CONF_VALUE tval, *val;
+ STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
+ NAME_CONSTRAINTS *ncons = NULL;
+ GENERAL_SUBTREE *sub = NULL;
+ ncons = NAME_CONSTRAINTS_new();
+ if (!ncons)
+ goto memerr;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
+ ptree = &ncons->permittedSubtrees;
+ tval.name = val->name + 10;
+ } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
+ ptree = &ncons->excludedSubtrees;
+ tval.name = val->name + 9;
+ } else {
+ X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
+ goto err;
+ }
+ tval.value = val->value;
+ sub = GENERAL_SUBTREE_new();
+ if (sub == NULL)
+ goto memerr;
+ if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
+ goto err;
+ if (!*ptree)
+ *ptree = sk_GENERAL_SUBTREE_new_null();
+ if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
+ goto memerr;
+ sub = NULL;
+ }
+
+ return ncons;
+
+ memerr:
+ X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ err:
+ if (ncons)
+ NAME_CONSTRAINTS_free(ncons);
+ if (sub)
+ GENERAL_SUBTREE_free(sub);
+
+ return NULL;
+}
+
+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,
+ bp, ind, "Permitted");
+ do_i2r_name_constraints(method, ncons->excludedSubtrees,
+ bp, ind, "Excluded");
+ return 1;
+}
+
+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;
+ if (sk_GENERAL_SUBTREE_num(trees) > 0)
+ BIO_printf(bp, "%*s%s:\n", ind, "", name);
+ for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
+ tree = sk_GENERAL_SUBTREE_value(trees, i);
+ BIO_printf(bp, "%*s", ind + 2, "");
+ if (tree->base->type == GEN_IPADD)
+ print_nc_ipadd(bp, tree->base->d.ip);
+ else
+ GENERAL_NAME_print(bp, tree->base);
+ BIO_puts(bp, "\n");
+ }
+ return 1;
+}
+
+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
+{
+ int i, len;
+ unsigned char *p;
+ p = ip->data;
+ len = ip->length;
+ BIO_puts(bp, "IP:");
+ if (len == 8) {
+ BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ } else if (len == 32) {
+ for (i = 0; i < 16; i++) {
+ BIO_printf(bp, "%X", p[0] << 8 | p[1]);
+ p += 2;
+ if (i == 7)
+ BIO_puts(bp, "/");
+ else if (i != 15)
+ BIO_puts(bp, ":");
+ }
+ } else
+ BIO_printf(bp, "IP Address:<invalid>");
+ 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 (*baseptr != '.' && 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/Cryptlib/OpenSSL/crypto/x509v3/v3_ocsp.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_ocsp.c
new file mode 100644
index 00000000..b151eacc
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_ocsp.c
@@ -0,0 +1,312 @@
+/* v3_ocsp.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 OPENSSL_NO_OCSP
+
+# include <stdio.h>
+# include "cryptlib.h"
+# include <openssl/conf.h>
+# include <openssl/asn1.h>
+# include <openssl/ocsp.h>
+# include <openssl/x509v3.h>
+
+/*
+ * OCSP extensions and a couple of CRL entry extensions
+ */
+
+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(const X509V3_EXT_METHOD *method, void *nonce,
+ BIO *out, int indent);
+
+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),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ i2r_ocsp_crlid, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_acutoff = {
+ NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ i2r_ocsp_acutoff, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_crl_invdate = {
+ NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ i2r_ocsp_acutoff, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_crl_hold = {
+ NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ i2r_object, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_nonce = {
+ NID_id_pkix_OCSP_Nonce, 0, NULL,
+ ocsp_nonce_new,
+ ocsp_nonce_free,
+ d2i_ocsp_nonce,
+ i2d_ocsp_nonce,
+ 0, 0,
+ 0, 0,
+ i2r_ocsp_nonce, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_nocheck = {
+ NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
+ 0, 0, 0, 0,
+ 0, s2i_ocsp_nocheck,
+ 0, 0,
+ i2r_ocsp_nocheck, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
+ NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ i2r_ocsp_serviceloc, 0,
+ NULL
+};
+
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
+ int ind)
+{
+ OCSP_CRLID *a = in;
+ if (a->crlUrl) {
+ if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0)
+ goto err;
+ if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (a->crlNum) {
+ if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0)
+ goto err;
+ if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (a->crlTime) {
+ if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0)
+ goto err;
+ if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ return 1;
+ err:
+ return 0;
+}
+
+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;
+ return 1;
+}
+
+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;
+ return 1;
+}
+
+/*
+ * OCSP nonce. This is needs special treatment because it doesn't have an
+ * ASN1 encoding at all: it just contains arbitrary data.
+ */
+
+static void *ocsp_nonce_new(void)
+{
+ return ASN1_OCTET_STRING_new();
+}
+
+static int i2d_ocsp_nonce(void *a, unsigned char **pp)
+{
+ ASN1_OCTET_STRING *os = a;
+ if (pp) {
+ memcpy(*pp, os->data, os->length);
+ *pp += os->length;
+ }
+ return os->length;
+}
+
+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
+{
+ ASN1_OCTET_STRING *os, **pos;
+ pos = a;
+ if (!pos || !*pos)
+ os = ASN1_OCTET_STRING_new();
+ else
+ os = *pos;
+ if (!ASN1_OCTET_STRING_set(os, *pp, length))
+ goto err;
+
+ *pp += length;
+
+ if (pos)
+ *pos = os;
+ return os;
+
+ err:
+ if (os && (!pos || (*pos != os)))
+ M_ASN1_OCTET_STRING_free(os);
+ OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
+ return NULL;
+}
+
+static void ocsp_nonce_free(void *a)
+{
+ M_ASN1_OCTET_STRING_free(a);
+}
+
+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;
+ return 1;
+}
+
+/* Nocheck is just a single NULL. Don't print anything and always set it */
+
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
+ BIO *out, int indent)
+{
+ return 1;
+}
+
+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(const X509V3_EXT_METHOD *method, void *in,
+ BIO *bp, int ind)
+{
+ int i;
+ OCSP_SERVICELOC *a = in;
+ ACCESS_DESCRIPTION *ad;
+
+ if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0)
+ goto err;
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) {
+ ad = sk_ACCESS_DESCRIPTION_value(a->locator, i);
+ if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, ad->method) <= 0)
+ goto err;
+ if (BIO_puts(bp, " - ") <= 0)
+ goto err;
+ if (GENERAL_NAME_print(bp, ad->location) <= 0)
+ goto err;
+ }
+ return 1;
+ err:
+ return 0;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_pci.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_pci.c
new file mode 100644
index 00000000..12f12a76
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_pci.c
@@ -0,0 +1,319 @@
+/* v3_pci.c */
+/*
+ * Contributed to the OpenSSL Project 2004 by Richard Levitte
+ * (richard@levitte.org)
+ */
+/* Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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. Neither the name of the Institute 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 THE INSTITUTE 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 THE INSTITUTE 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
+ BIO *out, int indent);
+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str);
+
+const X509V3_EXT_METHOD v3_pci =
+ { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
+ 0, 0, 0, 0,
+ 0, 0,
+ NULL, NULL,
+ (X509V3_EXT_I2R)i2r_pci,
+ (X509V3_EXT_R2I)r2i_pci,
+ NULL,
+};
+
+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
+ BIO *out, int indent)
+{
+ BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
+ if (pci->pcPathLengthConstraint)
+ i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
+ else
+ BIO_printf(out, "infinite");
+ BIO_puts(out, "\n");
+ BIO_printf(out, "%*sPolicy Language: ", indent, "");
+ i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
+ BIO_puts(out, "\n");
+ if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
+ BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
+ pci->proxyPolicy->policy->data);
+ return 1;
+}
+
+static int process_pci_value(CONF_VALUE *val,
+ ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
+ ASN1_OCTET_STRING **policy)
+{
+ int free_policy = 0;
+
+ if (strcmp(val->name, "language") == 0) {
+ if (*language) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+ X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ if (!(*language = OBJ_txt2obj(val->value, 0))) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+ X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ } else if (strcmp(val->name, "pathlen") == 0) {
+ if (*pathlen) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+ X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ if (!X509V3_get_value_int(val, pathlen)) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+ X509V3_R_POLICY_PATH_LENGTH);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ } else if (strcmp(val->name, "policy") == 0) {
+ unsigned char *tmp_data = NULL;
+ long val_len;
+ if (!*policy) {
+ *policy = ASN1_OCTET_STRING_new();
+ if (!*policy) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ free_policy = 1;
+ }
+ if (strncmp(val->value, "hex:", 4) == 0) {
+ unsigned char *tmp_data2 =
+ string_to_hex(val->value + 4, &val_len);
+
+ 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);
+ if (tmp_data) {
+ (*policy)->data = tmp_data;
+ memcpy(&(*policy)->data[(*policy)->length],
+ tmp_data2, val_len);
+ (*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);
+#ifndef OPENSSL_NO_STDIO
+ } else if (strncmp(val->value, "file:", 5) == 0) {
+ unsigned char buf[2048];
+ int n;
+ BIO *b = BIO_new_file(val->value + 5, "r");
+ if (!b) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ while ((n = BIO_read(b, buf, sizeof(buf))) > 0
+ || (n == 0 && BIO_should_retry(b))) {
+ if (!n)
+ continue;
+
+ tmp_data = OPENSSL_realloc((*policy)->data,
+ (*policy)->length + n + 1);
+
+ if (!tmp_data)
+ break;
+
+ (*policy)->data = tmp_data;
+ memcpy(&(*policy)->data[(*policy)->length], buf, n);
+ (*policy)->length += n;
+ (*policy)->data[(*policy)->length] = '\0';
+ }
+ BIO_free_all(b);
+
+ if (n < 0) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
+ X509V3_conf_err(val);
+ goto err;
+ }
+#endif /* !OPENSSL_NO_STDIO */
+ } else if (strncmp(val->value, "text:", 5) == 0) {
+ val_len = strlen(val->value + 5);
+ tmp_data = OPENSSL_realloc((*policy)->data,
+ (*policy)->length + val_len + 1);
+ if (tmp_data) {
+ (*policy)->data = tmp_data;
+ memcpy(&(*policy)->data[(*policy)->length],
+ val->value + 5, val_len);
+ (*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 {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+ X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!tmp_data) {
+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+ return 1;
+ err:
+ if (free_policy) {
+ ASN1_OCTET_STRING_free(*policy);
+ *policy = NULL;
+ }
+ return 0;
+}
+
+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *value)
+{
+ PROXY_CERT_INFO_EXTENSION *pci = NULL;
+ STACK_OF(CONF_VALUE) *vals;
+ ASN1_OBJECT *language = NULL;
+ ASN1_INTEGER *pathlen = NULL;
+ ASN1_OCTET_STRING *policy = NULL;
+ int i, j;
+
+ vals = X509V3_parse_list(value);
+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+ CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
+ if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
+ X509V3err(X509V3_F_R2I_PCI,
+ X509V3_R_INVALID_PROXY_POLICY_SETTING);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ if (*cnf->name == '@') {
+ STACK_OF(CONF_VALUE) *sect;
+ int success_p = 1;
+
+ sect = X509V3_get_section(ctx, cnf->name + 1);
+ if (!sect) {
+ X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
+ success_p =
+ process_pci_value(sk_CONF_VALUE_value(sect, j),
+ &language, &pathlen, &policy);
+ }
+ X509V3_section_free(ctx, sect);
+ if (!success_p)
+ goto err;
+ } else {
+ if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+ }
+
+ /* Language is mandatory */
+ if (!language) {
+ X509V3err(X509V3_F_R2I_PCI,
+ X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
+ goto err;
+ }
+ i = OBJ_obj2nid(language);
+ if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) {
+ X509V3err(X509V3_F_R2I_PCI,
+ X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+ goto err;
+ }
+
+ pci = PROXY_CERT_INFO_EXTENSION_new();
+ if (!pci) {
+ X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pci->proxyPolicy->policyLanguage = language;
+ language = NULL;
+ pci->proxyPolicy->policy = policy;
+ policy = NULL;
+ pci->pcPathLengthConstraint = pathlen;
+ pathlen = NULL;
+ goto end;
+ err:
+ if (language) {
+ ASN1_OBJECT_free(language);
+ language = NULL;
+ }
+ if (pathlen) {
+ ASN1_INTEGER_free(pathlen);
+ pathlen = NULL;
+ }
+ if (policy) {
+ ASN1_OCTET_STRING_free(policy);
+ policy = NULL;
+ }
+ if (pci) {
+ PROXY_CERT_INFO_EXTENSION_free(pci);
+ pci = NULL;
+ }
+ end:
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ return pci;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_pcia.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_pcia.c
new file mode 100644
index 00000000..e53c82e8
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_pcia.c
@@ -0,0 +1,56 @@
+/* v3_pcia.c */
+/*
+ * Contributed to the OpenSSL Project 2004 by Richard Levitte
+ * (richard@levitte.org)
+ */
+/* Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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. Neither the name of the Institute 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 THE INSTITUTE 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 THE INSTITUTE 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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(PROXY_POLICY) =
+ {
+ ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
+ ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(PROXY_POLICY)
+
+IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
+
+ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
+ {
+ ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
+ ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
+} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
+
+IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_pcons.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_pcons.c
new file mode 100644
index 00000000..cfccb97d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_pcons.c
@@ -0,0 +1,139 @@
+/* v3_pcons.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+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,
+ ASN1_ITEM_ref(POLICY_CONSTRAINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_POLICY_CONSTRAINTS,
+ v2i_POLICY_CONSTRAINTS,
+ NULL, NULL,
+ NULL
+};
+
+ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
+ ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
+ ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
+} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+
+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",
+ pcons->requireExplicitPolicy, &extlist);
+ X509V3_add_value_int("Inhibit Policy Mapping",
+ pcons->inhibitPolicyMapping, &extlist);
+ return extlist;
+}
+
+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;
+ int i;
+ if (!(pcons = POLICY_CONSTRAINTS_new())) {
+ X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ val = sk_CONF_VALUE_value(values, i);
+ if (!strcmp(val->name, "requireExplicitPolicy")) {
+ if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy))
+ goto err;
+ } else if (!strcmp(val->name, "inhibitPolicyMapping")) {
+ if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping))
+ goto err;
+ } else {
+ X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+ if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
+ X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS,
+ X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+ goto err;
+ }
+
+ return pcons;
+ err:
+ POLICY_CONSTRAINTS_free(pcons);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_pku.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_pku.c
new file mode 100644
index 00000000..dd01c441
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_pku.c
@@ -0,0 +1,114 @@
+/* v3_pku.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ PKEY_USAGE_PERIOD *usage, BIO *out,
+ int indent);
+/*
+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+ */
+const X509V3_EXT_METHOD v3_pkey_usage_period = {
+ NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
+ NULL
+};
+
+ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
+ ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
+ ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
+} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ PKEY_USAGE_PERIOD *usage, BIO *out,
+ int indent)
+{
+ BIO_printf(out, "%*s", indent, "");
+ if (usage->notBefore) {
+ BIO_write(out, "Not Before: ", 12);
+ ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
+ if (usage->notAfter)
+ BIO_write(out, ", ", 2);
+ }
+ if (usage->notAfter) {
+ BIO_write(out, "Not After: ", 11);
+ ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
+ }
+ return 1;
+}
+
+/*-
+static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK_OF(CONF_VALUE) *values;
+{
+return NULL;
+}
+*/
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_pmaps.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_pmaps.c
new file mode 100644
index 00000000..a168343b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_pmaps.c
@@ -0,0 +1,156 @@
+/* v3_pmaps.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * 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
+ * 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+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,
+ ASN1_ITEM_ref(POLICY_MAPPINGS),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_POLICY_MAPPINGS,
+ v2i_POLICY_MAPPINGS,
+ 0, 0,
+ NULL
+};
+
+ASN1_SEQUENCE(POLICY_MAPPING) = {
+ ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
+ ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
+} ASN1_SEQUENCE_END(POLICY_MAPPING)
+
+ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
+ POLICY_MAPPING)
+ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+
+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;
+ int i;
+ char obj_tmp1[80];
+ char obj_tmp2[80];
+ for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
+ pmap = sk_POLICY_MAPPING_value(pmaps, i);
+ i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
+ i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
+ X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
+ }
+ return ext_list;
+}
+
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+ POLICY_MAPPINGS *pmaps;
+ POLICY_MAPPING *pmap;
+ ASN1_OBJECT *obj1, *obj2;
+ CONF_VALUE *val;
+ int i;
+
+ if (!(pmaps = sk_POLICY_MAPPING_new_null())) {
+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (!val->value || !val->name) {
+ sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
+ X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return NULL;
+ }
+ obj1 = OBJ_txt2obj(val->name, 0);
+ obj2 = OBJ_txt2obj(val->value, 0);
+ if (!obj1 || !obj2) {
+ sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
+ X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return NULL;
+ }
+ pmap = POLICY_MAPPING_new();
+ if (!pmap) {
+ sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ pmap->issuerDomainPolicy = obj1;
+ pmap->subjectDomainPolicy = obj2;
+ sk_POLICY_MAPPING_push(pmaps, pmap);
+ }
+ return pmaps;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_prn.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_prn.c
new file mode 100644
index 00000000..acc9c6d9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_prn.c
@@ -0,0 +1,259 @@
+/* v3_prn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+/* Extension printing routines */
+
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
+ unsigned long flag, int indent, int supported);
+
+/* Print out a name+value stack */
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+ int ml)
+{
+ int i;
+ CONF_VALUE *nval;
+ if (!val)
+ return;
+ if (!ml || !sk_CONF_VALUE_num(val)) {
+ BIO_printf(out, "%*s", indent, "");
+ if (!sk_CONF_VALUE_num(val))
+ BIO_puts(out, "<EMPTY>\n");
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
+ if (ml)
+ BIO_printf(out, "%*s", indent, "");
+ else if (i > 0)
+ BIO_printf(out, ", ");
+ nval = sk_CONF_VALUE_value(val, i);
+ if (!nval->name)
+ BIO_puts(out, nval->value);
+ else if (!nval->value)
+ BIO_puts(out, nval->name);
+#ifndef CHARSET_EBCDIC
+ else
+ BIO_printf(out, "%s:%s", nval->name, nval->value);
+#else
+ else {
+ int len;
+ char *tmp;
+ len = strlen(nval->value) + 1;
+ tmp = OPENSSL_malloc(len);
+ if (tmp) {
+ ascii2ebcdic(tmp, nval->value, len);
+ BIO_printf(out, "%s:%s", nval->name, tmp);
+ OPENSSL_free(tmp);
+ }
+ }
+#endif
+ if (ml)
+ BIO_puts(out, "\n");
+ }
+}
+
+/* Main routine: print out a general extension */
+
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+ int indent)
+{
+ void *ext_str = NULL;
+ char *value = NULL;
+ const unsigned char *p;
+ const X509V3_EXT_METHOD *method;
+ STACK_OF(CONF_VALUE) *nval = NULL;
+ int ok = 1;
+
+ if (!(method = X509V3_EXT_get(ext)))
+ return unknown_ext_print(out, ext, flag, indent, 0);
+ p = ext->value->data;
+ if (method->it)
+ ext_str =
+ ASN1_item_d2i(NULL, &p, ext->value->length,
+ ASN1_ITEM_ptr(method->it));
+ else
+ ext_str = method->d2i(NULL, &p, ext->value->length);
+
+ if (!ext_str)
+ return unknown_ext_print(out, ext, flag, indent, 1);
+
+ if (method->i2s) {
+ if (!(value = method->i2s(method, ext_str))) {
+ ok = 0;
+ goto err;
+ }
+#ifndef CHARSET_EBCDIC
+ BIO_printf(out, "%*s%s", indent, "", value);
+#else
+ {
+ int len;
+ char *tmp;
+ len = strlen(value) + 1;
+ tmp = OPENSSL_malloc(len);
+ if (tmp) {
+ ascii2ebcdic(tmp, value, len);
+ BIO_printf(out, "%*s%s", indent, "", tmp);
+ OPENSSL_free(tmp);
+ }
+ }
+#endif
+ } else if (method->i2v) {
+ if (!(nval = method->i2v(method, ext_str, NULL))) {
+ ok = 0;
+ goto err;
+ }
+ X509V3_EXT_val_prn(out, nval, indent,
+ method->ext_flags & X509V3_EXT_MULTILINE);
+ } else if (method->i2r) {
+ if (!method->i2r(method, ext_str, out, indent))
+ ok = 0;
+ } else
+ ok = 0;
+
+ err:
+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+ if (value)
+ OPENSSL_free(value);
+ if (method->it)
+ ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
+ else
+ method->ext_free(ext_str);
+ return ok;
+}
+
+int X509V3_extensions_print(BIO *bp, char *title,
+ STACK_OF(X509_EXTENSION) *exts,
+ unsigned long flag, int indent)
+{
+ int i, j;
+
+ if (sk_X509_EXTENSION_num(exts) <= 0)
+ return 1;
+
+ if (title) {
+ BIO_printf(bp, "%*s%s:\n", indent, "", title);
+ indent += 4;
+ }
+
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ex;
+ ex = sk_X509_EXTENSION_value(exts, i);
+ if (indent && BIO_printf(bp, "%*s", indent, "") <= 0)
+ return 0;
+ obj = X509_EXTENSION_get_object(ex);
+ i2a_ASN1_OBJECT(bp, obj);
+ j = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
+ return 0;
+ if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
+ BIO_printf(bp, "%*s", indent + 4, "");
+ M_ASN1_OCTET_STRING_print(bp, ex->value);
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return 0;
+ }
+ return 1;
+}
+
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
+ unsigned long flag, int indent, int supported)
+{
+ switch (flag & X509V3_EXT_UNKNOWN_MASK) {
+
+ case X509V3_EXT_DEFAULT:
+ return 0;
+
+ case X509V3_EXT_ERROR_UNKNOWN:
+ if (supported)
+ BIO_printf(out, "%*s<Parse Error>", indent, "");
+ else
+ BIO_printf(out, "%*s<Not Supported>", indent, "");
+ return 1;
+
+ case X509V3_EXT_PARSE_UNKNOWN:
+ return ASN1_parse_dump(out,
+ ext->value->data, ext->value->length, indent,
+ -1);
+ case X509V3_EXT_DUMP_UNKNOWN:
+ return BIO_dump_indent(out, (char *)ext->value->data,
+ ext->value->length, indent);
+
+ default:
+ return 1;
+ }
+}
+
+#ifndef OPENSSL_NO_FP_API
+int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
+{
+ BIO *bio_tmp;
+ int ret;
+ if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)))
+ return 0;
+ ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
+ BIO_free(bio_tmp);
+ return ret;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_purp.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_purp.c
new file mode 100644
index 00000000..845be673
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_purp.c
@@ -0,0 +1,852 @@
+/* v3_purp.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+
+static void x509v3_cache_extensions(X509 *x);
+
+static int check_ssl_ca(const X509 *x);
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+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);
+
+static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b);
+static void xptable_free(X509_PURPOSE *p);
+
+static X509_PURPOSE xstandard[] = {
+ {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0,
+ check_purpose_ssl_client, "SSL client", "sslclient", NULL},
+ {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+ check_purpose_ssl_server, "SSL server", "sslserver", NULL},
+ {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+ check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
+ {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign,
+ "S/MIME signing", "smimesign", NULL},
+ {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0,
+ check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
+ {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))
+
+IMPLEMENT_STACK_OF(X509_PURPOSE)
+
+static STACK_OF(X509_PURPOSE) *xptable = NULL;
+
+static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b)
+{
+ return (*a)->purpose - (*b)->purpose;
+}
+
+/*
+ * As much as I'd like to make X509_check_purpose use a "const" X509* I
+ * really can't because it does recalculate hashes and do other non-const
+ * things.
+ */
+int X509_check_purpose(X509 *x, int id, int ca)
+{
+ int idx;
+ const X509_PURPOSE *pt;
+ if (!(x->ex_flags & EXFLAG_SET)) {
+ CRYPTO_w_lock(CRYPTO_LOCK_X509);
+ x509v3_cache_extensions(x);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+ }
+ if (id == -1)
+ return 1;
+ idx = X509_PURPOSE_get_by_id(id);
+ if (idx == -1)
+ return -1;
+ pt = X509_PURPOSE_get0(idx);
+ return pt->check_purpose(pt, x, ca);
+}
+
+int X509_PURPOSE_set(int *p, int purpose)
+{
+ if (X509_PURPOSE_get_by_id(purpose) == -1) {
+ X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE);
+ return 0;
+ }
+ *p = purpose;
+ return 1;
+}
+
+int X509_PURPOSE_get_count(void)
+{
+ if (!xptable)
+ return X509_PURPOSE_COUNT;
+ return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
+}
+
+X509_PURPOSE *X509_PURPOSE_get0(int idx)
+{
+ if (idx < 0)
+ return NULL;
+ if (idx < (int)X509_PURPOSE_COUNT)
+ return xstandard + idx;
+ return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
+}
+
+int X509_PURPOSE_get_by_sname(char *sname)
+{
+ int i;
+ X509_PURPOSE *xptmp;
+ for (i = 0; i < X509_PURPOSE_get_count(); i++) {
+ xptmp = X509_PURPOSE_get0(i);
+ if (!strcmp(xptmp->sname, sname))
+ return i;
+ }
+ return -1;
+}
+
+int X509_PURPOSE_get_by_id(int purpose)
+{
+ X509_PURPOSE tmp;
+ int idx;
+ if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
+ return purpose - X509_PURPOSE_MIN;
+ tmp.purpose = purpose;
+ if (!xptable)
+ return -1;
+ idx = sk_X509_PURPOSE_find(xptable, &tmp);
+ if (idx == -1)
+ return -1;
+ return idx + X509_PURPOSE_COUNT;
+}
+
+int X509_PURPOSE_add(int id, int trust, int flags,
+ int (*ck) (const X509_PURPOSE *, const X509 *, int),
+ char *name, char *sname, void *arg)
+{
+ int idx;
+ X509_PURPOSE *ptmp;
+ /*
+ * This is set according to what we change: application can't set it
+ */
+ flags &= ~X509_PURPOSE_DYNAMIC;
+ /* This will always be set for application modified trust entries */
+ flags |= X509_PURPOSE_DYNAMIC_NAME;
+ /* Get existing entry if any */
+ idx = X509_PURPOSE_get_by_id(id);
+ /* Need a new entry */
+ if (idx == -1) {
+ if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ptmp->flags = X509_PURPOSE_DYNAMIC;
+ } else
+ ptmp = X509_PURPOSE_get0(idx);
+
+ /* OPENSSL_free existing name if dynamic */
+ if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
+ OPENSSL_free(ptmp->name);
+ OPENSSL_free(ptmp->sname);
+ }
+ /* dup supplied name */
+ ptmp->name = BUF_strdup(name);
+ ptmp->sname = BUF_strdup(sname);
+ if (!ptmp->name || !ptmp->sname) {
+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ /* Keep the dynamic flag of existing entry */
+ ptmp->flags &= X509_PURPOSE_DYNAMIC;
+ /* Set all other flags */
+ ptmp->flags |= flags;
+
+ ptmp->purpose = id;
+ ptmp->trust = trust;
+ ptmp->check_purpose = ck;
+ ptmp->usr_data = arg;
+
+ /* If its a new entry manage the dynamic table */
+ if (idx == -1) {
+ if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void xptable_free(X509_PURPOSE *p)
+{
+ if (!p)
+ return;
+ if (p->flags & X509_PURPOSE_DYNAMIC) {
+ if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
+ OPENSSL_free(p->name);
+ OPENSSL_free(p->sname);
+ }
+ OPENSSL_free(p);
+ }
+}
+
+void X509_PURPOSE_cleanup(void)
+{
+ unsigned int i;
+ sk_X509_PURPOSE_pop_free(xptable, xptable_free);
+ for (i = 0; i < X509_PURPOSE_COUNT; i++)
+ xptable_free(xstandard + i);
+ xptable = NULL;
+}
+
+int X509_PURPOSE_get_id(X509_PURPOSE *xp)
+{
+ return xp->purpose;
+}
+
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
+{
+ return xp->name;
+}
+
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
+{
+ return xp->sname;
+}
+
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
+{
+ return xp->trust;
+}
+
+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: that is
+ * those which are used by the verify process. If an extension is
+ * critical and doesn't appear in this list then the verify process will
+ * normally reject the certificate. The list must be kept in numerical
+ * order because it will be searched using bsearch.
+ */
+
+ static const int supported_nids[] = {
+ NID_netscape_cert_type, /* 71 */
+ NID_key_usage, /* 83 */
+ NID_subject_alt_name, /* 85 */
+ NID_basic_constraints, /* 87 */
+ NID_certificate_policies, /* 89 */
+ NID_ext_key_usage, /* 126 */
+#ifndef OPENSSL_NO_RFC3779
+ NID_sbgp_ipAddrBlock, /* 290 */
+ NID_sbgp_autonomousSysNum, /* 291 */
+#endif
+ NID_policy_constraints, /* 401 */
+ NID_proxyCertInfo, /* 663 */
+ NID_name_constraints, /* 666 */
+ NID_policy_mappings, /* 747 */
+ NID_inhibit_any_policy /* 748 */
+ };
+
+ int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+
+ if (ex_nid == NID_undef)
+ return 0;
+
+ 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));
+}
+
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
+static void x509v3_cache_extensions(X509 *x)
+{
+ BASIC_CONSTRAINTS *bs;
+ PROXY_CERT_INFO_EXTENSION *pci;
+ ASN1_BIT_STRING *usage;
+ ASN1_BIT_STRING *ns;
+ EXTENDED_KEY_USAGE *extusage;
+ X509_EXTENSION *ex;
+
+ int i;
+ if (x->ex_flags & EXFLAG_SET)
+ return;
+#ifndef OPENSSL_NO_SHA
+ X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
+#endif
+ /* V1 should mean no extensions ... */
+ if (!X509_get_version(x))
+ x->ex_flags |= EXFLAG_V1;
+ /* Handle basic constraints */
+ if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
+ if (bs->ca)
+ x->ex_flags |= EXFLAG_CA;
+ if (bs->pathlen) {
+ if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
+ || !bs->ca) {
+ x->ex_flags |= EXFLAG_INVALID;
+ x->ex_pathlen = 0;
+ } else
+ x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
+ } else
+ x->ex_pathlen = -1;
+ BASIC_CONSTRAINTS_free(bs);
+ x->ex_flags |= EXFLAG_BCONS;
+ }
+ /* Handle proxy certificates */
+ if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
+ if (x->ex_flags & EXFLAG_CA
+ || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+ || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
+ x->ex_flags |= EXFLAG_INVALID;
+ }
+ if (pci->pcPathLengthConstraint) {
+ x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
+ } else
+ x->ex_pcpathlen = -1;
+ PROXY_CERT_INFO_EXTENSION_free(pci);
+ x->ex_flags |= EXFLAG_PROXY;
+ }
+ /* Handle key usage */
+ if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
+ if (usage->length > 0) {
+ x->ex_kusage = usage->data[0];
+ if (usage->length > 1)
+ x->ex_kusage |= usage->data[1] << 8;
+ } else
+ x->ex_kusage = 0;
+ x->ex_flags |= EXFLAG_KUSAGE;
+ ASN1_BIT_STRING_free(usage);
+ }
+ x->ex_xkusage = 0;
+ if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
+ x->ex_flags |= EXFLAG_XKUSAGE;
+ for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
+ switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
+ case NID_server_auth:
+ x->ex_xkusage |= XKU_SSL_SERVER;
+ break;
+
+ case NID_client_auth:
+ x->ex_xkusage |= XKU_SSL_CLIENT;
+ break;
+
+ case NID_email_protect:
+ x->ex_xkusage |= XKU_SMIME;
+ break;
+
+ case NID_code_sign:
+ x->ex_xkusage |= XKU_CODE_SIGN;
+ break;
+
+ case NID_ms_sgc:
+ case NID_ns_sgc:
+ x->ex_xkusage |= XKU_SGC;
+ break;
+
+ case NID_OCSP_sign:
+ x->ex_xkusage |= XKU_OCSP_SIGN;
+ break;
+
+ case NID_time_stamp:
+ x->ex_xkusage |= XKU_TIMESTAMP;
+ break;
+
+ case NID_dvcs:
+ x->ex_xkusage |= XKU_DVCS;
+ break;
+
+ case NID_anyExtendedKeyUsage:
+ x->ex_xkusage |= XKU_ANYEKU;
+ break;
+ }
+ }
+ sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
+ }
+
+ if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
+ if (ns->length > 0)
+ x->ex_nscert = ns->data[0];
+ else
+ x->ex_nscert = 0;
+ x->ex_flags |= EXFLAG_NSCERT;
+ ASN1_BIT_STRING_free(ns);
+ }
+ 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);
+ /* Does subject name match issuer ? */
+ if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
+ x->ex_flags |= EXFLAG_SI;
+ /* If SKID matches AKID also indicate self signed */
+ if (X509_check_akid(x, x->akid) == X509_V_OK &&
+ !ku_reject(x, KU_KEY_CERT_SIGN))
+ x->ex_flags |= EXFLAG_SS;
+ }
+ 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);
+#endif
+ for (i = 0; i < X509_get_ext_count(x); i++) {
+ ex = X509_get_ext(x, i);
+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
+ == NID_freshest_crl)
+ x->ex_flags |= EXFLAG_FRESHEST;
+ if (!X509_EXTENSION_get_critical(ex))
+ continue;
+ if (!X509_supported_extension(ex)) {
+ x->ex_flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+ x->ex_flags |= EXFLAG_SET;
+}
+
+/*-
+ * CA checks common to all purposes
+ * return codes:
+ * 0 not a CA
+ * 1 is a CA
+ * 2 basicConstraints absent so "maybe" a CA
+ * 3 basicConstraints absent but self signed V1.
+ * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
+ */
+
+static int check_ca(const X509 *x)
+{
+ /* keyUsage if present should allow cert signing */
+ if (ku_reject(x, KU_KEY_CERT_SIGN))
+ return 0;
+ if (x->ex_flags & EXFLAG_BCONS) {
+ if (x->ex_flags & EXFLAG_CA)
+ return 1;
+ /* If basicConstraints says not a CA then say so */
+ else
+ return 0;
+ } else {
+ /* we support V1 roots for... uh, I don't really know why. */
+ if ((x->ex_flags & V1_ROOT) == V1_ROOT)
+ return 3;
+ /*
+ * If key usage present it must have certSign so tolerate it
+ */
+ else if (x->ex_flags & EXFLAG_KUSAGE)
+ return 4;
+ /* Older certificates could have Netscape-specific CA types */
+ else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA)
+ return 5;
+ /* can this still be regarded a CA certificate? I doubt it */
+ return 0;
+ }
+}
+
+int X509_check_ca(X509 *x)
+{
+ if (!(x->ex_flags & EXFLAG_SET)) {
+ CRYPTO_w_lock(CRYPTO_LOCK_X509);
+ x509v3_cache_extensions(x);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+ }
+
+ return check_ca(x);
+}
+
+/* Check SSL CA: common checks for SSL client and server */
+static int check_ssl_ca(const X509 *x)
+{
+ int ca_ret;
+ ca_ret = check_ca(x);
+ if (!ca_ret)
+ return 0;
+ /* check nsCertType if present */
+ if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
+ return ca_ret;
+ else
+ return 0;
+}
+
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ if (xku_reject(x, XKU_SSL_CLIENT))
+ return 0;
+ if (ca)
+ return check_ssl_ca(x);
+ /* We need to do digital signatures or key agreement */
+ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))
+ return 0;
+ /* nsCertType if present should allow SSL client use */
+ if (ns_reject(x, NS_SSL_CLIENT))
+ return 0;
+ return 1;
+}
+
+/*
+ * Key usage needed for TLS/SSL server: digital signature, encipherment or
+ * key agreement. The ssl code can check this more thoroughly for individual
+ * key types.
+ */
+#define KU_TLS \
+ KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
+
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC))
+ return 0;
+ if (ca)
+ return check_ssl_ca(x);
+
+ if (ns_reject(x, NS_SSL_SERVER))
+ return 0;
+ if (ku_reject(x, KU_TLS))
+ return 0;
+
+ return 1;
+
+}
+
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ int ret;
+ ret = check_purpose_ssl_server(xp, x, ca);
+ if (!ret || ca)
+ return ret;
+ /* We need to encipher or Netscape complains */
+ if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+ return 0;
+ return ret;
+}
+
+/* common S/MIME checks */
+static int purpose_smime(const X509 *x, int ca)
+{
+ if (xku_reject(x, XKU_SMIME))
+ return 0;
+ if (ca) {
+ int ca_ret;
+ ca_ret = check_ca(x);
+ if (!ca_ret)
+ return 0;
+ /* check nsCertType if present */
+ if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
+ return ca_ret;
+ else
+ return 0;
+ }
+ if (x->ex_flags & EXFLAG_NSCERT) {
+ if (x->ex_nscert & NS_SMIME)
+ return 1;
+ /* Workaround for some buggy certificates */
+ if (x->ex_nscert & NS_SSL_CLIENT)
+ return 2;
+ return 0;
+ }
+ return 1;
+}
+
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ int ret;
+ ret = purpose_smime(x, ca);
+ if (!ret || ca)
+ return ret;
+ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION))
+ return 0;
+ return ret;
+}
+
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ int ret;
+ ret = purpose_smime(x, ca);
+ if (!ret || ca)
+ return ret;
+ if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+ return 0;
+ return ret;
+}
+
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ if (ca) {
+ int ca_ret;
+ if ((ca_ret = check_ca(x)) != 2)
+ return ca_ret;
+ else
+ return 0;
+ }
+ if (ku_reject(x, KU_CRL_SIGN))
+ return 0;
+ return 1;
+}
+
+/*
+ * OCSP helper: this is *not* a full OCSP check. It just checks that each CA
+ * is valid. Additional checks must be made on the chain.
+ */
+
+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+ /*
+ * Must be a valid CA. Should we really support the "I don't know" value
+ * (2)?
+ */
+ if (ca)
+ return check_ca(x);
+ /* leaf certificate is checked in OCSP_verify() */
+ 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, -1);
+ 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;
+}
+
+/*-
+ * Various checks to see if one certificate issued the second.
+ * This can be used to prune a set of possible issuer certificates
+ * which have been looked up using some simple method such as by
+ * subject name.
+ * These are:
+ * 1. Check issuer_name(subject) == subject_name(issuer)
+ * 2. If akid(subject) exists check it matches issuer
+ * 3. If key_usage(issuer) exists check it supports certificate signing
+ * returns 0 for OK, positive for reason for mismatch, reasons match
+ * codes for X509_verify_cert()
+ */
+
+int X509_check_issued(X509 *issuer, X509 *subject)
+{
+ if (X509_NAME_cmp(X509_get_subject_name(issuer),
+ X509_get_issuer_name(subject)))
+ return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+ x509v3_cache_extensions(issuer);
+ x509v3_cache_extensions(subject);
+
+ 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))
+ return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
+ } else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
+ return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
+ 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/Cryptlib/OpenSSL/crypto/x509v3/v3_skey.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_skey.c
new file mode 100644
index 00000000..1cede047
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_skey.c
@@ -0,0 +1,150 @@
+/* v3_skey.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_skey_id = {
+ NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
+ (X509V3_EXT_S2I)s2i_skey_id,
+ 0, 0, 0, 0,
+ NULL
+};
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct)
+{
+ return hex_to_string(oct->data, oct->length);
+}
+
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str)
+{
+ ASN1_OCTET_STRING *oct;
+ long length;
+
+ if (!(oct = M_ASN1_OCTET_STRING_new())) {
+ X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (!(oct->data = string_to_hex(str, &length))) {
+ M_ASN1_OCTET_STRING_free(oct);
+ return NULL;
+ }
+
+ oct->length = length;
+
+ return oct;
+
+}
+
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str)
+{
+ ASN1_OCTET_STRING *oct;
+ ASN1_BIT_STRING *pk;
+ unsigned char pkey_dig[EVP_MAX_MD_SIZE];
+ unsigned int diglen;
+
+ if (strcmp(str, "hash"))
+ return s2i_ASN1_OCTET_STRING(method, ctx, str);
+
+ if (!(oct = M_ASN1_OCTET_STRING_new())) {
+ X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (ctx && (ctx->flags == CTX_TEST))
+ return oct;
+
+ if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
+ X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY);
+ goto err;
+ }
+
+ if (ctx->subject_req)
+ pk = ctx->subject_req->req_info->pubkey->public_key;
+ else
+ pk = ctx->subject_cert->cert_info->key->public_key;
+
+ if (!pk) {
+ X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY);
+ goto err;
+ }
+
+ if (!EVP_Digest
+ (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
+ goto err;
+
+ if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
+ X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ return oct;
+
+ err:
+ M_ASN1_OCTET_STRING_free(oct);
+ return NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_sxnet.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_sxnet.c
new file mode 100644
index 00000000..a4e6a93e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_sxnet.c
@@ -0,0 +1,273 @@
+/* v3_sxnet.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+/* Support for Thawte strong extranet extension */
+
+#define SXNET_TEST
+
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+ int indent);
+#ifdef SXNET_TEST
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
+#endif
+const X509V3_EXT_METHOD v3_sxnet = {
+ NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
+#ifdef SXNET_TEST
+ (X509V3_EXT_V2I)sxnet_v2i,
+#else
+ 0,
+#endif
+ (X509V3_EXT_I2R)sxnet_i2r,
+ 0,
+ NULL
+};
+
+ASN1_SEQUENCE(SXNETID) = {
+ ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
+ ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(SXNETID)
+
+IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
+
+ASN1_SEQUENCE(SXNET) = {
+ ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
+ ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
+} ASN1_SEQUENCE_END(SXNET)
+
+IMPLEMENT_ASN1_FUNCTIONS(SXNET)
+
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+ int indent)
+{
+ long v;
+ char *tmp;
+ SXNETID *id;
+ int i;
+ v = ASN1_INTEGER_get(sx->version);
+ BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
+ for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+ id = sk_SXNETID_value(sx->ids, i);
+ tmp = i2s_ASN1_INTEGER(NULL, id->zone);
+ BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
+ OPENSSL_free(tmp);
+ M_ASN1_OCTET_STRING_print(out, id->user);
+ }
+ return 1;
+}
+
+#ifdef SXNET_TEST
+
+/*
+ * NBB: this is used for testing only. It should *not* be used for anything
+ * else because it will just take static IDs from the configuration file and
+ * they should really be separate values for each user.
+ */
+
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
+{
+ CONF_VALUE *cnf;
+ SXNET *sx = NULL;
+ int i;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+ return NULL;
+ }
+ return sx;
+}
+
+#endif
+
+/* Strong Extranet utility functions */
+
+/* Add an id given the zone as an ASCII number */
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen)
+{
+ ASN1_INTEGER *izone = NULL;
+ if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+ X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
+ return 0;
+ }
+ return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+}
+
+/* Add an id given the zone as an unsigned long */
+
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
+ int userlen)
+{
+ ASN1_INTEGER *izone = NULL;
+ if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+ X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE);
+ M_ASN1_INTEGER_free(izone);
+ return 0;
+ }
+ return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+
+}
+
+/*
+ * Add an id given the zone as an ASN1_INTEGER. Note this version uses the
+ * passed integer and doesn't make a copy so don't free it up afterwards.
+ */
+
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
+ int userlen)
+{
+ SXNET *sx = NULL;
+ SXNETID *id = NULL;
+ if (!psx || !zone || !user) {
+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,
+ X509V3_R_INVALID_NULL_ARGUMENT);
+ return 0;
+ }
+ if (userlen == -1)
+ userlen = strlen(user);
+ if (userlen > 64) {
+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG);
+ return 0;
+ }
+ if (!*psx) {
+ if (!(sx = SXNET_new()))
+ goto err;
+ if (!ASN1_INTEGER_set(sx->version, 0))
+ goto err;
+ *psx = sx;
+ } else
+ sx = *psx;
+ if (SXNET_get_id_INTEGER(sx, zone)) {
+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID);
+ return 0;
+ }
+
+ if (!(id = SXNETID_new()))
+ goto err;
+ if (userlen == -1)
+ userlen = strlen(user);
+
+ if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen))
+ goto err;
+ if (!sk_SXNETID_push(sx->ids, id))
+ goto err;
+ id->zone = zone;
+ return 1;
+
+ err:
+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE);
+ SXNETID_free(id);
+ SXNET_free(sx);
+ *psx = NULL;
+ return 0;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
+{
+ ASN1_INTEGER *izone = NULL;
+ ASN1_OCTET_STRING *oct;
+ if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+ X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
+ return NULL;
+ }
+ oct = SXNET_get_id_INTEGER(sx, izone);
+ M_ASN1_INTEGER_free(izone);
+ return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
+{
+ ASN1_INTEGER *izone = NULL;
+ ASN1_OCTET_STRING *oct;
+ if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+ X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE);
+ M_ASN1_INTEGER_free(izone);
+ return NULL;
+ }
+ oct = SXNET_get_id_INTEGER(sx, izone);
+ M_ASN1_INTEGER_free(izone);
+ return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
+{
+ SXNETID *id;
+ int i;
+ for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+ id = sk_SXNETID_value(sx->ids, i);
+ if (!M_ASN1_INTEGER_cmp(id->zone, zone))
+ return id->user;
+ }
+ return NULL;
+}
+
+IMPLEMENT_STACK_OF(SXNETID)
+
+IMPLEMENT_ASN1_SET_OF(SXNETID)
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_utl.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_utl.c
new file mode 100644
index 00000000..43b9cb9c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_utl.c
@@ -0,0 +1,1351 @@
+/* v3_utl.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-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
+ * 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).
+ *
+ */
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include <openssl/bn.h>
+
+static char *strip_spaces(char *name);
+static int sk_strcmp(const char *const *a, const char *const *b);
+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);
+static int ipv6_cb(const char *elem, int len, void *usr);
+static int ipv6_hex(unsigned char *out, const char *in, int inlen);
+
+/* Add a CONF_VALUE name value pair to stack */
+
+int X509V3_add_value(const char *name, const char *value,
+ STACK_OF(CONF_VALUE) **extlist)
+{
+ CONF_VALUE *vtmp = NULL;
+ char *tname = NULL, *tvalue = NULL;
+ if (name && !(tname = BUF_strdup(name)))
+ goto err;
+ if (value && !(tvalue = BUF_strdup(value)))
+ goto err;
+ if (!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))))
+ goto err;
+ if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null()))
+ goto err;
+ vtmp->section = NULL;
+ vtmp->name = tname;
+ vtmp->value = tvalue;
+ if (!sk_CONF_VALUE_push(*extlist, vtmp))
+ goto err;
+ return 1;
+ err:
+ X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE);
+ if (vtmp)
+ OPENSSL_free(vtmp);
+ if (tname)
+ OPENSSL_free(tname);
+ if (tvalue)
+ OPENSSL_free(tvalue);
+ return 0;
+}
+
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+ STACK_OF(CONF_VALUE) **extlist)
+{
+ return X509V3_add_value(name, (const char *)value, extlist);
+}
+
+/* Free function for STACK_OF(CONF_VALUE) */
+
+void X509V3_conf_free(CONF_VALUE *conf)
+{
+ if (!conf)
+ return;
+ if (conf->name)
+ OPENSSL_free(conf->name);
+ if (conf->value)
+ OPENSSL_free(conf->value);
+ if (conf->section)
+ OPENSSL_free(conf->section);
+ OPENSSL_free(conf);
+}
+
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+ STACK_OF(CONF_VALUE) **extlist)
+{
+ if (asn1_bool)
+ return X509V3_add_value(name, "TRUE", extlist);
+ return X509V3_add_value(name, "FALSE", extlist);
+}
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+ STACK_OF(CONF_VALUE) **extlist)
+{
+ if (asn1_bool)
+ return X509V3_add_value(name, "TRUE", extlist);
+ return 1;
+}
+
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
+{
+ BIGNUM *bntmp = NULL;
+ char *strtmp = NULL;
+ if (!a)
+ return NULL;
+ if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
+ !(strtmp = BN_bn2dec(bntmp)))
+ X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ BN_free(bntmp);
+ return strtmp;
+}
+
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
+{
+ BIGNUM *bntmp = NULL;
+ char *strtmp = NULL;
+ if (!a)
+ return NULL;
+ if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
+ !(strtmp = BN_bn2dec(bntmp)))
+ X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ BN_free(bntmp);
+ return strtmp;
+}
+
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
+{
+ BIGNUM *bn = NULL;
+ ASN1_INTEGER *aint;
+ int isneg, ishex;
+ int ret;
+ if (!value) {
+ X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
+ return 0;
+ }
+ bn = BN_new();
+ if (value[0] == '-') {
+ value++;
+ isneg = 1;
+ } else
+ isneg = 0;
+
+ if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
+ value += 2;
+ ishex = 1;
+ } else
+ ishex = 0;
+
+ if (ishex)
+ ret = BN_hex2bn(&bn, value);
+ else
+ ret = BN_dec2bn(&bn, value);
+
+ if (!ret || value[ret]) {
+ BN_free(bn);
+ X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
+ return 0;
+ }
+
+ if (isneg && BN_is_zero(bn))
+ isneg = 0;
+
+ aint = BN_to_ASN1_INTEGER(bn, NULL);
+ BN_free(bn);
+ if (!aint) {
+ X509V3err(X509V3_F_S2I_ASN1_INTEGER,
+ X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+ return 0;
+ }
+ if (isneg)
+ aint->type |= V_ASN1_NEG;
+ return aint;
+}
+
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+ STACK_OF(CONF_VALUE) **extlist)
+{
+ char *strtmp;
+ int ret;
+ if (!aint)
+ return 1;
+ if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
+ return 0;
+ ret = X509V3_add_value(name, strtmp, extlist);
+ OPENSSL_free(strtmp);
+ return ret;
+}
+
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
+{
+ char *btmp;
+ if (!(btmp = value->value))
+ goto err;
+ if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
+ || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
+ || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
+ *asn1_bool = 0xff;
+ return 1;
+ } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
+ || !strcmp(btmp, "N") || !strcmp(btmp, "n")
+ || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
+ *asn1_bool = 0;
+ return 1;
+ }
+ err:
+ X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
+ X509V3_R_INVALID_BOOLEAN_STRING);
+ X509V3_conf_err(value);
+ return 0;
+}
+
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
+{
+ ASN1_INTEGER *itmp;
+ if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
+ X509V3_conf_err(value);
+ return 0;
+ }
+ *aint = itmp;
+ return 1;
+}
+
+#define HDR_NAME 1
+#define HDR_VALUE 2
+
+/*
+ * #define DEBUG
+ */
+
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
+{
+ char *p, *q, c;
+ char *ntmp, *vtmp;
+ STACK_OF(CONF_VALUE) *values = NULL;
+ char *linebuf;
+ int state;
+ /* We are going to modify the line so copy it first */
+ linebuf = BUF_strdup(line);
+ if (linebuf == NULL) {
+ X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ state = HDR_NAME;
+ ntmp = NULL;
+ /* Go through all characters */
+ for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+ p++) {
+
+ switch (state) {
+ case HDR_NAME:
+ if (c == ':') {
+ state = HDR_VALUE;
+ *p = 0;
+ ntmp = strip_spaces(q);
+ if (!ntmp) {
+ X509V3err(X509V3_F_X509V3_PARSE_LIST,
+ X509V3_R_INVALID_NULL_NAME);
+ goto err;
+ }
+ q = p + 1;
+ } else if (c == ',') {
+ *p = 0;
+ ntmp = strip_spaces(q);
+ q = p + 1;
+#if 0
+ printf("%s\n", ntmp);
+#endif
+ if (!ntmp) {
+ X509V3err(X509V3_F_X509V3_PARSE_LIST,
+ X509V3_R_INVALID_NULL_NAME);
+ goto err;
+ }
+ X509V3_add_value(ntmp, NULL, &values);
+ }
+ break;
+
+ case HDR_VALUE:
+ if (c == ',') {
+ state = HDR_NAME;
+ *p = 0;
+ vtmp = strip_spaces(q);
+#if 0
+ printf("%s\n", ntmp);
+#endif
+ if (!vtmp) {
+ X509V3err(X509V3_F_X509V3_PARSE_LIST,
+ X509V3_R_INVALID_NULL_VALUE);
+ goto err;
+ }
+ X509V3_add_value(ntmp, vtmp, &values);
+ ntmp = NULL;
+ q = p + 1;
+ }
+
+ }
+ }
+
+ if (state == HDR_VALUE) {
+ vtmp = strip_spaces(q);
+#if 0
+ printf("%s=%s\n", ntmp, vtmp);
+#endif
+ if (!vtmp) {
+ X509V3err(X509V3_F_X509V3_PARSE_LIST,
+ X509V3_R_INVALID_NULL_VALUE);
+ goto err;
+ }
+ X509V3_add_value(ntmp, vtmp, &values);
+ } else {
+ ntmp = strip_spaces(q);
+#if 0
+ printf("%s\n", ntmp);
+#endif
+ if (!ntmp) {
+ X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
+ goto err;
+ }
+ X509V3_add_value(ntmp, NULL, &values);
+ }
+ OPENSSL_free(linebuf);
+ return values;
+
+ err:
+ OPENSSL_free(linebuf);
+ sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
+ return NULL;
+
+}
+
+/* Delete leading and trailing spaces from a string */
+static char *strip_spaces(char *name)
+{
+ char *p, *q;
+ /* Skip over leading spaces */
+ p = name;
+ while (*p && isspace((unsigned char)*p))
+ p++;
+ if (!*p)
+ return NULL;
+ q = p + strlen(p) - 1;
+ while ((q != p) && isspace((unsigned char)*q))
+ q--;
+ if (p != q)
+ q[1] = 0;
+ if (!*p)
+ return NULL;
+ return p;
+}
+
+/* hex string utilities */
+
+/*
+ * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
+ * hex representation @@@ (Contents of buffer are always kept in ASCII, also
+ * on EBCDIC machines)
+ */
+
+char *hex_to_string(const unsigned char *buffer, long len)
+{
+ char *tmp, *q;
+ const unsigned char *p;
+ int i;
+ const static char hexdig[] = "0123456789ABCDEF";
+ if (!buffer || !len)
+ return NULL;
+ if (!(tmp = OPENSSL_malloc(len * 3 + 1))) {
+ X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ q = tmp;
+ for (i = 0, p = buffer; i < len; i++, p++) {
+ *q++ = hexdig[(*p >> 4) & 0xf];
+ *q++ = hexdig[*p & 0xf];
+ *q++ = ':';
+ }
+ q[-1] = 0;
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(tmp, tmp, q - tmp - 1);
+#endif
+
+ return tmp;
+}
+
+/*
+ * Give a string of hex digits convert to a buffer
+ */
+
+unsigned char *string_to_hex(const char *str, long *len)
+{
+ unsigned char *hexbuf, *q;
+ unsigned char ch, cl, *p;
+ if (!str) {
+ X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT);
+ return NULL;
+ }
+ if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1)))
+ goto err;
+ for (p = (unsigned char *)str, q = hexbuf; *p;) {
+ ch = *p++;
+#ifdef CHARSET_EBCDIC
+ ch = os_toebcdic[ch];
+#endif
+ if (ch == ':')
+ continue;
+ cl = *p++;
+#ifdef CHARSET_EBCDIC
+ cl = os_toebcdic[cl];
+#endif
+ if (!cl) {
+ X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS);
+ OPENSSL_free(hexbuf);
+ return NULL;
+ }
+ if (isupper(ch))
+ ch = tolower(ch);
+ if (isupper(cl))
+ cl = tolower(cl);
+
+ if ((ch >= '0') && (ch <= '9'))
+ ch -= '0';
+ else if ((ch >= 'a') && (ch <= 'f'))
+ ch -= 'a' - 10;
+ else
+ goto badhex;
+
+ if ((cl >= '0') && (cl <= '9'))
+ cl -= '0';
+ else if ((cl >= 'a') && (cl <= 'f'))
+ cl -= 'a' - 10;
+ else
+ goto badhex;
+
+ *q++ = (ch << 4) | cl;
+ }
+
+ if (len)
+ *len = q - hexbuf;
+
+ return hexbuf;
+
+ err:
+ if (hexbuf)
+ OPENSSL_free(hexbuf);
+ X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE);
+ return NULL;
+
+ badhex:
+ OPENSSL_free(hexbuf);
+ X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT);
+ return NULL;
+
+}
+
+/*
+ * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
+ */
+
+int name_cmp(const char *name, const char *cmp)
+{
+ int len, ret;
+ char c;
+ len = strlen(cmp);
+ if ((ret = strncmp(name, cmp, len)))
+ return ret;
+ c = name[len];
+ if (!c || (c == '.'))
+ return 0;
+ return 1;
+}
+
+static int sk_strcmp(const char *const *a, const char *const *b)
+{
+ return strcmp(*a, *b);
+}
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
+{
+ GENERAL_NAMES *gens;
+ 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_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
+{
+ AUTHORITY_INFO_ACCESS *info;
+ STACK_OF(OPENSSL_STRING) *ret = NULL;
+ int i;
+
+ info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
+ if (!info)
+ return NULL;
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
+ ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
+ if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
+ if (ad->location->type == GEN_URI) {
+ if (!append_ia5
+ (&ret, ad->location->d.uniformResourceIdentifier))
+ break;
+ }
+ }
+ }
+ AUTHORITY_INFO_ACCESS_free(info);
+ return ret;
+}
+
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
+{
+ GENERAL_NAMES *gens;
+ STACK_OF(X509_EXTENSION) *exts;
+ 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);
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ return ret;
+}
+
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+ GENERAL_NAMES *gens)
+{
+ STACK_OF(OPENSSL_STRING) *ret = NULL;
+ X509_NAME_ENTRY *ne;
+ ASN1_IA5STRING *email;
+ GENERAL_NAME *gen;
+ int i;
+ /* Now add any email address(es) to STACK */
+ i = -1;
+ /* First supplied X509_NAME */
+ while ((i = X509_NAME_get_index_by_NID(name,
+ NID_pkcs9_emailAddress, i)) >= 0) {
+ ne = X509_NAME_get_entry(name, i);
+ email = X509_NAME_ENTRY_get_data(ne);
+ if (!append_ia5(&ret, email))
+ return NULL;
+ }
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ gen = sk_GENERAL_NAME_value(gens, i);
+ if (gen->type != GEN_EMAIL)
+ continue;
+ if (!append_ia5(&ret, gen->d.ia5))
+ return NULL;
+ }
+ return ret;
+}
+
+static void str_free(OPENSSL_STRING str)
+{
+ OPENSSL_free(str);
+}
+
+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_OPENSSL_STRING_new(sk_strcmp);
+ if (!*sk)
+ return 0;
+ /* Don't add duplicates */
+ if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
+ return 1;
+ emtmp = BUF_strdup((char *)email->data);
+ if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
+ X509_email_free(*sk);
+ *sk = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
+{
+ sk_OPENSSL_STRING_pop_free(sk, str_free);
+}
+
+typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags);
+
+/* Skip pattern prefix to match "wildcard" subject */
+static void skip_prefix(const unsigned char **p, size_t *plen,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ const unsigned char *pattern = *p;
+ size_t pattern_len = *plen;
+
+ /*
+ * If subject starts with a leading '.' followed by more octets, and
+ * pattern is longer, compare just an equal-length suffix with the
+ * full subject (starting at the '.'), provided the prefix contains
+ * no NULs.
+ */
+ if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
+ return;
+
+ while (pattern_len > subject_len && *pattern) {
+ if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
+ *pattern == '.')
+ break;
+ ++pattern;
+ --pattern_len;
+ }
+
+ /* Skip if entire prefix acceptable */
+ if (pattern_len == subject_len) {
+ *p = pattern;
+ *plen = pattern_len;
+ }
+}
+
+/* Compare while ASCII ignoring case. */
+static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
+ if (pattern_len != subject_len)
+ return 0;
+ while (pattern_len) {
+ unsigned char l = *pattern;
+ unsigned char r = *subject;
+ /* The pattern must not contain NUL characters. */
+ if (l == 0)
+ return 0;
+ if (l != r) {
+ if ('A' <= l && l <= 'Z')
+ l = (l - 'A') + 'a';
+ if ('A' <= r && r <= 'Z')
+ r = (r - 'A') + 'a';
+ if (l != r)
+ return 0;
+ }
+ ++pattern;
+ ++subject;
+ --pattern_len;
+ }
+ return 1;
+}
+
+/* Compare using memcmp. */
+static int equal_case(const unsigned char *pattern, size_t pattern_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
+ if (pattern_len != subject_len)
+ return 0;
+ return !memcmp(pattern, subject, pattern_len);
+}
+
+/*
+ * RFC 5280, section 7.5, requires that only the domain is compared in a
+ * case-insensitive manner.
+ */
+static int equal_email(const unsigned char *a, size_t a_len,
+ const unsigned char *b, size_t b_len,
+ unsigned int unused_flags)
+{
+ size_t i = a_len;
+ if (a_len != b_len)
+ return 0;
+ /*
+ * We search backwards for the '@' character, so that we do not have to
+ * deal with quoted local-parts. The domain part is compared in a
+ * case-insensitive manner.
+ */
+ while (i > 0) {
+ --i;
+ if (a[i] == '@' || b[i] == '@') {
+ if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
+ return 0;
+ break;
+ }
+ }
+ if (i == 0)
+ i = a_len;
+ return equal_case(a, i, b, i, 0);
+}
+
+/*
+ * Compare the prefix and suffix with the subject, and check that the
+ * characters in-between are valid.
+ */
+static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
+ const unsigned char *suffix, size_t suffix_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ const unsigned char *wildcard_start;
+ const unsigned char *wildcard_end;
+ const unsigned char *p;
+ int allow_multi = 0;
+ int allow_idna = 0;
+
+ if (subject_len < prefix_len + suffix_len)
+ return 0;
+ if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
+ return 0;
+ wildcard_start = subject + prefix_len;
+ wildcard_end = subject + (subject_len - suffix_len);
+ if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
+ return 0;
+ /*
+ * If the wildcard makes up the entire first label, it must match at
+ * least one character.
+ */
+ if (prefix_len == 0 && *suffix == '.') {
+ if (wildcard_start == wildcard_end)
+ return 0;
+ allow_idna = 1;
+ if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
+ allow_multi = 1;
+ }
+ /* IDNA labels cannot match partial wildcards */
+ if (!allow_idna &&
+ subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
+ return 0;
+ /* The wildcard may match a literal '*' */
+ if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
+ return 1;
+ /*
+ * Check that the part matched by the wildcard contains only
+ * permitted characters and only matches a single label unless
+ * allow_multi is set.
+ */
+ for (p = wildcard_start; p != wildcard_end; ++p)
+ if (!(('0' <= *p && *p <= '9') ||
+ ('A' <= *p && *p <= 'Z') ||
+ ('a' <= *p && *p <= 'z') ||
+ *p == '-' || (allow_multi && *p == '.')))
+ return 0;
+ return 1;
+}
+
+#define LABEL_START (1 << 0)
+#define LABEL_END (1 << 1)
+#define LABEL_HYPHEN (1 << 2)
+#define LABEL_IDNA (1 << 3)
+
+static const unsigned char *valid_star(const unsigned char *p, size_t len,
+ unsigned int flags)
+{
+ const unsigned char *star = 0;
+ size_t i;
+ int state = LABEL_START;
+ int dots = 0;
+ for (i = 0; i < len; ++i) {
+ /*
+ * Locate first and only legal wildcard, either at the start
+ * or end of a non-IDNA first and not final label.
+ */
+ if (p[i] == '*') {
+ int atstart = (state & LABEL_START);
+ int atend = (i == len - 1 || p[i + 1] == '.');
+ /*-
+ * At most one wildcard per pattern.
+ * No wildcards in IDNA labels.
+ * No wildcards after the first label.
+ */
+ if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
+ return NULL;
+ /* Only full-label '*.example.com' wildcards? */
+ if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
+ && (!atstart || !atend))
+ return NULL;
+ /* No 'foo*bar' wildcards */
+ if (!atstart && !atend)
+ return NULL;
+ star = &p[i];
+ state &= ~LABEL_START;
+ } else if (('a' <= p[i] && p[i] <= 'z')
+ || ('A' <= p[i] && p[i] <= 'Z')
+ || ('0' <= p[i] && p[i] <= '9')) {
+ if ((state & LABEL_START) != 0
+ && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
+ state |= LABEL_IDNA;
+ state &= ~(LABEL_HYPHEN | LABEL_START);
+ } else if (p[i] == '.') {
+ if ((state & (LABEL_HYPHEN | LABEL_START)) != 0)
+ return NULL;
+ state = LABEL_START;
+ ++dots;
+ } else if (p[i] == '-') {
+ /* no domain/subdomain starts with '-' */
+ if ((state & LABEL_START) != 0)
+ return NULL;
+ state |= LABEL_HYPHEN;
+ } else
+ return NULL;
+ }
+
+ /*
+ * The final label must not end in a hyphen or ".", and
+ * there must be at least two dots after the star.
+ */
+ if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
+ return NULL;
+ return star;
+}
+
+/* Compare using wildcards. */
+static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ const unsigned char *star = NULL;
+
+ /*
+ * Subject names starting with '.' can only match a wildcard pattern
+ * via a subject sub-domain pattern suffix match.
+ */
+ if (!(subject_len > 1 && subject[0] == '.'))
+ star = valid_star(pattern, pattern_len, flags);
+ if (star == NULL)
+ return equal_nocase(pattern, pattern_len,
+ subject, subject_len, flags);
+ return wildcard_match(pattern, star - pattern,
+ star + 1, (pattern + pattern_len) - star - 1,
+ subject, subject_len, flags);
+}
+
+/*
+ * Compare an ASN1_STRING to a supplied string. If they match return 1. If
+ * cmp_type > 0 only compare if string matches the type, otherwise convert it
+ * to UTF8.
+ */
+
+static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
+ unsigned int flags, const char *b, size_t blen,
+ char **peername)
+{
+ int rv = 0;
+
+ if (!a->data || !a->length)
+ return 0;
+ if (cmp_type > 0) {
+ if (cmp_type != a->type)
+ return 0;
+ if (cmp_type == V_ASN1_IA5STRING)
+ rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
+ else if (a->length == (int)blen && !memcmp(a->data, b, blen))
+ rv = 1;
+ if (rv > 0 && peername)
+ *peername = BUF_strndup((char *)a->data, a->length);
+ } else {
+ int astrlen;
+ unsigned char *astr;
+ astrlen = ASN1_STRING_to_UTF8(&astr, a);
+ if (astrlen < 0) {
+ /*
+ * -1 could be an internal malloc failure or a decoding error from
+ * malformed input; we can't distinguish.
+ */
+ return -1;
+ }
+ rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
+ if (rv > 0 && peername)
+ *peername = BUF_strndup((char *)astr, astrlen);
+ OPENSSL_free(astr);
+ }
+ return rv;
+}
+
+static int do_x509_check(X509 *x, const char *chk, size_t chklen,
+ unsigned int flags, int check_type, char **peername)
+{
+ GENERAL_NAMES *gens = NULL;
+ X509_NAME *name = NULL;
+ int i;
+ int cnid = NID_undef;
+ int alt_type;
+ int san_present = 0;
+ int rv = 0;
+ equal_fn equal;
+
+ /* See below, this flag is internal-only */
+ flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
+ if (check_type == GEN_EMAIL) {
+ cnid = NID_pkcs9_emailAddress;
+ alt_type = V_ASN1_IA5STRING;
+ equal = equal_email;
+ } else if (check_type == GEN_DNS) {
+ cnid = NID_commonName;
+ /* Implicit client-side DNS sub-domain pattern */
+ if (chklen > 1 && chk[0] == '.')
+ flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
+ alt_type = V_ASN1_IA5STRING;
+ if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
+ equal = equal_nocase;
+ else
+ equal = equal_wildcard;
+ } else {
+ alt_type = V_ASN1_OCTET_STRING;
+ equal = equal_case;
+ }
+
+ if (chklen == 0)
+ chklen = strlen(chk);
+
+ gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+ if (gens) {
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ GENERAL_NAME *gen;
+ ASN1_STRING *cstr;
+ gen = sk_GENERAL_NAME_value(gens, i);
+ if (gen->type != check_type)
+ continue;
+ san_present = 1;
+ if (check_type == GEN_EMAIL)
+ cstr = gen->d.rfc822Name;
+ else if (check_type == GEN_DNS)
+ cstr = gen->d.dNSName;
+ else
+ cstr = gen->d.iPAddress;
+ /* Positive on success, negative on error! */
+ if ((rv = do_check_string(cstr, alt_type, equal, flags,
+ chk, chklen, peername)) != 0)
+ break;
+ }
+ GENERAL_NAMES_free(gens);
+ if (rv != 0)
+ return rv;
+ if (cnid == NID_undef
+ || (san_present
+ && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
+ return 0;
+ }
+
+ /* We're done if CN-ID is not pertinent */
+ if (cnid == NID_undef)
+ return 0;
+
+ i = -1;
+ name = X509_get_subject_name(x);
+ while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
+ X509_NAME_ENTRY *ne;
+ ASN1_STRING *str;
+ ne = X509_NAME_get_entry(name, i);
+ str = X509_NAME_ENTRY_get_data(ne);
+ /* Positive on success, negative on error! */
+ if ((rv = do_check_string(str, -1, equal, flags,
+ chk, chklen, peername)) != 0)
+ return rv;
+ }
+ return 0;
+}
+
+int X509_check_host(X509 *x, const char *chk, size_t chklen,
+ unsigned int flags, char **peername)
+{
+ if (chk == NULL)
+ return -2;
+ /*
+ * Embedded NULs are disallowed, except as the last character of a
+ * string of length 2 or more (tolerate caller including terminating
+ * NUL in string length).
+ */
+ if (chklen == 0)
+ chklen = strlen(chk);
+ else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
+ return -2;
+ if (chklen > 1 && chk[chklen - 1] == '\0')
+ --chklen;
+ return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
+}
+
+int X509_check_email(X509 *x, const char *chk, size_t chklen,
+ unsigned int flags)
+{
+ if (chk == NULL)
+ return -2;
+ /*
+ * Embedded NULs are disallowed, except as the last character of a
+ * string of length 2 or more (tolerate caller including terminating
+ * NUL in string length).
+ */
+ if (chklen == 0)
+ chklen = strlen((char *)chk);
+ else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
+ return -2;
+ if (chklen > 1 && chk[chklen - 1] == '\0')
+ --chklen;
+ return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
+}
+
+int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
+ unsigned int flags)
+{
+ if (chk == NULL)
+ return -2;
+ return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
+}
+
+int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
+{
+ unsigned char ipout[16];
+ size_t iplen;
+
+ if (ipasc == NULL)
+ return -2;
+ iplen = (size_t)a2i_ipadd(ipout, ipasc);
+ if (iplen == 0)
+ return -2;
+ return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
+}
+
+/*
+ * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
+ * with RFC3280.
+ */
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
+{
+ unsigned char ipout[16];
+ ASN1_OCTET_STRING *ret;
+ int iplen;
+
+ /* If string contains a ':' assume IPv6 */
+
+ iplen = a2i_ipadd(ipout, ipasc);
+
+ if (!iplen)
+ return NULL;
+
+ ret = ASN1_OCTET_STRING_new();
+ if (!ret)
+ return NULL;
+ if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
+ ASN1_OCTET_STRING_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
+{
+ ASN1_OCTET_STRING *ret = NULL;
+ unsigned char ipout[32];
+ char *iptmp = NULL, *p;
+ int iplen1, iplen2;
+ p = strchr(ipasc, '/');
+ if (!p)
+ return NULL;
+ iptmp = BUF_strdup(ipasc);
+ if (!iptmp)
+ return NULL;
+ p = iptmp + (p - ipasc);
+ *p++ = 0;
+
+ iplen1 = a2i_ipadd(ipout, iptmp);
+
+ if (!iplen1)
+ goto err;
+
+ iplen2 = a2i_ipadd(ipout + iplen1, p);
+
+ OPENSSL_free(iptmp);
+ iptmp = NULL;
+
+ if (!iplen2 || (iplen1 != iplen2))
+ goto err;
+
+ ret = ASN1_OCTET_STRING_new();
+ if (!ret)
+ goto err;
+ if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
+ goto err;
+
+ return ret;
+
+ err:
+ if (iptmp)
+ OPENSSL_free(iptmp);
+ if (ret)
+ ASN1_OCTET_STRING_free(ret);
+ return NULL;
+}
+
+int a2i_ipadd(unsigned char *ipout, const char *ipasc)
+{
+ /* If string contains a ':' assume IPv6 */
+
+ if (strchr(ipasc, ':')) {
+ if (!ipv6_from_asc(ipout, ipasc))
+ return 0;
+ return 16;
+ } else {
+ if (!ipv4_from_asc(ipout, ipasc))
+ return 0;
+ return 4;
+ }
+}
+
+static int ipv4_from_asc(unsigned char *v4, const char *in)
+{
+ int a0, a1, a2, a3;
+ if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
+ return 0;
+ if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
+ || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
+ return 0;
+ v4[0] = a0;
+ v4[1] = a1;
+ v4[2] = a2;
+ v4[3] = a3;
+ return 1;
+}
+
+typedef struct {
+ /* Temporary store for IPV6 output */
+ unsigned char tmp[16];
+ /* Total number of bytes in tmp */
+ int total;
+ /* The position of a zero (corresponding to '::') */
+ int zero_pos;
+ /* Number of zeroes */
+ int zero_cnt;
+} IPV6_STAT;
+
+static int ipv6_from_asc(unsigned char *v6, const char *in)
+{
+ IPV6_STAT v6stat;
+ v6stat.total = 0;
+ v6stat.zero_pos = -1;
+ v6stat.zero_cnt = 0;
+ /*
+ * Treat the IPv6 representation as a list of values separated by ':'.
+ * The presence of a '::' will parse as one, two or three zero length
+ * elements.
+ */
+ if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
+ return 0;
+
+ /* Now for some sanity checks */
+
+ if (v6stat.zero_pos == -1) {
+ /* If no '::' must have exactly 16 bytes */
+ if (v6stat.total != 16)
+ return 0;
+ } else {
+ /* If '::' must have less than 16 bytes */
+ if (v6stat.total == 16)
+ return 0;
+ /* More than three zeroes is an error */
+ if (v6stat.zero_cnt > 3)
+ return 0;
+ /* Can only have three zeroes if nothing else present */
+ else if (v6stat.zero_cnt == 3) {
+ if (v6stat.total > 0)
+ return 0;
+ }
+ /* Can only have two zeroes if at start or end */
+ else if (v6stat.zero_cnt == 2) {
+ if ((v6stat.zero_pos != 0)
+ && (v6stat.zero_pos != v6stat.total))
+ return 0;
+ } else
+ /* Can only have one zero if *not* start or end */
+ {
+ if ((v6stat.zero_pos == 0)
+ || (v6stat.zero_pos == v6stat.total))
+ return 0;
+ }
+ }
+
+ /* Format result */
+
+ if (v6stat.zero_pos >= 0) {
+ /* Copy initial part */
+ memcpy(v6, v6stat.tmp, v6stat.zero_pos);
+ /* Zero middle */
+ memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
+ /* Copy final part */
+ if (v6stat.total != v6stat.zero_pos)
+ memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
+ v6stat.tmp + v6stat.zero_pos,
+ v6stat.total - v6stat.zero_pos);
+ } else
+ memcpy(v6, v6stat.tmp, 16);
+
+ return 1;
+}
+
+static int ipv6_cb(const char *elem, int len, void *usr)
+{
+ IPV6_STAT *s = usr;
+ /* Error if 16 bytes written */
+ if (s->total == 16)
+ return 0;
+ if (len == 0) {
+ /* Zero length element, corresponds to '::' */
+ if (s->zero_pos == -1)
+ s->zero_pos = s->total;
+ /* If we've already got a :: its an error */
+ else if (s->zero_pos != s->total)
+ return 0;
+ s->zero_cnt++;
+ } else {
+ /* If more than 4 characters could be final a.b.c.d form */
+ if (len > 4) {
+ /* Need at least 4 bytes left */
+ if (s->total > 12)
+ return 0;
+ /* Must be end of string */
+ if (elem[len])
+ return 0;
+ if (!ipv4_from_asc(s->tmp + s->total, elem))
+ return 0;
+ s->total += 4;
+ } else {
+ if (!ipv6_hex(s->tmp + s->total, elem, len))
+ return 0;
+ s->total += 2;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
+ */
+
+static int ipv6_hex(unsigned char *out, const char *in, int inlen)
+{
+ unsigned char c;
+ unsigned int num = 0;
+ if (inlen > 4)
+ return 0;
+ while (inlen--) {
+ c = *in++;
+ num <<= 4;
+ if ((c >= '0') && (c <= '9'))
+ num |= c - '0';
+ else if ((c >= 'A') && (c <= 'F'))
+ num |= c - 'A' + 10;
+ else if ((c >= 'a') && (c <= 'f'))
+ num |= c - 'a' + 10;
+ else
+ return 0;
+ }
+ out[0] = num >> 8;
+ out[1] = num & 0xff;
+ return 1;
+}
+
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
+ unsigned long chtype)
+{
+ CONF_VALUE *v;
+ int i, mval;
+ char *p, *type;
+ if (!nm)
+ return 0;
+
+ for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
+ v = sk_CONF_VALUE_value(dn_sk, i);
+ type = v->name;
+ /*
+ * Skip past any leading X. X: X, etc to allow for multiple instances
+ */
+ for (p = type; *p; p++)
+#ifndef CHARSET_EBCDIC
+ if ((*p == ':') || (*p == ',') || (*p == '.'))
+#else
+ if ((*p == os_toascii[':']) || (*p == os_toascii[','])
+ || (*p == os_toascii['.']))
+#endif
+ {
+ p++;
+ if (*p)
+ type = p;
+ break;
+ }
+#ifndef CHARSET_EBCDIC
+ if (*type == '+')
+#else
+ if (*type == os_toascii['+'])
+#endif
+ {
+ mval = -1;
+ type++;
+ } else
+ mval = 0;
+ if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
+ (unsigned char *)v->value, -1, -1,
+ mval))
+ return 0;
+
+ }
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3err.c b/Cryptlib/OpenSSL/crypto/x509v3/v3err.c
new file mode 100644
index 00000000..bcc1be72
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/x509v3/v3err.c
@@ -0,0 +1,249 @@
+/* crypto/x509v3/v3err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2014 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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
+
+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"},
+ {ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"},
+ {ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"},
+ {ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"},
+ {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"},
+ {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"},
+ {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS),
+ "I2V_AUTHORITY_INFO_ACCESS"},
+ {ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"},
+ {ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"},
+ {ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"},
+ {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"},
+ {ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"},
+ {ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"},
+ {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"},
+ {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"},
+ {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"},
+ {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"},
+ {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"},
+ {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"},
+ {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"},
+ {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"},
+ {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS),
+ "V2I_AUTHORITY_INFO_ACCESS"},
+ {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"},
+ {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"},
+ {ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"},
+ {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"},
+ {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"},
+ {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"},
+ {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"},
+ {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL),
+ "V3_ADDR_VALIDATE_PATH_INTERNAL"},
+ {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"},
+ {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"},
+ {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"},
+ {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"},
+ {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"},
+ {ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"},
+ {ERR_FUNC(X509V3_F_X509V3_EXT_FREE), "X509V3_EXT_free"},
+ {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"},
+ {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"},
+ {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"},
+ {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"},
+ {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"},
+ {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"},
+ {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"},
+ {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA X509V3_str_reasons[] = {
+ {ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"},
+ {ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"},
+ {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_CANNOT_FIND_FREE_FUNCTION),
+ "cannot find free function"},
+ {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"},
+ {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"},
+ {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"},
+ {ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"},
+ {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"},
+ {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"},
+ {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED),
+ "extension setting not supported"},
+ {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"},
+ {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_ASNUMBER), "invalid asnumber"},
+ {ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"},
+ {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"},
+ {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),
+ "invalid extension string"},
+ {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"},
+ {ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"},
+ {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"},
+ {ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"},
+ {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
+ {ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"},
+ {ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"},
+ {ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"},
+ {ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"},
+ {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER),
+ "invalid object identifier"},
+ {ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"},
+ {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),
+ "invalid policy identifier"},
+ {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),
+ "invalid proxy policy setting"},
+ {ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"},
+ {ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"},
+ {ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"},
+ {ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"},
+ {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"},
+ {ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"},
+ {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),
+ "need organization and numbers"},
+ {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"},
+ {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"},
+ {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"},
+ {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"},
+ {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED),
+ "no proxy cert policy language defined"},
+ {ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"},
+ {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"},
+ {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_ALREADY_DEFINED),
+ "policy language already defined"},
+ {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"},
+ {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"},
+ {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS),
+ "unable to get issuer details"},
+ {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID),
+ "unable to get issuer keyid"},
+ {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT),
+ "unknown bit string argument"},
+ {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"},
+ {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}
+};
+
+#endif
+
+void ERR_load_X509V3_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, X509V3_str_functs);
+ ERR_load_strings(0, X509V3_str_reasons);
+ }
+#endif
+}